[APM32F0]

GPIO赋值你真的认为很简单吗?

[复制链接]
1220|36
手机看帖
扫描二维码
随时随地手机跟帖
onemoren|  楼主 | 2022-3-24 23:18 | 显示全部楼层 |阅读模式
本帖最后由 onemoren 于 2022-3-24 23:12 编辑

#申请原创#

清0一个IO口,一条简单C语言搞定,如:
GPIOD->DOUT&=0XBF;

很多初学者会认为这是一个原子操作,实际用KEIL做汇编,会发现有6条汇编指令来完成,如下面图片所示。


前两行汇编,是取址和算出DOUT寄存器并读出里面的值存在R0中;中间两行汇编,是将R0和0XBF运算后存于R0中;最后两行是用R1寻址DOUT寄存器,并将R0的值回写到DOUT中。

所以C中IO赋值语句不是原子操作,有没有想过,整个赋值过程会被中断打断?如果在这6行汇编中产生中断,要注意:
1.如果中断产生,会立即响应中断函数,中断函数中如果没对相同的端口,如上图的GPIOD的DOUT做操作,那不会产生什么异常;
2.如果中断函数中刚好有对GPIOD的DOUT做操作,那有可能会产生异常现象(因为退出中断后,又做了一次DOUT赋值)。

另外,大家要注意的是,从上面汇编最后两行来看,DOUT寄存器回写是8位同时回写。GPIOD->DOUT&=0XBF的目的本来是对第6位进行清0,但实际上最后回写时还是做了一次8位回写(关于GPIO输出操作,大家可以参考对比一下F103的BRR/BSRR操作,是不用16位同时回写的,但F003没有这两个寄存器)。

GPIO赋值是不是也挺复杂的。有兴趣多看看汇编出来的效果。



68B67512-4B49-4c35-99B5-AFBBB1884A6F.png

使用特权

评论回复
zjh20070904| | 2022-3-25 18:16 | 显示全部楼层
本帖最后由 zjh20070904 于 2022-3-25 18:17 编辑

如果存在这种情况,可以考虑以下方案应对楼上的赋值问题:关闭中断
GPIOD->DOUT&=0XBF;
开中断

这样进入中断处理函数中读取的数值就是成功赋值的。

使用特权

评论回复
Adagio827| | 2022-3-27 20:32 | 显示全部楼层
看完楼主精彩的分析有个小疑问:中断里对寄存器赋值是常规操作吗?

使用特权

评论回复
一个人破| | 2022-3-28 13:26 | 显示全部楼层
那是不是说,对于003芯片,相同GPIO的不同引脚操作,最好是都放在主函数,或者都放在中断中?

使用特权

评论回复
凉白开| | 2022-3-28 18:15 | 显示全部楼层
全放在中断中也会出现中断相互嵌套打断的问题,还是放主循环或者暂时关中断比较靠谱

使用特权

评论回复
多云转晴| | 2022-3-31 15:04 | 显示全部楼层
学到了学到了,亲测用f103直接操作ODR也会出现这个逻辑问题!

使用特权

评论回复
onemoren|  楼主 | 2022-3-31 18:48 | 显示全部楼层
Adagio827 发表于 2022-3-27 20:32
看完楼主精彩的分析有个小疑问:中断里对寄存器赋值是常规操作吗? ...

没有问题啊

使用特权

评论回复
xdqfc| | 2022-4-15 14:48 | 显示全部楼层
研究的真仔细哈

使用特权

评论回复
rafd| | 2022-4-15 23:18 | 显示全部楼层
谢谢

使用特权

评论回复
redone| | 2022-4-18 13:28 | 显示全部楼层
确实认为很简单了,因为只是用,没研究这么深入

使用特权

评论回复
maqianqu| | 2022-11-3 21:14 | 显示全部楼层
以前没有太注意这个。              

使用特权

评论回复
sheflynn| | 2022-11-3 21:28 | 显示全部楼层
IDR不是直接赋值的吗?              

使用特权

评论回复
mmbs| | 2022-11-3 21:47 | 显示全部楼层
寄存器操作的时候需要注意了。              

使用特权

评论回复
AloneKaven| | 2022-11-4 21:21 | 显示全部楼层
只是用,没研究这么深入

使用特权

评论回复
mmbs| | 2022-11-5 09:51 | 显示全部楼层
这个函数里面是这么定义的吗?              

使用特权

评论回复
Undshing| | 2023-1-3 16:06 | 显示全部楼层
中断相互嵌套打断好像是不可避免啊

使用特权

评论回复
fengm| | 2023-1-9 11:00 | 显示全部楼层
使用寄存器配置的吗?              

使用特权

评论回复
mnynt121| | 2023-1-9 11:10 | 显示全部楼层
GPIO使用库函数简单呢。              

使用特权

评论回复
pixhw| | 2023-1-9 12:11 | 显示全部楼层
习惯使用寄存器操作。              

使用特权

评论回复
i1mcu| | 2023-1-9 13:00 | 显示全部楼层
这个操作非常的难吗?              

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

14

主题

22

帖子

0

粉丝