27,521
社区成员
发帖
与我相关
我的任务
分享
//发送后下位机正常接受
#define ACK_OK 1
//发送后下位机没反应
#define ACK_TIMEOUT 2
//发送后下位机报告校验错误
#define ACK_VERERR 3
//空闲
#define STA_READY 0
//接受到正确的帧
#define STA_SENTOK 1
//状态发送完
#define STA_SENT 2
//状态: 收到一个校验错误的ACK
#define STA_VERERR 3
volatile uchar sta=STA_READY;
uint16 uartcnt=0;
void tx(uchar *pstr,uchar n) //didnot send 0x0d to start print
{
uchar i; //no format,must \n or enter before use it
for(i=0;i<n;i++)
{
SBUF=*pstr++;
while(TI==0);
TI=0;
}
}
uchar sendmsg(uchar *pstr,uchar n)
{
uchar *buf="Hi,Girl!";
uchar ver[2]={0x55,0xaa};//假设校验是0x55aa
txbuf(buf,8);//发送起始标记8字节
txbuf(pstr,8);//发送内容8字节
txbuf(ver,2);//发送校验2字节
sta=STA_SENT;
uartcnt=0;
while(sta==STA_SENT)
{
if(sta==STA_VERERR){sta=STA_READY;return ACK_VERERR;}
if(sta==STA_SENTOK){sta=STA_READY;return ACK_OK;}
//假设TIMER0中断10次算超时
if(uartcnt>10){STA=sta_ready;return ACK_TIMEOUT;}
}
}
void main(void)
{
uchar temp;
Timer0初始化;
UART初始化
LOOP1:
temp=sendmsg("Hello,world!",8);
if(temp==ACK_OK)
{
}
else if(temp==ACK_TIMEOUT)
{
//超时处理,如果再发的话
goto LOOP1;
}
else if(temp==ACK_VERERR)
{
//校验错误处理,如果再发的话
goto LOOP1;
}
while(1);
}
void Timer0(void) interrupt 1
{
uartcnt++;
}
uchar rxbuf[32];
//假设下位机收到数据后并确认数据是正确后返回"Hi,Girl!"的前8个字节和2个字节的校验(0x55aa)
void Uart0(void) interrupt ? //主机接收中断,下位机的自己想
{
uchar i;
if(RI==0)return;
for(i=0;i<31;i++)rxbuf[i]=rxbuf[i+1];
rxbuf[31]=SBUF;
RI=0;
for(i=0;i<31-18;i++)
{
if(rxbuf[i]=='H')
{
if(rxbuf[i+1]=='i' && rxbuf[i+2]==',' && rxbuf[i+3]=='G' ......)//这里其实是要检查帧的起始标记
{
//检查到有效的起始标记
if(rxbuf[i+8]==0x55&&rxbuf[i+9]==0xaa)
{
//校验正确
for(i=0;i<31;i++)rxbuf[i]=0;
return STA_SENTOK;
}
else
{
//校验错误
for(i=0;i<31;i++)rxbuf[i]=0;
return STA_VERERR;
}
}
}
}
}