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

📄 uartnews._h

📁 基于单片机的短信报警机
💻 _H
字号:

void ReDial(void);
/**************************************************
*原型:void InitUART( unsigned char baudrate )
*功能:串口初始化,19.2k,一个字节520.8US
*参数:unsigned char baudrat
*返回:无
**************************************************/
void InitUART( unsigned char baudrate )
	{
	UBRR = baudrate; //19.2k
	UCSRB = ( (1<<RXCIE) | (1<<RXEN) | (1<<TXEN) );//接收中断开,接收口开,发送口开
    UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);//8位数据+1位STOP位
	}   
/*************************************************
*原型:void UART_TX_interrupt(void)
*功能:初始化,执行任务
*说明:无
*参数:无
*返回:无
**************************************************/
/*  		字符输出函数 		 */
void putchar(unsigned char c)
	{	 
     while (!GET_BIT(UCSRA,UDRE)) ;
	 
	 UDR=c;    
	}

/*			字符串输出函数	   	 */
void puts(char *s)
	{
	while (*s)
		{
		putchar(*s);
		s++;
		}	
    putchar(0x0D);//回车换行
	putchar(0x0A);
	}	
void putgmgr(char *s)
{
 while (*s)
		{
		putchar(*s);
		s++;
		}	
 putchar(0x1a);//^z
 }
/*************************************************
*原型:unsigned char Bj_rx(uchar addrss_1,uchar data,uchar count_1)
*功能:在数组内查找一个字符
*说明:如果有找到返回地址,无返回0
*参数:addrss,data
*返回:addrss or 0
**************************************************/
unsigned char Bj_rx(uchar addrss_1,uchar data,uchar count_1)
{
 for( ;count_1<addrss_1;count_1++)
		 {
		  //判断SIM卡有无预存号
		  if(Uart.Buf[count_1] == data) 
			      return count_1;
		  }
 return 0;
 }
/*************************************************
*原型:void CopyStr(uchar *p,uchar *s)
*功能:把字符串s拷贝在p
*说明:无
*参数:*p,*S
*返回:指针地址
*日期:06-01-16
**************************************************/
uchar  *CopyStr(uchar *p,uchar *s)
{
  do
    {
	 *p ++ =*s++;
	 }
  while((*s != NULL)&&(*s != 0x0d));
  *p = NULL;
  return p;
 }

 /*************************************************
*原型:uint ReadTime(uchar *p)
*功能: 读取心跳时间与复位时间
*说明:如果无存心跳时间为10分钟,复位时间为1天
*参数:uchar *p-接收到,len长度
*返回:val-运算完的值
**************************************************/
#define TIMELEN	  4
uint ReadTime(uchar *p)
{
 uchar count;
 uint temp=1;
 uint val = NULL;
 uint tempval;
 uchar bitcount=0;//位计数
 //当结束或超过位数跳出
 while((*p != '"')&&(bitcount < TIMELEN))
 		  {
		   count = *p ++;          //把值读进
		   count = count - 0x30;
		   tempval =(uint)(val * 10);   //乘进位
		   val = (uint)(count+tempval);    //存进
		   bitcount ++;            //位数加1
		   }
 return val;
 }
/*************************************************
*原型:void Save_tel(uchar count,uchar *p )
*功能:把从SIM卡读到电话本存到二维数组内
*说明:最大可存16位号码,超出只取前面,时间0-9999分钟
*参数:uchar count-定位,*p要填写的缓冲区
*返回:无
**************************************************/
void Save_tel(uchar count,uchar *p )
{
 unsigned char i = 0;

  ++ count;
  
  *p++ = 'A';
  *p++ = 'T';
  *p++ = 'D';
 while((Uart.Buf[count]!= '"' )&&(Uart.Buf[count] != '*'))
				  {
				    if(i < TELLEN)//当号码长度未超过TELLEN,填写在缓冲区内
						    *p++ = Uart.Buf[count]; 
				   count++;       //指向下一个接收缓冲区
				   }
  *p++ =';';
  *p = NULL;//结束
//如有预存的定时时间			   
 if(Uart.Buf[count] =='*')
 		{
		 ++count;
		 Time.Atd=ReadTime(&Uart.Buf[count]);//转换成时间
		}
 else 
 	    {
		 Time.Atd = NULL;//定时标志为0
		 }
 } 
