|
求助:8051串口 中断接收 查询发送 数据丢失
[复制链接]
用C8051F020与PC机之间串口通讯.
单片机用中断方式接收数据,用查询方式发送数据.
我的程序是为了实现:定义5字节数据为一帧,PC机向单片机发送数据,当数据到达一帧(5个字节)的时候,单片机向PC机将这一帧数据发送出去.
我用了2个BUFF,第1个BUFF用于依次接收SBUF0中的数据,将第1个BUFF里面的数据传入第2个BUFF.当第2个BUFF的数据达到5个字节的时候,就将取数标志置位,就将BUFF2中的数从串口发出.
用串口调试助手进行调试,试验现象如下:
发送5字节数据为一帧(1包数据),例如:AA BB CC DD EE.每次当单片机复位或者重起之后,发送之后接收到的第一帧数据总是为AA CC DD EE,丢失第2字节数据;然后不复位继续发送,则正常接收AA BB CC DD EE,只要不复位或者重起,之后都是正常.
我用16进制和非16进制,都出现"首次"会第2个数据丢失的现象,之后都是正常.
而我观察BUFF2中数组inbuf2[len2]中的第2个元素,观察显示,第2个元素"BB"正常.
通俗讲,就是复位后第一次发送,第2字节数据"应该"正常接收,但就是发不出来,我也试过会不会是延迟的问题,但是我手动1个字节1个字节地发送,还是出现上述问题,就觉得不会是延迟方面问题.
这个程序是没有校验代码的,如果加上了校验,会不会改善?请问一下,如何加校验呢?
还有个小问题,如果对2个BUFF进行复位?
请大家帮我分析一下,谢谢!
其中程序如下,我略去了一些代码.
#define len 5 //BUFF1缓冲区长度
unsigned char idata inbuf[len];
unsigned char idata *inlast=inbuf;
unsigned char idata *getlast=inbuf;
bit inbufsign; //BUFF1缓冲区非空标志 有=1,空=0
bit inbufful; //BUFF1缓冲区满标志 满=1,非满=0
bit read_flag=0; //取数标志位
int i=0;
unsigned char *str;
unsigned int strlen;
#define len2 5 //BUFF2缓冲区长度
unsigned char idata inbuf2[len2];
unsigned char idata c,c1;
//主函数//
void main (void)
{
...
...
EA=1; //中断开放
while(1) //查询发送
{
if(read_flag) //如果取数标志置位,就将读到的数从串口发出
{
read_flag=0;
sendstring(inbuf2,len2);
}
}
}
//串口接收中断//
void serial() interrupt 4
{
if(RI0)
{
RI0=0;
if(!inbufful) //查询BUFF1是否满
{
*inlast=SBUF0; //放入数据
inlast++; //放入位置加1
inbufsign=1;
if(inlast=inbuf+len)
inlast=inbuf; //地址到顶部回底部
if(inlast=getlast)
inbufful=1; //BUFF1置满标志
}
c1=getbyte();
inbuf2=c1; //将BUFF1中数据依次读入到BUFF2的数组中
i++;
if(i==5)
{
read_flag=1;
i=0; //若达到5字节时,置取数标志位,启动发送
}
}
}
//从缓冲区BUFF1中取一个byte//
unsigned char getbyte(void)
{
while(!inbufsign); //BUFF1空等待
ES0=0;
c=*getlast; //取数据
getlast++; //最后取走的数据位置加1
inbufful=0; //BUFF1的满标志清0
if(getlast=inbuf+len)
getlast=inbuf; //地址到顶部回到底部
if(getlast=inlast)
inbufsign=0; //地址相等,BUFF1置空标志
ES0=1;
return(c);
}
//向串口发送一个字符//
void sendchar(unsigned char ch)
{
SBUF0=ch;
while(TI0==0);
TI0=0;
}
//向串口发送一个字符串,strlen为该字符串长度//
void sendstring(unsigned char *str,unsigned int strlen)
{
int k;
for(k=0;k
{
sendchar(*str);
str++;
}
while(k
}
谢谢
|
|