串口问题总结:

直通线交叉线:

标准DB9(PC的公头 2=RX;3=TX;5=GND),延长线(母头连PC,公头连设备)也是标准的直连线;但PC和设备之间需要交叉(设备端DB9的2=TX=MCU的TXD,即MCU和设备板子上的DB9是不交叉的),但这很不方便,一般PC到设备都让其直连,而设备的DB9与MCU之间实现交叉。对于有的即连接PC又连接单片机的一定要看其具体定义,根据自己的板子决定中间的连接线是否交叉。

1容易烧串口芯片:一段是单片机串口另一端是USB-RS232,后来发现单片机的串口芯片(MAX232)发热厉害,无法通讯.后发现虽然收发两端接错了,但想应该不至于因为有的为了测试串口线的收发是否正常专门短接RX-TX.后来看到文章才明白:如果两端串口都是带电源时,地线直接相连,如果此时地线电平差别很大,且经常热插拔就会烧芯片。解决的办法是插拔时至少保证一方的电源时关闭的。

2串口的信号线:虽然现在都用简化的3线串口,但所有的信号线内部并非都是悬空的。若内部非悬空外部悬空可能会差生干扰;若不用的信号线接反也有可能烧坏芯片。所以应对重要的信号线用光耦进行隔离。

3串口的组网:采用双绞线或网线中的两根,带电源线的最好也将VCC GND做成双绞结构。RX485/422布线时总线应远离动力线避免与其平行。采用终端匹配电阻的组网方式而非星型和网状。终端应该离总线较近以避免发射信号对总线的影响。

4串口软件相关的:接收超时、掉线检测、环形缓冲区

4.1接收超时:如果接收收据是ASCII可通过""作为判断结束的标志;如果是固定帧则通过数据长度来确定结束的完成;如果用查询方式也可根据自定义帧结构前端的数据长度来确定结束标志;modbus总线的每个字符间隔和帧间隔时间也可作为结束标志;如果都不是,通过中断接收如果确定结束标志?答案是用超时法:在串口接收中断中清零超时计数器(并设置一个使能累加超时计数器的标志),而在一个定时器中如果超时计数器使能,累加超时计数器并判断是否累加计数器超过预设阈值,是则禁止超时计数器标志,设置接收完成标志并清零计数器值;。因为一但数据接收完成就不会进入接收中断,计数器也就不会被置0,再周期性检查时它会累加直到大于预设值。设定值也就是在中断接收停止前提下第几次进入超时判断函数。(每次的时间就是判断函数的周期执行时间(如UCOS的周期性任务或定时器中断服务函数的周期调用间隔。)

4.2掉线检测:PC一般采用:每收到一帧数据就将掉线计数器清0,并调用掉线检测函数:拿掉线计数器与预设值比较:大于预设值说明长时间串口不活动,掉线了,就设置掉线标志位,重启串口(调用串口初始化函数),掉线计数器清0;否则掉线计数器累加。在PC有进程线程的系统里面很有用可以根据这个在不用串口是先将其从进程中关掉;或者PC机要发送数据时重启串口然后再发送;

  而对于单片机我们认为串口一直处于活动状态,除非程序自己通过关闭串口的时钟或其它设置方法来把串口关闭了,它没有PC那样复杂的进程概念,一掉线(周期性)就初始化串口反而造成串口的不正常。

4.3环形缓冲区:对于通讯各帧的长度都不一样如果都为其定义一个静态数组,会很浪费系统资源(静态分配一旦分配就不能撤销,而动态分配比较耗时增加系统负担),此时环形数据或叫环形缓冲区就非常适合这种情况:缓冲区的长度按照最长帧的长度来设置。通过帧结束和帧长度2个信息对应不同帧的通讯。

  接收情况:中断一直做是否大于总缓冲区长度的判断:是则清零否则累加 ,并将接收的数据存到接收缓冲区。根据结束标记(超时法),如果接收缓冲区长度大于0有数据就开始二级缓存(只缓存接收计数器计数的实际长度的数据),并清零接收计数器,让其下标为0重新从开头存储。

  发送情况:发送者将各包数据发缓冲器,有个发缓冲计数器的长度;串口发送中断集中将缓冲器的数据通过串口线发出,发送完发送长度清零。

原文地址:https://www.cnblogs.com/jieruishu/p/4443998.html