⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 midialarm.c

📁 一个用C语言开发AVR单片机音乐播放器程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//*此程序为凝血仪音频报警程序,晶振1MHz*/
#include <iom128v.h>
#include <macros.h>

#pragma  interrupt_handler  can_int:4
//#pragma interrupt_handler ex_int3:5
//#pragma interrupt_handler ex_int4:6
//#pragma interrupt_handler ex_int5:7
//#pragma interrupt_handler ex_int6:8
//#pragma interrupt_handler ex_int7:9
//#pragma interrupt_handler ex_int8:10
#pragma interrupt_handler timer2_ovf_isr:11
#pragma interrupt_handler timer1_comp_isr:13
#pragma interrupt_handler timer0_ovf_isr:17
#pragma interrupt_handler usart0_rxc_isr:19
//#pragma interrupt_handler twi_isr:34

#define    LED_OFF         PORTE |= 0x04
#define    LED_ON          PORTE &= ~0x04

//语音芯片管脚宏定义
#define    SBT_HIGH        PORTB |= 0x20
#define    SBT_LOW         PORTB &= ~0x20
#define    RST_HIGH        PORTB |= 0x01
#define    RST_LOW         PORTB &= ~0x01
#define    VOICE_BUSY      (PINB & 0x02)

//CAN INT2(中断号4,低电平触发);
#define    CAN_INT         (PIND & 0x04)
#define    CAN_CS_1        PORTG |= 0x10
#define    CAN_CS_0        PORTG &= ~0x10
#define	   CAN_RST_1	   PORTG |= 0x08
#define	   CAN_RST_0	   PORTG &= ~0x08
#define    CAN_OFFSET	   0xFF00

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;

/*定义报警音(单音),前面数表示音符,后面数代表节拍*/
/*uint yewei_data[][2] = {{659,200},{523,400},{0,200},{659,200},{523,400},{0,200},
                        {659,200},{523,400},{0,200},{0,0}};  //液位感知  */
uint toohot_data[][2] = {{1318,200},{1318,200},{1318,200},{1318,200},{1318,200},
                         {0,0}};    //超温报警
uint taskfinish_data[][2] = {{988,200},{0,200},{988,200},{0,200},{988,200},{0,200},
                             {988,200},{0,200},{0,0}};  //所有测试完成
uint initsuccess_data[][2] = {{698,150},{0,50},{523,100},{523,100},{587,100},{0,100},{523,100},
                              {0,100},{0,200},{659,100},{0,100},{698,100},{0,100},{0,0}}; 
                              /*{{392,100},{659,100},{659,200},{587,200},{523,200},
                              {0,200},{523,400},{587,200},{0,0}};*/   //初始化成功
uint seriouserror_data[][2] = {{1760,25},{0,50},{1760,25},{0,50},{1760,25},{0,50},
                               {1760,25},{0,50},{1760,25},{0,50},{1760,25},{0,50},
			       {1760,25},{0,50},{1760,25},{0,50},{0,0}};   //严重故障
uint normalerror_data[][2] = {{784,50},{1046,50},{1175,100},{0,100},{1568,50},{0,50},
                              {1568,50},{0,50},{1568,50},{0,50},{1568,50},{0,50},{0,0}};  
							  //一般故障  
uint probestrike_data[][2] = {{1760,50},{1175,100},{0,100},{1760,50},{1175,100},{0,100},
                              {1760,50},{1175,100},{0,100},{0,0}};  //撞针保护报警                  
uint awakeup_data[][2] = {{1175,50},{1046,50},{0,50},{1046,50},{880,50},{0,50},{880,50},
                          {698,50},{0,50},{784,50},{659,50},{0,50},{659,100},{523,100},
						  /*{698,50},{587,50},{0,50},{659,100},{523,100},{0,50},*/{0,0}};    //提醒报警
uint liquidlack_data[][2] = {{1245,100},{0,100},{1245,100},{0,400},{1245,100},{0,100},
                             {1245,100},{0,400},{0,0}};		//液体缺乏报警	
uint initdefeat_data[][2] = {{659,100},{0,50},{784,100},{0,50},{1318,200},{1318,150},{1318,50},
                             {0,600},{659,100},{0,50},{784,100},{0,50},{1318,200},{1318,150},
							 {1318,50},{0,600},{0,0}};				  
uint delay = 0;      //节拍计数器 

