前言
我们经常遇到一个困惑:明明感觉代码没有问题,但是运行时就是无法按照预期执行。并且把别人的示例拿过来跑是可以跑通的,确认了硬件没问题,比对代码也找不出差异。
这通常是因为一些细节问题导致的,这类问题在逐检查时常常因为当局者迷难以发现,最常见的就是位运算相关的细节错误例如:
-
清零错误:
GPIOA->CRH &= GPIO_CRH_MODE10; //期望将GPIOA的CRH寄存器中的PA10工作模式清零
上述代码少了
~
,正确操作如下:GPIOA->CRH &= ~GPIO_CRH_MODE10; //期望将GPIOA的CRH寄存器中的PA10工作模式清零
-
判断某一位是否为1:
if(USART1->SR & USART_SR_RXNE == 1) { buffer[size++] = USART1->DR; }
通过按位与来判断某一位是否为1应该操作如下:
if(USART1->SR & USART_SR_RXNE) { buffer[size++] = USART1->DR; }
MDK外设寄存器视图
通过MDK的Debug功能,我们实时查看代码执行到断电时,对应的外设寄存器中的值,从而可视化地分析响应的寄存器是否真的按照预期被设置了,从而避免检查代码时无法察觉细节错误的情况。
以 GPIOA->CRH &= GPIO_CRH_MODE10
为例,我们期望通过这一行代码将 CRH
寄存器的第8、9个bit清零
设置断点
可以在该行代码的左侧点击打上断点:
放行程序到断点处暂停
然后进入Debug模式并通过Run使程序停在断点处:
打开外设系统视图
找到对应寄存器
步进并查看对应寄存器是否按照预期被设置
步进后发现本来预期只设置MODE10,结果发现其他的bit位也被影响了(高亮部分),说明我们的代码有问题
直接修改寄存器并生效
如上,我们可以通过勾选/取消勾选(相当于ODR置1/0),并实时观察LED的变化。其他寄存器中可编辑的地方应该也都是可以实时手动修改的。