51单片机串口通信的问题
发布网友
发布时间:2022-04-22 06:06
我来回答
共5个回答
热心网友
时间:2023-12-14 12:07
比如发送abcdefghi,就回送I get aI get bI get cI get dI get eI get fI get gI get hI get i;
但是结果总是有一部分数据被忽略掉,....
----
每当收到一字节,就回送七字节。
时间上,明显不同。
楼主发送数据,采用了查询方法。
那么,在等待发送七字节结束的期间,显然会丢失收到的字节。
采用查询的方法进行发送,肯定会有遗漏。
发送,也应该用中断的方法,这才不会影响接收。追问这位大哥说的我大概明白是怎么回事,就是时间上存在问题,那么具体的程序应该怎么改呢???就是说怎么用中断的方法发送数据呢???
追答关于这个问题,我写过一篇文章。
搜:
做而论道 51单片机串口的发送与接收
百度一下。
在主函数中,先发送第一个字节,并不用等待。
然后在发送中断中,发送下一字节,也不用等待,马上退出串行中断,这就不会耽误接收了。
热心网友
时间:2023-12-14 12:07
首先ES是串口中断的标志,不是用来确定接收是否完成的!!!!!要确定是否接收完成,应该用if(RI){……};
串口发送的时候是1位1位发送的,对于a这个字符,ASC码转换成16进制就是61H(01100001),发的时候8个数据位和1个停止位。单片机在接收的时候,接收的SBUF是8位的(还有个发送的SBUF,地址是一样的),因此,只要波特率一致,01100001就会被送到SBUF,这时RI置位,表示接收完成。LZ因为设置了接收中断(ES=1),因此这时程序就跳到中断里去了。
程序运行出现问题,我认为,是因为LZ把发送数据的代码写到了接收中断中,当在发送数据的时候,串口还是在接收数据的,SBUF被更新,这导致了数据的丢失(PS:个人感觉哦)
建议LZ把发送和接收分开来写,用一个数组把上位机发过来的数据先存起来,然后在按你的格式发送出去!!!
热心网友
时间:2023-12-14 12:08
不要把中断开关写到中断函数里面。可以试试下面这样写:
# include <reg51.h>
# define uchar unsigned char
# define uint unsigned int
uchar code table[]="I get ";
uchar j,i,a[20],flag;
void chushi()
{
TMOD=0x20; //定时器1工作方式为2
TH1=0xfd; // 放入初值
TL1=0xfd;
TR1=1; //打开定时器1
REN=1; //允许接受信号
SM0=0; //确定串行口工作方式为1
SM1=1;
EA=1;//打开总中断开关
ES=1; //打开串行口中断开关
}
void ser()interrupt 4
{
a[j]=SBUF;
while(!RI);
RI=0; //收到数据后置RI为0
flag=1;
}
void main()
{
chushi();
while(1)
{
if(flag)
{
ES=0; //标志位确定是否收到数据
flag=0;
for(i=0;i<6;i++)
{
SBUF=table[i];
while(!TI);
TI=0;
}
SBUF=a[j++];
while(!TI);
TI=0;
SBUF=' ';
while(!TI);
TI=0;
ES=1;
}
}
}
热心网友
时间:2023-12-14 12:08
你的错误属于初学者常见错误。
中断函数处理时间太长了,请将中断函数中的
for(i=0;i<6;i++)
{
SBUF=table[i];
while(!TI);
TI=0;
}
放到主函数中。
热心网友
时间:2023-12-14 12:09
关键问题还J没清零。