uint delay1s = 0;    //指示灯闪烁计数器(闪烁频率1s)
uchar shine_flag = 0;   //指示灯闪烁启动标志位

uchar alarmcode = 0;   //报警码
//uchar voicegrp = 0x00;    //音乐播放类型


uchar can_laddr = 0x00;   //本地地址 (PINF & 0x0F)
uchar can_saddr = 0x00;   //发送地址
uchar num_canRbuf = 0; //纪录can接收缓冲器中现有命令数
uchar p_canRbuf = 0;//指向当前can接收缓冲器位置
uchar now_pcanRbuf = 0;//指向当前要执行的can命令行
uchar canRbuf[20][12];//CAN接收缓冲器
uchar canSndbuf[8] = {0,0,0,0,0,0,0,0};   //can发送缓存区
uchar num_canrec[20];//CAN收到参数数
//uchar canRevbuf = {0,0,0,0,0,0,0,0};   //can接收缓存区

uchar command[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};//当前需执行的命令,从canRbuf中接收一条命令
 
uchar com_flag = 0;   //串口缓存区有无数据标志(1:有数据, 0:无数据)
uchar com_num =0;    //串口接收数据计数器
uchar comRbuf[5] = {0,0,0,0,0};    //串口接收缓存区
//uchar comRbuf[2] = {0,0};
uchar comSbuf[5] = {0,0,0,0,0};    //串口发送缓存区
//uchar comSbuf[2] = {0,0};



uchar twi_laddr = 127;    //I2c本地地址	
uchar I2cRnum = 0;     //I2c收到的字节数
uchar I2cSnum = 0;     //
uchar p_I2cRbuf = 0;   //指向当前i2c接收缓存器位置
uchar I2cSbuf[4] = {0, 0, 0, 0};  //IIC总线发送缓冲 0:设备地址 1:高位地址 2:低位地址 3:需存数据	   	   	  
uchar I2cRbuf[8] = {0, 0, 0, 0, 0, 0, 0, 0};  //IIC接收缓冲 
uchar totalnum = 0x00;    //目前收到信息的总字节数

struct saveinformation{
                         ulong id;
						 uchar num_information;
					     uchar high_addr; 
						 uchar low_addr;
                         //struct saveinformation *next;							
                      }recdata[200];



void DelayMs(uchar k)       //延时ims,晶振为1M
{
   uint j;
   for( ; k>0 ; k--)
   {
	  for(j=160;j!=0;j--);
   }
}

void DelayUs(uchar x)      //延时100xus,晶振为1M
{
    uchar y;
	while(x)
	{
	   x--;
	   for(y=21;y!=0;y--);
	}
}

void port_init()       //端口初始化
{
   // out:1   in:0
   DDRA = 0x00;      
   PORTA = 0x00;   
   DDRB = 0xFF;      //PB1(U5BUSY)输入
   PORTB = 0x00;
   DDRC = 0x00;      //PC7~0保留
   PORTC = 0xFF;
   DDRD = 0x03;      
   PORTD = 0x04;     //D0:SCL,D1:SDA,D2:CAN_INT,D3:BAKIN1
   DDRE = 0x0E;
   PORTE = 0x0C;     //E0:RXD,E1:TXD,E2:LED,E3:BAKIN4
   DDRF = 0x00;
   PORTF = 0xFF;
   DDRG = 0x1C;
   PORTG = 0x08;   
}

/***********************************************
usart 8位数据位; 1位停止位; 9600bps;  无校验
***********************************************/
void usart_init()//通用异步串口初始化
{
    UCSR0A = 0x02;	//(1)U2X=1
	UCSR0B = 0x00;	//(2)UCSZ2=0;RXEN=0;TXEN=0
	UCSR0C = 0x86;	//(6)UMSEL=0,(5,4)UPM1:0=0 0,(3)USBS=0,(2,1)UCSZ1:0=1 1
	UBRR0H = 0x00;	//UBRR=12,U2X=1,9600bps
	UBRR0L = 0x0C;
	UCSR0B |= (1<<RXCIE0) | (1<<RXEN0) | (1<<TXEN0);//使能串口与中断
}


void usart0_rxc_isr()
{
   comRbuf[com_num] = UDR0;   //将数据寄存器的内容存入接收缓存区
   com_num++;       //串口接收数据计数器加1
   if(com_num>=5)
   {
      com_num = 0;
	  com_flag = 1;
   }   
}

