笔者根据个人多年的嵌入式开发经验,在此斗胆总结一番,希望可以给一些新人提供排查方向。
在此,以串口通信为例,介绍排查步骤或方向:
通信,不管是单向通信还是双向通信,必然存在两个器件,所以我们需要重点关注这两个(这不是废话嘛~),而两者之间必然存在物理连接--导线(无线除外),遇到通信问题,应该首先保证导线连接正常、电压正常,如果这一点都没有确定,直接跳过该步骤,很大可能做无用功,查来查去,最终可能查了一个寂寞。
串口双向通信,一般会设计成主从方式,即一个主器件通过双方约定好的协议主动向从机发起数据传输,并且从机永远是被动应答。这样保证在多从机通信的情况下,不会出现数据错乱的情况(如果多个从机同时发送数据,可能造成交通拥堵,毕竟一个方向只有一条道)。
这种情况下,可以让主机定时发送固定数据帧(比如版本查询,这样可以减少变量),通过查看示波器来确定从机是否有返回数据。
如此,我们可以确定两个问题:
一是,观察主机发送引脚波形是否正常(串口平时一般为高电平,发数据时才会变化)、同时需要确定电压是否正常、波特率可看可不看、具体传输数据也是,因为该阶段只是从大的方向进行排查;二是,从机是否有回应。
这里又分为两种情况:
一是,从机没有回应:
此时,我们需要在接下来的排查步骤中确定几个问题:
<1>从机发送功能是否正常?
<2>主机发送的数据从机是否已经正常接收?
<3>主机发送的数据协议是否正确。
二是,从机有回应:
这种情况下,问题就比较简单,重点排查上层协议即可(可以保证从机的收、发没有问题)。
这里特别注意的是,波形测量位置一定是在最终点,而不是中间某个探测点或者模拟开关之类的器件。
比如,主机发送引脚,测量位置应该在从机芯片的接收引脚,而测量主机的接收则在主机芯片的接收引脚,才不会导致结果误判。
如果说步骤 1 发现主机没有正常传输波形产生,就要根据情况再确定一些问题。
1、如果发现波形失真、变形、电压不正常等情况,请呼叫硬件工程师一起排查。
2、主机芯片发送引脚可以看到波形,但从机接收引脚看不到,请使用万用表确定是否虚焊接。相反方向也排查一遍。
3、主机或从机不能正常发送或接收。
如果你使用了 DMA 发送,又使用了《终极串口接收方式,极致效率》笔记介绍的方式接收,那么你可以从以下方向进行排查(其他更简单的方式类似):
1)发送、接收引脚时钟是否开启、输入输出模式是否配置正常,发送引脚一般复用输出、接收一般上拉输入(如果只是引脚配置错误,发送 DMA的 计数器会变化,但是没有实际波形输出);
2)串口外设寄存器配置是否正常。如果全是 0 ,说时钟没有打开,或者未调用初始化函数,其次查看对应的 DMA 请求位(发送、接收,如果这个没有开启,DMA 计数器不会变化)、串口使能位等;波特率可以等发出波形再看,毕竟你现在连数据都没有。
3)查看 DMA 配置是否正常,外设、内存地址寄存器、计数器、使能位、对应通道的传输标志位(F4 如果传输标志不清除,无法启动下一次传输),总之把对应结构体的成员看一遍就对了,可能一个小配置错了,就导致整个传输失败。
4)如果是特殊引脚,看是否需要关闭默认功能,开启普通 GPIO 功能
5)如果是复映射功能,查看对应的映射寄存器是否配置正确,配置时,可能需要开启对应的时钟。
以上排查方法对发送、接收都适合。排查后,可以通过短接 Tx、Rx 引脚的方式确定发送、接收是否异常。如果是单方向的,可以配合串口模块测试。
终极杀招:如果上述排查都没有发现问题,还是失败,要么换板子,要么换一个可以用的简单例程修改后测试,此时可以对比例程调试模式下的寄存器配置(寄存器配置截图后对比)。
另外, 排查时需要特别注意的是,不能只看代码,不看实际寄存器的值。因为有的时候,代码也可能有各种各样的问题(比如时钟如果没有打开,那么即使有对应的配置代码,你一个寄存器值也写不进去),只有看最终寄存器的值才最安心。这里也多次强调了时钟的重要性,不过一般这种问题很容易排查。
上述排查,应该基本解决了双方通信问题的,即自发自收应该没有问题。但不代表双方就能够正常通信了。
这里可能存在几个问题:
1、双方波特率设置不匹配(这个问题比较容易查,直接看波形或寄存器(寄存器可能还没那么靠谱,外设一致可以)即可)
2、上层协议不匹配,比如 CRC 校验有问题、帧头定义有误等等……
3、对方解析函数有问题。
这个时候,配合逻辑分析仪分析是最方便的,到底是从机问题还是主机问题一目了然,当然你直接在Tx、Rx上并上两个串口模块的 Rx 去接收串口数据也是可以的~~
以上排查步骤不一定按顺序排查,但一般查看波形都是优先选择。
4、其他通信在此继续介绍一下 SPI 通信可能出现的问题:
1、SPI 发送数据后,没有延时即立刻开始接收(此时从机可能没有反应过来,也就没有数据输出),SPI 的波形可能失真(通过示波器可以观察出来),也可能波形挺好,但接收就是有问题;
2、 CS 控制时机不对,或者也可能需要延时一段时间。
3、SPI 波特率太高,导致器件无法识别。测试时最好使用最低波特率,但也不排除太低波特率反而不行的情况,所以多试试几种。
总之,测试代码应该要考虑最极端的情况(比如延时久一点,波特率慢一点),调通之后再优化这些参数,提高通信效率。
另外,如果有参考例程,可以直接对比例程输出的波形进行修改,直到你的代码输出波形(注意,这里直接对比波形)和例程保持一致,如果还是有问题,那么换从机器件再试。当然,电源这里也一定要先确定没有问题。
一般来说,只要 CS、CLK、MOSI 控制时序正确,器件的 MISO 引脚一定会有数据输出(即使你没有接主机的 MISO),如果你能看到 MISO 输出波形,但主机还是没有正确接收,那么就查主机的 MISO 引脚配置和延时情况了。
I2C 通信:
1、和 SPI 类似,查看时序问题;2、注意地址问题,有可能说明书的地址和实际的地址之间换算可能需要移位;3、注意从机锁死问题,传输前发几个停止信号过去试试。
以上就是笔者总结的和通信有关的排查指南,如果能对大家有所帮助。