起因
在做项目移植PS2代码的时候,本来以为简简单单的一件事,关了好几个小时的时间,读到的数据一直不正确(数据跳动不稳定),本来决定放弃,但还是决定将坑一踩到底!所以就有了这篇文章
解决方向
以之前排坑的经验,问题可能出在以下几个地方
- 硬件问题
- IO口配置
- 时钟树配置以及定时器配置
- 底层驱动代码不适配(广泛流传的代码都是F103版本)
问题探索
- 硬件问题
找了一块F103板子,正常驱动,排除了PS2损坏,线材断路问题。 - IO口配置
按照官方例程配置的IO口,并测试了每个IO口输出正常,也试过修改IO口的速度,都无济于事。 - 底层驱动代码不适配
PS2驱动代码中,只有以下几行涉及到了底层
#define DI HAL_GPIO_ReadPin(PS2_DAT_GPIO_Port,PS2_DAT_Pin)
#define DO_H HAL_GPIO_WritePin(PS2_CMD_GPIO_Port,PS2_CMD_Pin,GPIO_PIN_SET)
#define DO_L HAL_GPIO_WritePin(PS2_CMD_GPIO_Port,PS2_CMD_Pin,GPIO_PIN_RESET)
#define CS_H HAL_GPIO_WritePin(PS2_CS_GPIO_Port,PS2_CS_Pin,GPIO_PIN_SET)
#define CS_L HAL_GPIO_WritePin(PS2_CS_GPIO_Port,PS2_CS_Pin,GPIO_PIN_RESET)
#define CLK_H HAL_GPIO_WritePin(PS2_CLK_GPIO_Port,PS2_CLK_Pin,GPIO_PIN_SET)
#define CLK_L HAL_GPIO_WritePin(PS2_CLK_GPIO_Port,PS2_CLK_Pin,GPIO_PIN_RESET)
核对每个IO口的宏定义,与板子上IO口对应。源代码中还有许多处用到了delay_ms/delay_us函数,由于使用的是成熟的定时器库,保证了延时的准确性,所以也排除这个问题。 4. 定时器配置 与F1使用TIM4作为内部时钟不同,F4使用TIM5,但是两者都是普通定时器,并没有本质区别,所以问题显然不出在这里 5. 时钟树配置 最后的最后,将问题定位到了这里!!!!!! 参照官方例程,将主时钟频率从180MHz改成了72MHz,它正常了!!!!! 也就是说,PS2对通信时序的要求很高,F4的最大时钟频率会加速通信的频率,可能导致了某些协议的崩溃,所以才出现了数据不稳定的情况。
展望
最优解当然不是改动芯片的时钟频率,这会影响到其他程序的执行速率。由理论上分析,可以通过在驱动代码中添加一定的delay操作,使时序恢复正常,但是由于时间关系,我没有做下去,希望感兴趣的选手可以深入研究一下,最好能共享代码出来嘻嘻嘻。(目前网上没有找到)
欢迎大家与我进一步交流:2250017028@qq.com
|