void usart_txc(uchar data)
{
   while(!(UCSR0A & (1<<UDRE0)));     //等待数据寄存器为空(UDRE0=0)
   UDR0 = data;
}

/**************************************************
I2c总线程序
**************************************************/
void twi_init()
{
   //IIc总线 TWI接口初始化
   TWCR  = 0x00; //disable twi.
   TWBR  = 0x40; //set bit rate 32
   TWSR  = 0x00; //set prescal	TWPS1:0=00
   TWAR = (twi_laddr<<1) | 0x01;  //local address is 127 ;识别广播地址
}

/*************************************************
twi_Msend(uchar twi_saddr,uchar twi_num): I2c发送函数
可发送10个字节以内数据
twi_saddr发送地址,twi_snum发送字节,I2cSbuf[10]发送缓存区
*************************************************/
/*uchar twi_Msend(uchar twi_saddr,uchar twi_snum)
{
   uchar addr_w,n,twi_count,twi_flag;
   uint j;
   twi_flag =1;   //发送成功:0    发送失败:1
   if(twi_saddr >=0x01 && twi_saddr <= 0x04 )
      addr_w = (twi_saddr << 1) & 0xFE;   //D7~1:发送地址(7位),D0:写标志(1)
   else 
      return 0;
   
   n = 0;
   while(twi_flag)
   {
      n++;
      if(n>50)
      {
         TWCR = (1<<TWEN) | (1<<TWINT) | (1<<TWSTO);  //STOP
		 twi_init();
         TWCR = (1<<TWEA)|(1<<TWEN);
         return 0;
      }
	  
      //start
      TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);     //进入主发模式
      j = 0;
      while(!(TWCR & (1<<TWINT)) && j <= 10000){j++;} //从start信号发送开始计时,收到应答结束 
      if(j>10000)
      {   
         twi_init();
	     TWCR = (1<<TWEA) | (1<<TWEN);
	     return 0;    
      }
      
	  switch(TWSR & 0xF8)
	  {
	     case 0x08 : twi_flag = 0;
		             break;
		 case 0x18 : twi_flag = 0;
		             break;
		 case 0x38 : twi_flag = 1;
		             break;
		 default :  twi_init();        //发送失败,重新初始化
                    TWCR = (1<<TWEA)|(1<<TWEN);
                    return 0;
	  }
	  if(twi_flag)       //start发送成功,继续加载发送地址
	     continue;
      //发送从机地址和写命令
	  TWDR = addr_w;
      TWCR = (1<<TWINT) | (1<<TWEN);
      j=0;
      while(!(TWCR & (1<<TWINT)) && j <= 10000){j++;} 
      if(j>10000)
      {
	     twi_init();
         TWCR = (1<<TWEA) | (1<<TWEN);
         return 0;    
      }
	  
      switch(TWSR & 0xF8)
	  {
	     case 0x18 : twi_flag = 0;
		             break;
		 case 0x20 : twi_flag = 1;
		             break;
		 case 0x38 : twi_flag = 1;
		             break;
		 default : twi_init();        //发送失败,重新初始化
                   TWCR = (1<<TWEA)|(1<<TWEN);
                   return 0;
	  }
	  if(twi_flag)
	     continue;     //发送地址发送成功,加载数据字节
	  //发送数据 I2cSbuf[0]~I2cSbuf[7]
	  for(twi_count=0; twi_count<twi_snum; twi_count++)
	  {
		 TWDR = I2cSbuf[twi_count];
		 TWCR = (1<<TWINT) | (1<<TWEN);
		    
	     j=0;
	     while(!(TWCR & (1<<TWINT)) && j<=10000){j++;}
	     if(j>10000)
	     {
	        twi_init();
			TWCR = (1<<TWEA) | (1<<TWEN);
			return 0;
		 }
			
		 switch(TWSR & 0xF8)
		 {
		    case 0x28 : twi_flag = 0;
			            break;
			case 0x30 : twi_flag = 1;
			            break;
			case 0x38 : twi_flag = 1;
			            break;
			default : twi_init();
			          TWCR = (1<<TWEA) | (1<<TWEN);
					  return 0;
		 }
		 if(twi_flag)
		    break;
	  }
      if(twi_flag)
		 continue;
      //stop
      TWCR = (1<<TWINT) |(1<<TWSTO) | (1<<TWEN);
      DelayMs(10);
      return 1;
   }
   return 1;
}*/

