📄 uart.c
字号:
i++; // 数据指针下移
if(maxtrans)
temp=SPIbuf[i];
else
temp=recv_buf[i];
checksum+=temp;
if(temp!=laddr)
wrongaddr=TRUE; // 地址不正确
i++; // 数据指针下移
}
nextstate=STATE_MSG_NUM; // 检查信息号
break;
case STATE_MSG_NUM:
if(maxtrans)
temp=SPIbuf[i];
else
temp=recv_buf[i];
if(temp<'0'||temp>'9')
errordect=TRUE; // 通信错误
checksum+=temp;
i++; // 数据指针下移
nextstate=STATE_STX; // 检查STX
break;
case STATE_STX:
if(maxtrans)
temp=SPIbuf[i];
else
temp=recv_buf[i];
if(temp==STX)
{
checksum+=STX;
nextstate=STATE_MSG_STRING;
}
else
errordect=TRUE; // 数据包不正确
i++; // 数据指针下移
break;
case STATE_MSG_STRING:
strindex=0;
while(TRUE)
{
if(maxtrans)
temp=SPIbuf[i];
else
temp=recv_buf[i];
if(temp==ETX)
{
checksum+=ETX;
break;
}
checksum+=temp;
i++; // 数据指针下移
strindex++;
if(strindex>MAX_COMMAND_LENGTH)
{
errordect=TRUE; // 命令超长
break;
}
}
i++; // 数据指针下移
nextstate=STATE_CHECKSUM; // 检查校验和
break;
case STATE_CHECKSUM:
if(maxtrans)
temp=SPIbuf[i];
else
temp=recv_buf[i];
testchecksum=Asc_hex(temp);
i++;
if(maxtrans)
temp=SPIbuf[i];
else
temp=recv_buf[i];
testchecksum=testchecksum<<4;
testchecksum+=Asc_hex(temp);
temp=(testchecksum+checksum)&0xFF;
if(temp!=0)
errordect=TRUE; // 校验和错
i++;
nextstate=STATE_EOT; // 检查结束
break;
case STATE_EOT:
if(maxtrans)
temp=SPIbuf[i];
else
temp=recv_buf[i];
if(temp!=EOT)
errordect=TRUE; // 没有结束错误
else
endofmessage=TRUE; // 信息包完整
break;
}
if(errordect||endofmessage||wrongaddr)
break;
}
if(wrongaddr)
{
ClearRcvBuf(); // 清接收缓冲区
return FALSE; // 地址错误直接返回,不进行任何操作
}
if(errordect)
{
ClearRcvBuf(); // 清接收缓冲区
sendmessage(NAK);
return FALSE; // 接收错误
}
if(endofmessage)
{
return TRUE; // 接收正确
}
}
///////////////////////////////////////////////////////////////////////////////
// 上位机命令处理过程
///////////////////////////////////////////////////////////////////////////////
void host_proc()
{
idata uint i;
idata uchar temp;
if(checkmessage()==TRUE)
{
if(readbuf()==TRUE) // 处理具体的上位机命令
{
if(maxtrans) // 大数据量传输模式
{
if((SPIbuf[COMMAND_PTR]=='S')&&(SPIbuf[COMMAND_PTR+1]=='C')
&&(SPIbuf[COMMAND_PTR+2]=='S')&&(SPIbuf[COMMAND_PTR+3]=='S'))
{
sendmessage(ACK); // 发送ACK,告诉主机正常执行
if(comm_ok) // 通信正常修改参数
maxtrans=FALSE; // 切换为小数据量传输模式
}
else if((SPIbuf[COMMAND_PTR]=='S')&&(SPIbuf[COMMAND_PTR+1]=='C')
&&(SPIbuf[COMMAND_PTR+2]=='S')&&(SPIbuf[COMMAND_PTR+3]=='L'))
{
sendmessage(ACK); // 发送ACK,告诉主机正常执行
if(comm_ok) // 通信正常修改参数
maxtrans=FALSE; // 切换为小数据量传输模式
}
else
{
SPIbuf[1]='0'; // 修改地址向DSP发送
SPIbuf[2]='1';
SPIbuf[3]='0';
SPIbuf[4]='2';
// 重新计算校验和
i=0;
checksum=0;
while(SPIbuf[i]!=ETX)
{
checksum+=SPIbuf[i];
i++;
}
checksum+=SPIbuf[i]; // ETX
checksum=~checksum+1;
temp=(checksum&0xF0)>>4;
i++;
SPIbuf[i]=Hex_ascii(temp);
temp=checksum&0x0F;
i++;
SPIbuf[i]=Hex_ascii(temp);
if(Send_spi()) // 直接向DSP发送
{
SPIbuf[1]=haddr; // 修改地址向上位机发送
SPIbuf[2]=laddr;
SPIbuf[3]='0';
SPIbuf[4]='0';
// 重新计算校验和
i=0;
checksum=0;
while(SPIbuf[i]!=ETX)
{
checksum+=SPIbuf[i];
i++;
}
checksum+=SPIbuf[i]; // ETX
checksum=~checksum+1;
temp=(checksum&0xF0)>>4;
i++;
SPIbuf[i]=Hex_ascii(temp);
temp=checksum&0x0F;
i++;
SPIbuf[i]=Hex_ascii(temp);
i++;
COMENABLE; // 允许串口中断
Dir=1; // 485发送
time_out=120; // 1.2s转发完所有数据
trans_ctr=0; // 发送指针
trans_size=i+1; // 发送数据大小
SBUF=SPIbuf[0]; // 发送数据
comm_ok=TRUE; // 串口通信正常
while(trans_size)
{
if(time_out==0)
{
comm_ok=FALSE; // 串口通信失败
break;
}
} // 直到数据传输完毕
Dir=0; // 关闭485发送
if(comm_ok) // 通信正常
{
if(SPIbuf[7]=='D'&&SPIbuf[8]=='U'&&SPIbuf[9]=='T'&&SPIbuf[10]=='S')
{
pulse=1;
if(wieformat==1) // 自定义门禁方式
white_bill_reg(); // 注册白名单
}
if(SPIbuf[7]=='U'&&SPIbuf[8]=='U'&&SPIbuf[9]=='T'&&SPIbuf[10]=='S')
pulse=1;
}
ClearRcvBuf(); // 清接收缓冲区
}
else
sendmessage(NAK); // SPI发送超时失败
}
}
else // 小数据量命令模式
{
if((recv_buf[COMMAND_PTR]=='S')&&(recv_buf[COMMAND_PTR+1]=='M')&&(recv_buf[COMMAND_PTR+2]=='T'))
{
for(i=0;i<15;i++)
{
cur_time[i]=recv_buf[COMMAND_PTR+3+i];
set_time(); // 设置系统时间
}
sendmessage(ACK); // 发送ACK,告诉主机正常执行
}
else if((recv_buf[COMMAND_PTR]=='G')&&(recv_buf[COMMAND_PTR+1]=='R')&&(recv_buf[COMMAND_PTR+2]=='R'))
{
sendmessage(RTL); // 发送实时信息
}
else if((recv_buf[COMMAND_PTR]=='S')&&(recv_buf[COMMAND_PTR+1]=='C')
&&(recv_buf[COMMAND_PTR+2]=='S')&&(recv_buf[COMMAND_PTR+3]=='S'))
{
sendmessage(ACK); // 发送ACK,告诉主机正常执行
if(comm_ok) // 通信正常
maxtrans=FALSE; // 切换为小数据量传输
}
else if((recv_buf[COMMAND_PTR]=='S')&&(recv_buf[COMMAND_PTR+1]=='C')
&&(recv_buf[COMMAND_PTR+2]=='S')&&(recv_buf[COMMAND_PTR+3]=='L'))
{
sendmessage(ACK); // 发送ACK,告诉主机正常执行
if(comm_ok) // 通信正常
maxtrans=TRUE; // 切换为大数据量传输
}
else
sendmessage(NAK); // 命令不支持
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
// 设置波特率
///////////////////////////////////////////////////////////////////////////////
void Baud_Init()
{
switch(baudrate)
{
case 0:
TR2=0; // 关闭T2定时器
TH2 = 0xff ;
TL2 = 0x70; // 波特率设为4800bps
RCAP2H=0xff;
RCAP2L=0x70;
TR2 = 1; // 允许T2中断
break;
case 1:
TR2=0; // 关闭T2定时器
TH2 = 0xff ;
TL2 = 0xb8; // 波特率设为9600bps
RCAP2H=0xff;
RCAP2L=0xb8;
TR2 = 1; // 允许T2中断
break;
case 2:
TR2=0; // 关闭T2定时器
TH2 = 0xff ;
TL2 = 0xdc; // 波特率设为19200bps
RCAP2H=0xff;
RCAP2L=0xdc;
TR2 = 1; // 允许T2中断
break;
case 3:
TR2=0; // 关闭T2定时器
TH2 = 0xff ;
TL2 = 0xee; // 波特率设为38400bps
RCAP2H=0xff;
RCAP2L=0xee;
TR2 = 1; // 允许T2中断
break;
case 4:
TR2=0; // 关闭T2定时器
TH2 = 0xff ;
TL2 = 0xf4; // 波特率设为57600bps
RCAP2H=0xff;
RCAP2L=0xf4;
TR2 = 1; // 允许T2中断
break;
case 5:
TR2=0; // 关闭T2定时器
TH2 = 0xff ;
TL2 = 0xfa; // 波特率设为115200bps
RCAP2H=0xff;
RCAP2L=0xfa;
TR2 = 1; // 允许T2中断
break;
default:
break;
}
}
///////////////////////////////////////////////////////////////////////////////
// 清接收缓冲区
///////////////////////////////////////////////////////////////////////////////
void ClearRcvBuf()
{
idata uint i;
COMDISABLE; // 不允许串口再接收数据
if(maxtrans)
{
for(i=0; i<BUFSIZE; i++)
SPIbuf[i]=0x00;
}
else
{
for(i=0; i<RCVBUFSIZE; i++)
recv_buf[i]=0x00;
}
recv_ctr=0;
COMENABLE; // 允许串口接收数据
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -