标题: 有关RS232串行通信的问题,请教大家 [打印本页]

作者: newlined    时间: 2024-9-5 16:58
标题: 有关RS232串行通信的问题,请教大家
现在51单片机普遍集成了232串口,我的理解是既然集成了串口,收发都应该是不用占用CPU的时间的(中断处理除外),在一些例程中,我发现单片机接收数据是这样的,程序中初始化串口后,打开串口中断,当串口接收数据完成后,会触发串口中断,在中断程序中,只要 RI=0;DAT=SBUF;取走数据即可。在发送数据时,我原以为只要在主程序中 执行 SBUF=DAT;在串口中断程序中有语句TI=0;就行。但实际中不行,数据发不出去,要这样编写程序,
SBUF=DAT;while(!TI); TI=0; 程序是这样执行的,数据送到SBUF;触发串口发送机制,CPU等待发送完成,然后清TI。为什么是这样,数据送到SBUF,让串口自己发送,发送完成后,通过中断通知CPU不行吗?以前那些没有集成232串口,用外部232芯片的单片机,在发送数据时,也要等待数据发送完成吗?谢谢。


作者: xuyaqi    时间: 2024-9-6 06:42
CPU把8位要发送数据传给串口硬件发送是需要时间的,while(!TI); 就是等发完。
作者: runmuel    时间: 2024-9-6 08:41
建议看一看51单片机的结构原理你就会明白了,串口中断没有硬件清除中断标志功能,至于232芯片只是增强传输距离作用而已。
作者: newlined    时间: 2024-9-6 09:04
xuyaqi 发表于 2024-9-6 06:42
CPU把8位要发送数据传给串口硬件发送是需要时间的,while(!TI); 就是等发完。

谢谢您的回复,CPU把8位要发送数据传给串口硬件发送是需要时间,这个时间不是就是执行 SBUF=DAT;的时间吗?您的意思是数据送到SBUF后就TI自动置1了?请看下面的时序图,看起来执行SBUF=DAT后TI不置1,发送完成后才置1。

无标题.png (19.21 KB, 下载次数: 6)

无标题.png

作者: zhuls    时间: 2024-9-6 09:12
SBUF=DAT;是可以的,
如果你确定你近期内不再使用DAT/SBUF,无视while(!TI)这句代码。删除它也是可以的。
同理,如果你一次只接收一个字节(8bit),那么接收中断也可以取消,需要的时候再去取数。
作者: wufa1986    时间: 2024-9-6 09:18
是不占用,只是不等待的话程序复杂度会提高
作者: 黄youhui    时间: 2024-9-6 09:20
现在51单片机普遍集成了232串口?能问下那几款吗?下次我试试
作者: ppcbug    时间: 2024-9-6 10:04
本来 MCU 的串口 发送 也是可以工作在 中断模式下的。

第一次, 手工填写 第一个字节, SBUF =‘A'  
以后在中断中:

XXXXXX interrupt 4
{
if(RI)
{

}
if(TI)
{
TI=0;
SBUF='B'  继续发
}
}

只是 中断UART发送  非常麻烦 还有不节省资源, 很少人用。
作者: newlined    时间: 2024-9-6 10:28
发表于 2024-9-6 09:20
现在51单片机普遍集成了232串口?能问下那几款吗?下次我试试

我现在是用STC的单片机,现在51的单片机都集成了串口,是不是我描述的不严谨?加了那种232收发器的接口才叫232串口?
作者: newlined    时间: 2024-9-6 10:54
ppcbug 发表于 2024-9-6 10:04
本来 MCU 的串口 发送 也是可以工作在 中断模式下的。

第一次, 手工填写 第一个字节, SBUF =‘A'  