/**********************************************
I2c主设备接收程序   接收缓存I2cRbuf[8]
**********************************************/
/*uchar twi_Mreceive(uchar twi_Saddr, uchar twi_rnum)
{
   uchar twi_count, twi_flag, addr_r,temp,n;  //n:为失败次数
   uint j;
   twi_flag = 1;   //MR success:0   MR defeat:1
   if(twi_Saddr<=0x04 && twi_Saddr>=0x01)
      addr_r = (twi_Saddr<<1) | 0x01;
   else
      return 0;
	  
   n = 0;
   while(twi_flag)
   {
      n++;
	  if(n>100)
	  {
	     twi_init();
		 TWCR = (1<<TWEA) | (1<<TWEN);
		 return 0;
	  }  
	  
      //start
	  TWCR = (1<<TWINT) | (1<<TWSTA) |(1<<TWEA);
	  j=0;
	  while(!(TWCR&(1<<TWINT)) && j<=10000){j++;}
	  if(j<10000)
	  {
	     twi_init();
		 TWCR = (1<<TWEA) | (1<<TWEN);
		 return 0;
	  }
	  
	  switch(TWSR & 0xF8)
	  {
	     case 0x08 : twi_flag = 0;
		             break;
		 case 0x10 : twi_flag = 0;
		             break;
		 case 0x38 : twi_flag = 1;
		             break;
		 default : twi_init();
		           TWCR = (1<<TWEA) | (1<<TWEN);
				   return 0;
	  }
	  if(twi_flag)
	     continue;
	  
	  //发送从地址和sla_r
	  TWDR = addr_r;
	  TWCR = (1<<TWINT) | (1<<TWEN);
	  j=0;
	  while(!(TWCR&(1<<TWINT)) && j<=10000){j++;}
	  if(j>10000)
	  {
	     twi_init();
		 TWCR = (1<<TWEA) | (1<<TWEN);
		 return 0;
	  }
	  switch(TWSR&0xF8)
	  {
	     case 0x38 : twi_flag = 1;
		             break;
		 case 0x40 : twi_flag = 0;
		             break;
		 case 0x48 : twi_flag = 1;
		             break;
		 default :  twi_init();
		            TWCR = (1<<TWEA) | (1<<TWEN);
					return 0; 
	  }
	  if(twi_flag)
	     continue;
	  
	  //接收数据
	  twi_count = 0;   //接收字节计数器初始化
	  while(twi_count < twi_rnum)
	  {
	     twi_count++;     //清除中断标志位
		 temp = (1<<TWINT);
		 if(twi_count<twi_num)
             temp |= (1<<TWEA);   
		 TWCR = temp; 
		   
		 j = 0;
	     while(!(TWCR & (1<<TWINT)) && j <= 10000){j++;}
	     if(j>10000)
	     {
	        twi_init();
	        TWCR = (1<<TWIE) | (1<<TWEN) ; 
	        return 0;
         } 
		 switch(TWSR & 0xF8)
		 {
		    case 0x38 : twi_flag = 1;
			            break;
			case 0x50 : twi_flag = 0;
			            I2cRbuf[twi_count-1] = TWDR;
						if(twi_count == 8)
						   TWCR &= 0xBF;     //复位TWEA, 
						   TWCR = (1<<TWINT);     //发 NACK,		   
						break;
			case 0x58 : twi_flag = 0;
			      		I2cRbuf[twi_count-1] = TWDR;
			            //stop
	                    TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
	                    DelayMs(10);
	                    return 1;	
			default : twi_init();
			          TWCR = (1<<TWEA) | (1<<TWEN);
					  return 0;
		 }
		 if(twi_flag)
		    continue;
	  } 
   }
   return 0;
}*/

/**********************************************
I2c从设备接收程序   接收缓存I2cRbuf[10]
**********************************************/
/*uchar twi_Sreceive()
{
   uchar twi_count,twi_flag;
   uint j;
   TWCR = (1<<TWEN) | (1<<TWEA);  //TWI中断屏蔽
   
   j = 0;
   while(!(TWCR & (1<<TWINT)) && j<=10000){j++;}  //等待sla_w
   if(j>10000)
   {
	  twi_init();
	  TWCR = (1<<TWIE) | (1<<TWEN) ;  //使能twi中断
	  return 0;
   } 
   
   switch(TWSR & 0xF8)
   {
      case 0x60 : twi_flag = 0;
	              break;
	  case 0x68 : twi_flag = 0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -