#include"uart_handle.h"
bit flagFrame = 0; //帧接收完成标志,即接收到一帧新数据
bit flagTxd = 0; //单字节发送完成标志,用来替代TXD中断标志位
unsigned char cntRxd = 0; //接收字节计数
unsigned char bufRxd[22]; //接收字节缓冲区
unsigned char bufTxd[17]; //接收字节缓冲区
/* 串口数据写入,即串口发送函数,buf-待发送数据的指针,len-指定的发送长度 */
void UartWrite(unsigned char *buf, unsigned char len)
{
while (len--) //循环发送所有字节
{
flagTxd = 0; //清零发送标志
SBUF = *buf++; //发送一个字节数据
while (!flagTxd); //等待该字节发送完成
}
}
/* 串口数据读取函数,buf-接收指针,len-指定的读取长度,返回值-实际读到的长度 */
unsigned char UartRead(unsigned char *buf, unsigned char len)
{
unsigned char i;
if (len > cntRxd) //指定读取长度大于实际接收到的数据长度时,
{ //读取长度设置为实际接收到的数据长度
len = cntRxd;
}
for (i=0; i<len; i++) //拷贝接收到的数据到接收指针上
{
*buf++ = bufRxd[i];
}
cntRxd = 0; //接收计数器清零
return len; //返回实际读取长度
}
/* 串口接收监控,由空闲时间判定帧结束,需在定时中断中调用,ms-定时间隔 */
void UartRxMonitor(unsigned char ms)
{
static unsigned char cntbkp = 0;
static unsigned char idletmr = 0;
if (cntRxd > 0) //接收计数器大于零时,监控总线空闲时间
{
if (cntbkp != cntRxd) //接收计数器改变,即刚接收到数据时,清零空闲计时
{
cntbkp = cntRxd;
idletmr = 0;
}
else //接收计数器未改变,即总线空闲时,累积空闲时间
{
if (idletmr < 30) //空闲计时小于30ms时,持续累加
{
idletmr += ms;
if (idletmr >= 30) //空闲时间达到30ms时,即判定为一帧接收完毕
{
flagFrame = 1; //设置帧接收完成标志
}
}
}
}
else
{
cntbkp = 0;
}
}
/* 串口动作函数,根据接收到的命令帧执行响应的动作
buf-接收到的命令帧指针,len-命令帧长度 */
void UartAction(unsigned char *buf, unsigned char len)
{
unsigned char i=0;
if(len<8)
return;
if( (buf[0]==ask_key[0])&&(buf[1]==ask_key[1])&&(buf[2]==ask_key[2])&&(buf[3]==ask_key[3])&&(buf[4]==ask_key[4])&&(buf[5]==ask_key[5])&&(buf[6]==ask_key[6])&&(buf[7]==ask_key[7])&&(buf[8]==ask_key[8]) )//获取设备信息
{
UartWrite(key_ack, 115);
}else if( (buf[0]==ask_heart[0])&&(buf[1]==ask_heart[1])&&(buf[2]==ask_heart[2])&&(buf[3]==ask_heart[3])&&(buf[4]==ask_heart[4]))//心跳
{
if(len!=9)
return;
for(i=0;i<8;i++)
{
bufTxd[i]=heart_ack[i];
}
bufTxd[5]=buf[5];
bufTxd[8]=gizProtocolSum(bufTxd, 9);
UartWrite(bufTxd, 9);
}else if( (buf[0]==ask_key[0])&&(buf[1]==ask_losenet[1])&&(buf[2]==ask_losenet[2])&&(buf[3]==ask_losenet[3])&&(buf[4]==ask_losenet[4])&&(buf[5]==ask_losenet[5])&&(buf[6]==ask_losenet[6])&&(buf[7]==ask_losenet[7])&&(buf[8]==ask_losenet[8])&&(buf[9]==ask_losenet[9])&&(buf[10]==ask_losenet[10]) )
{
UartWrite(losenet_ack, 9);
}else if( (buf[0]==ask_wifistate[0])&&(buf[1]==ask_wifistate[1])&&(buf[2]==ask_wifistate[2])&&(buf[3]==ask_wifistate[3])&&(buf[4]==ask_wifistate[4]))//模块推送WIFI状态
{
if(len!=11)
return;
for(i=0;i<8;i++)
{
bufTxd[i]=wifistate_ack[i];
}
bufTxd[5]=buf[5];
bufTxd[8]=gizProtocolSum(bufTxd, 9);
UartWrite(bufTxd, 9);
}else if( (buf[0]==ask_app[0])&&(buf[1]==ask_app[1])&&(buf[2]==ask_app[2])&&(buf[3]==ask_app[3])&&(buf[4]==ask_app[4]))//APP上线
{
if(len!=11)
return;
for(i=0;i<8;i++)
{
bufTxd[i]=app_ack[i];
}
bufTxd[5]=buf[5];
bufTxd[8]=gizProtocolSum(bufTxd, 9);
UartWrite(bufTxd, 9);
}else if( (buf[0]==ask_yewu[0])&&(buf[1]==ask_yewu[1])&&(buf[2]==ask_yewu[2])&&(buf[3]==ask_yewu[3])&&(buf[4]==ask_yewu[4]))//开APP获取数据
{
if(len!=10)
return;
for(i=0;i<15;i++)
{
bufTxd[i]=yewu_ack[i];
}
bufTxd[5]=buf[5];
yewu_ack[10]=set_time[0];
yewu_ack[11]=set_time[1];
yewu_ack[12]=set_time[2];
yewu_ack[13]=set_time[3];
bufTxd[14]=gizProtocolSum(bufTxd, 15);
UartWrite(bufTxd, 15);
get_time_fig=1;//开始获取时间
}else if( (buf[0]==dwon_time[0])&&(buf[1]==dwon_time[1])&&(buf[2]==dwon_time[2])&&(buf[3]==dwon_time[3])&&(buf[4]==dwon_time[4])&&(buf[9]>0x04))//下发设置时间
{
if(len!=16)
return;
if(buf[9]==0x08)
{
set_time[0]=buf[11];//开时
up_message[10]=set_time[0];
}
if(buf[9]==0x10)
{
set_time[1]=buf[12];//开分
up_message[11]=set_time[1];
}
if(buf[9]==0x20)
{
set_time[2]=buf[13];//关时
up_message[12]=set_time[2];
}
if(buf[9]==0x40)
{
set_time[3]=buf[14];//关分
up_message[13]=set_time[3];
}
for(i=0;i<8;i++)
{
bufTxd[i]=dwon_time_ack[i];
}
bufTxd[5]=buf[5];
bufTxd[8]=gizProtocolSum(bufTxd, 9);
UartWrite(bufTxd, 9);
}else if( (buf[0]==time_ack[0])&&(buf[1]==time_ack[1])&&(buf[2]==time_ack[2])&&(buf[3]==time_ack[3])&&(buf[4]==time_ack[4]))//返回北京时间
{
if(len!=20)
return;
i=gizProtocolSum(buf, 20);
if(i==buf[19])
{
shi_fen_miao[0]=buf[12];//时FF FF 00 10 18 01 00 00 07 E6 01 10 12 02 18 61 E3 ED 30 B4
shi_fen_miao[1]=buf[13];//分
shi_fen_miao[2]=buf[14];//秒
SaveFig=1;//保存标志
get_time_fig=0;
}
}else if( (buf[0]==ask_relay[0])&&(buf[1]==ask_relay[1])&&(buf[2]==ask_relay[2])&&(buf[3]==ask_relay[3])&&(buf[4]==ask_relay[4])&&(buf[9]<0x08))//下发控制继电器指令
{
if(len!=16)
return;
switch(buf[9])
{
case 0x01:
if(buf[9]==buf[10])
{
led_control(1,ON);
up_message[9]|=0x01;//更新上传数据
yewu_ack[9]|=0x01;//更新APP上线获取数据
}else if(buf[10]==0x00)
{
led_control(1,OFF);
up_message[9]&=0xFE;
yewu_ack[9]&=0xFE;
}
break;
case 0x02:
if(buf[9]==buf[10])
{
led_control(2,ON);
up_message[9]|=0x02;
yewu_ack[9]|=0x02;
}else if(buf[10]==0x00)
{
led_control(2,OFF);
up_message[9]&=0xFD;
yewu_ack[9]&=0xFD;
}
break;
default:break;
}
for(i=0;i<8;i++)
{
bufTxd[i]=relay_ack[i];
}
bufTxd[5]=buf[5];
bufTxd[8]=gizProtocolSum(bufTxd, 9);
UartWrite(bufTxd, 9);
}
}
/* 串口驱动函数,监测数据帧的接收,调度功能函数,需在主循环中调用 */
void UartDriver()
{
unsigned char len;
unsigned char buf[22];
if (flagFrame) //有命令到达时,读取处理该命令
{
flagFrame = 0;
len = UartRead(buf, sizeof(buf)); //将接收到的命令读取到缓冲区中
UartAction(buf, len); //传递数据帧,调用动作执行
}
}