谢谢您及大家的回复,看了大家的回复后,我领悟到我首贴描述的不严谨,在发送单个字节,不连续占用串口应该是可以的,程序发不出去数据是因为上一次的数据没有发送完成,连续往SBUF写数据,造成数据丢失,编写程序时应该判断串口是否正在发送数据,正在发送数据就不要往SBUF写了。我现在才明白,有一些程序,定义一个TI_BUSY,初始化为0,程序如下:串口中断中是这样:if (TI){TI=0;TI_BUSY=0;} 主程序是这样:
while(TI_BUSY);SBUF=DAT;TI_BUSY=1;这样数据在串口忙时就等待串口发送完成,再发送下一个数据,需要浪费CPU时间,但不丢数据,我以前的程序就是这个路子,是不是如果发送数据的要求不是很严格的情况下,也可以这样编写:串口中断中还是跟以前一样,主程序中是这样:if (!TI_BUSY){SBUF=DAT;TI_BUSY=1},先判断串口发送器是不是忙,如果忙就不往SBUF写数据,等下次再写。

作者: xiaobendan001    时间: 2024-9-6 11:39
怎会很少人用呢?如果是只有一两个字节,等待还行,如果多了,就很费时间,尤其是发送数量不确定的情况下,就更需要中断方式了。发送先放入缓冲区里面,然后启动,在中断里面继续直到发送完成。
作者: xuyaqi    时间: 2024-9-6 13:23
newlined 发表于 2024-9-6 09:04
谢谢您的回复,CPU把8位要发送数据传给串口硬件发送是需要时间,这个时间不是就是执行 SBUF=DAT;的时间吗 ...

SBUF=DAT 只是指令,CPU收到指令后要执行,硬件把8位传送完TI才置1。
作者: newlined    时间: 2024-9-6 14:26
ppcbug 发表于 2024-9-6 10:04
本来 MCU 的串口 发送 也是可以工作在 中断模式下的。

第一次, 手工填写 第一个字节, SBUF =‘A'  

您的这个方法,能做到需要串口连续发数据时,一股脑全部发完,一个字节接一个字节,很巧妙,发完这一组数据后,需要再发时,是不是需要再手工填写一个字节, SBUF =‘A'  ?
作者: ppcbug    时间: 2024-9-6 14:36
newlined 发表于 2024-9-6 14:26
您的这个方法,能做到需要串口连续发数据时,一股脑全部发完,一个字节接一个字节,很巧妙,发完这一组数 ...

是的。 待发缓冲发完以后,就不再产生发中断了.
设置完新的发缓冲,必须在中断外触发一下, 让它继续产生 TI  发中断。


作者: newlined    时间: 2024-9-7 08:05
不好意思各位,昨天下午测试程序,发现我在10贴中的程序有误,要串口正确工作,如下程序是可以的:串口初始化,串口中断中不对TI操作,主程序如下:SBUF=DAT; while(!TI);TI=0;主程序要等待串口发送完成,我原来想的CPU不等待串口的程序,现在还调试不通。
作者: newlined    时间: 2024-9-7 09:44
刚才程序验证,8楼ppcbug老师的方法是可行的。
作者: newlined    时间: 2024-9-7 10:04
刚才程序验证:10楼中我提到的方法也是可以的,程序每次跑到这里,如果串口不忙,就发送一个字节的数据,忙就下一次发送。
作者: 人中狼    时间: 2024-9-7 10:27
newlined 发表于 2024-9-7 08:05
不好意思各位,昨天下午测试程序,发现我在10贴中的程序有误,要串口正确工作,如下程序是可以的:串口初始 ...

先理解串口的基本工作原理吧
作者: newlined    时间: 2024-9-7 14:37
人中狼 发表于 2024-9-7 10:27
先理解串口的基本工作原理吧

这几天正看的晕头转向中
作者: Graves    时间: 2024-9-7 15:38
完全可以看下stc的UART发送例程,有阻塞发送和队列发送,阻塞发送就SBUF=DAT; while(!TI);TI=0;可以着重看看队列发送的实现
作者: newlined    时间: 2024-9-9 08:53
qq475878026 发表于 2024-9-7 15:38
完全可以看下stc的UART发送例程,有阻塞发送和队列发送,阻塞发送就SBUF=DAT; while(!TI);TI=0;可以着重看 ...

谢谢您的回帖,麻烦看看这两个程序是队列发送吗?

STC32G-DEMO-CODE.rar

41.73 KB, 下载次数: 1






欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1