Cortex M系列内核中断中操作io失效原因分析

一.问题现象

问题:发现对LCD进行数据更新时,LCD屏幕闪烁背光不稳定,删除LCD数据更新程序时,背光稳定

软件实现:背光是在250us中断中对端口PC8操作实现对亮度的控制

二.原因

LCD进行数据更新显示时,大量的对多个IO端口输出状态进行操作,这些操作会影响中断中对LCD背光端口的操作,假如非中断中大量对GPIOC的任意端口进行操作时,中断中对GPIOC操作就可能失效!

 

  1. 由上面图片中蓝色部分,内核对io端口的操作大致分为3个部分

      a.从外设寄存器中读取GPIO的值(我这个单片机实际用到16bit,即整个PA0~PA15)

      b. 使用r0~r3的通用寄存器修改端口值、

      c.将值写回外设寄存器中     

2.若执行了步骤a,但未执行到c时被中断打断,此时r0值(即从外设读取的值)被压栈,,中断中执行io操作修改了当前外设寄存器的值,退出中断后r0出栈,然后又写回外设寄存器,导致中断中操作的值失效变回进入中断前的值

三.测试分析

1.汇编测试

汇编释义

R0 = POARTA寄存器的基地址(猜测是0x40013000)

将地址R0+0x10地址(PORTA->DO寄存器地址)的数据放在r0

       将0x1放在R3

      R1 = 255

R1=255+1=256=0x100

       用r1给r0或运算后值存入r0

R1 = POARTA寄存器的基地址

       将r0写到r1+x10地址的数据中去

      

仿真现象:

       在执行上面这段汇编的中间过程如果被中断打断,在中断中会修改PA端口DO寄存器的值,退出中断,且执行完上面最后一句后,中断中修改的值失效

2.示波器分析

波形发现对一个io进行操作后极短的时候又恢复到原样,很可能就是退出中断后还未完成非中断时io操作,在完成io操作之后,中断中操作的端口的寄存器的值又变回压栈前的值

图片:

无  

3.文档支持

在cortexM3权威指南发现下面这段话

 

上面的内容解释了为什么中断修改的io会在退出中断后恢复

四.解决方案

1.最推荐的方案就是使用SET和RESET寄存器,不使用DO寄存器,因为SET和RESET寄存器是只读寄存器,底层汇编读取这个寄存器值时其实是0,而这个寄存器写1有效,写0无效,所以不会有DO寄存器的相关问题

2如果你非要用DO寄存器,那么尽量避免非中断中的GPIO操作和中断中操作的GPIO是相同类型的GPIO(比如都是GPIOA)。

               

附件

1.我使用的单片机的寄存器分布

2.中断内中执行的测试程序

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值