因仑“3+1”工程特种兵精英论坛

标题: STM32的GPIO管脚位值取反的风险分析 [打印本页]

作者: 痛苦的滋味    时间: 2016-5-8 22:53
标题: STM32的GPIO管脚位值取反的风险分析
在《如何对STM32的GPIO管脚位值进行取反设置?》中有朋友提出的对于管脚取反设置的方法,我认为有一定的风险,在那里我说了下原因,但是没有引起大家的重视我认为有必要再发一个帖子来讨论下。
http://www.amobbs.com/thread-4580994-1-1.html

有朋友提出,对引脚取反的方法
“GPIOx->ODR ^= (1<<n);
如果要将PC7取反,则为GPIOC->ODR ^= (1<<7);”

让我们分析下  GPIOC->ODR ^= (1<<7); 这种方式吧,其实是有一定的风险的。
看下反汇编如下:
   55:             GPIOC->ODR ^= (1<<7);

     //读取 GPIOC->ODR 的值,放到R0中
1.   0x0800B868 4807         LDR      r0,[pc,#28]  ; @0x0800B888
2.   0x0800B86A 68C0         LDR      r0,[r0,#0x0C]
     //将读取的在R0中的值进行改写
3.   0x0800B86C F0800002   EOR      r0,r0,#0x80
     //写回GPIOC->ODR
4.   0x0800B870 4905          LDR      r1,[pc,#20]  ; @0x0800B888
5.   0x0800B872 60C8          STR      r0,[r1,#0x0C]
……
     //GPIOC地址
6.   0x0800B888 1000      DCW      0x1000
……

如果在2~5步之间有中断程序,改写了GPIOC->ODR的值,那么这个程序执行结果可能不是我们所希望的。

个人推荐没有副作用的方法有两个,
一. 位带操作
二.((GPIOC->ODR & GPIO_Pin_7) ? (GPIOC->BRR  = GPIO_Pin_7): (GPIOC->BSRR = GPIO_Pin_7))





欢迎光临 因仑“3+1”工程特种兵精英论坛 (http://bbs.enlern.com/) Powered by Discuz! X3.4