案例: 一文本框中有4个字节数据,点command后mscomm控件将这4个字节发送给了AT89S52,MCU接到数据,我的下位机程序利用中断处理了这4个字节数据(我一直在说字节哦)。 疑问: 单片机每次只能接收一个字节数据(SBUF只能装一个,否则会被后来的数覆盖),虽然MSCOMM是一次发了4个,但单片机收到一个字节后就应该中断(是收一个而不是4个都收到后才中断置位RI吧?),等我的程序把数据从SBUF后取走并清0RI后,它再接收下一个字节(是因为收到SBUF中数被移走的信号还是收到RI为0的信号?)直到4个都收到。但在MCU端中断时MSCOMM仍在发数据,这部分数岂不是会漏掉?另外我说的通信流程对吗?
|
这种情况通常不会出现,因为:
1、单片机每“次”的确只能接收1个字节,但由于串口的速度实在太低,通常都在115200bps以下(即使用了同步方式也“只能”达到1Mbps)。注意,是bps,位/秒,而不是“字节/秒”,这就是“串”行通信,要至少8个“bps时间”才能接收一个完整的字符,事实上,加上起始位等,8个位往往传送不了一个字节(不知道我的理解是不是有偏差),这就是说,速度至少还要再慢上8倍。
2、带有USART的单片机里USART一般都是做为“外部设备”,独立于MCU进行收发工作,即其收发过程中的串-并和并-串转换以及数据IO过程都是“自主”和“自动”的,不需要CPU逐位进行收发处理,因此,在CPU将数据送到SBUF后,便可以放手不管了,USART收发器会自动将SBUF的内容转换成串行数据发送出去。接收时也是由USART将串行数据转成并行数据并存放到SBUF后才会通知MCU(产生接收中断)。MCU所需要做的只是往SBUF送数或从SBUF中取数(都只要1个指令周期)。
3、设置串口参数的时候应该能看出,为了适应串口的慢,不得不动用定时器进行延时,以“产生”所需要的波特率,而这个“延时”通常都要给8位甚至16位定时器设置初值,定时器每一次计数都需要一个指令周期,即CPU可以执行一条指令的时间,而定时器两次串口溢出才仅仅接收或发送一个“位”,接收一个字节需要数倍于此的时间,那么这么长的时间对CPU来说,足以从容地从SBUF里取出数据并对其进行处理了。
4、即使CPU的任务相当繁重,或对接收到的每个字节都需要进行相当复杂的处理,我们也完全可以通过建立接收缓冲区的方式将暂时来不及处理的数据暂存起来,等CPU空闲时再做处理。而从SBUF取出数据并保存到缓冲区只需要很少的几条指令就能完成,不会影响到串口继续接收。
5、标准的RS-232协议并非只有TX、RX和GND三个引脚,即便是最简单的9针插口,也专门设计了检测传输状态和收发请求的针脚。如果单片机真的实在无法及时完成收发动作,也完全可以利用一个口线作为状态标识,使PC能够知道单片机什么时候可以接收数据,而不会任由数据丢失。
6、为了增加数据传输的可靠性,大量数据传输时通常都会采用CRC校验方式,并以“包”或“帧”的方式发送有格式约定的字节流,而非单个字符,这样一来,完全可以通过约定一些“通信协议”的方式,使收发双方都能够及时知道接收的数据是否完整,并及时重发新发送出错的数据。
现在所能想到的暂时就这么多,思路较乱,文字表述也挺罗索,谨供参考,欢迎交流。