现在的位置: 首页 > 综合 > 正文

时序的问题

2018年06月06日 ⁄ 综合 ⁄ 共 905字 ⁄ 字号 评论关闭

今天一天解决了一个问题.

在Wince下与设备通过SPI通讯,过程如下:

1. 给设备发Reset信号

2. 检查数据是否Ready

3. SPI通讯

为了具体化,我列出程序的伪代码:

1. 拉高Reset脚

2. Sleep 1毫秒(给出的规格是最少Delay 10us)

3. 拉低Reset脚

4. 检查Ready脚是否为高

5. SPI采集数据

Bug的表现是这样的:

a. 有时候测不到Ready信号

b. 有时候能取到正常的数据,大部分时候数据完全不对,偶尔前半部分数据对.

c. 为了模块化,我改了一版封装比较好的版本,就是把混在一起的语句用几个函数包装了起来.测试时发现封装好的版本大部分时候检测不到信号,而且取得错误数据的几率高很多.

请电子工程师检查代码,认为逻辑是对的,没问题.然后开始怀疑取数据时SPI速度太快,改了之后没任何改善.

逐行比较两个版本的代码,改成几乎完全一致,唯一不同是多了函数封装.结果还是封装版本出错的几率高.开始怀疑函数调用产生了开销,导致时序不正确.检查了各个关键点,没发现特别耗时的操作.有点走头无路,就差察看汇编代码了.

我还用延时代替Ready信号的检查,再SPI切换片选信号前后加延时,加大Reset信号为高电平的时间.所有的办法都试了.

只有...,只有...,只有没把Wince里等待1毫秒的函数Sleep(1)换掉.因为Sleep最小就是1ms.

因为改过系统自带的SPI驱动,怀疑驱动没正确加载,上午的时候尝试过用GPIO软模拟SPI.后来发现模拟出来的CLOCK信号频率太低,遂放弃.

抱着试试看的态度,把Sleep(1)换成了for循环.

居然成功了,那一刻,我觉得自己是成功人士.

设备检测到FIFO_RESET的上升沿,就开始设置READY信号,接着自动通过SPI丢数据上来.因为Sleep太久,就错过了这精彩的一幕幕,只抓到个尾巴.

结论:

1. 设备代码不OK,检查READY信号的逻辑不合理,或者,至少说明多久时间内要检查;还有,FIFO_RESET延时没有给出上限.

2. 这类开发中,所有偶发的Bug都与时间有关.

3. CSDN的博客还是很烂.中途我丢失一部分内容,重新排了一次版,因为段落的距离太大大大大了

抱歉!评论已关闭.