/*************************************************
*原型:void UART_RX_interrupt(void)
*功能:接收串口数据
*说明:无
*参数:无
*返回:无
**************************************************/
#pragma interrupt_handler UART_RX_interrupt:iv_USART_RX 
void UART_RX_interrupt( void )
 {
    unsigned char data,hz1;
	data = UDR; 
	hz1 = UART_RXHEAD;
	UART_RXHEAD++; 
	Uart.Buf[hz1] = data;    //把数据存到接收缓冲区
   //如果超出范围从头收起
	if(UART_RXHEAD>=UARTRXLEN)
				UART_RXHEAD = NULL;

    if((data == 'K')&&(Uart.Buf[--hz1] =='O'))
 		  		DealRxUartBz = TRUE;	

	//在空闲状态来电振铃发摘机命令起机
	else if((data=='G')&&(Uart.Buf[--hz1]=='N')&&(!Busybz))
			   {
			     UART_RXHEAD = NULL; //接收计数器与号码标志指向空 
				 WorkCount = GET;   //任务计数器指向接听命令
				 }
  }
/*************************************************
*原型:void QueryState(void)
*功能:根据*ECAV的内容判断通话是否成功
*说明:无
*参数:uchar addrssend
*返回:无
**************************************************/	
void QueryState(uchar addrssend)
{
 uchar count;
 
    if(count=Bj_rx(addrssend,',',0))
		    { 
		     count = count = Bj_rx(addrssend,',',++count);
			 count ++;
		     if(Uart.Buf[count] == '0')
			  				{//接听马上挂机
							 WorkCount = RINGOFF;
							 Time.Sec = 1;
							}
		     }
	else  //发送挂机命令
	        {  
			  WorkCount = RINGOFF;//				   
  		   }	 			
   }
/*************************************************
*原型:void Deal_rx(void)
*功能:处理接收到的数据
*说明:无
*参数:uchar addrss-双音计数
*返回:无
**************************************************/
void DealRxBuf(uchar addrss)
{
   unsigned char count = NULL;

   CLR_BIT(UCSRB,RXCIE);//关接收
   
   switch(WorkCount)//任务指示器
 	    {
		 case LINE:    
		 case SETUPTEL: 
		 	         WorkCount++;
					 break;			
		 case RTEL:
		      //在数组从COUNT开始到ADDRSS内查找一个字符,无找到返回0
		      if(count=Bj_rx(addrss,'"',count))
						{ 
			   		     Save_tel(count,TelBuf); //读出电话本与定时时间
						 WorkCount = CALLTEL;//有读到电话本马上去拔号处理
						  DealTxUartBz = TRUE;//如果未读到电话本,红灯亮
						 }
			   break;
		 case CALLTEL://拔号成功,接着查询状态
		 	    WorkCount = QUERY;
				Time.Sec = timesec;//2000ms
			   break;
		 case QUERY://根据回应分析状态
		 	    QueryState(addrss);
			    break;
	     case GET://有来电接听挂断
		 	    WorkCount = RINGOFF;
				break;
		 case RINGOFF://发挂机命令成功
		 	    Time.Mec = Time.Min = NULL;
				
				Time.Sec = time3sec;//定时3秒
		 	    if(!Time.Atd)//如果无定时,直接拔打下一个
		 	   	       	{
						 Time.Sec = timesec;
						 WorkCount = CALLTEL;
						 }
				else //否则定时未到,等待定时到再拔号
					    {
						 WorkCount = NULLACK;
						 }
				Busybz = FALSE;
			    break;	
		}
   UART_RXHEAD = NULL;    //接收器指向头
   DealRxUartBz = FALSE;  //串口接收处理标志清0
   SET_BIT(UCSRB,RXCIE);  //开接收
   }
/**************************************************
*原型:void InitUART(void)
*功能:初始化UART,接收中断开,接收/发送口开
*参数:速率为19.2k,8位数据+1位STOP位,bandrate
*返回:无
**************************************************/
void DealTx(void)
{
 switch(WorkCount)
 				  {
				   case LINE://建立连接
						  puts("ATE0");
						  break;
			
				   case SETUPTEL:
				   		  puts("AT+CPBS=\"SM\"");
						  break;
				 
				   case RTEL://查找电话本
				      
				   		  puts("AT+CPBR=1");
						  break;
						  
				   case CALLTEL://在报警时发拔号命令
				   		 //拔号定时重新清0
						  puts("ATH");
						  delay_ms(1500);
						  DealRxUartBz =FALSE;
						  WorkCount = CALLTEL;
						  Time.Sec = time3sec;//定时3秒
						  puts(TelBuf);
						  Busybz = TRUE;//忙标志置1
						  break;
						  
				  case QUERY://查询拔号状态
				  	      puts("AT+CLCC");
						  Time.Sec = timesec;
						  break;
				  case GET://接听
				   		  puts("ATA");//发送摘机命令
						  break;   
				   case RINGOFF://挂机 
				   		  puts("ATH");
						  break;
				}

 DealTxUartBz = FALSE;   //已发送完,把发送标志清0
 UART_RXHEAD = NULL;
 }	

⌨️ 快捷键说明

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