打印

50分高分挖坟,STM32中断清标志问题

[复制链接]
11789|43
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
NE5532|  楼主 | 2012-11-19 17:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
原帖
https://bbs.21ic.com/viewthread.php?tid=172906&highlight=%E6%B8%85%E9%99%A4%2B%E4%B8%AD%E6%96%AD%2B%E6%A0%87%E5%BF%97

也没有了结的,现在偶也遇到了。

环境:STM32L152RB(就是STM32L-Discovery的硬件环境),IAR 6.40.1.3812

问题描述:TMR2 向上计数,自动重载方式写LED闪烁,定时器溢出频率1Hz(已经用轮询方式验证其工作正常),换用中断方式编写时,清除TIM2_SR.UIF标志位的语句似乎不能放置在中断服务函数最后一句,如下:

void TIM2_IRQHandler (void)
{
    GPIOB_ODR ^= 0x000000C0;
    TIM2_SR &= ~(0x0001);           //换到后面就出错

    __no_operation();
    __no_operation();
}



CPU工作时钟采用内部HSI,经锁相环到32MHz,Flash采用64位宽取指,Flash等待周期按照DS的要求进行设置,内核电压1.8V

个人感觉似乎与取指有关,因为资料太多,未能找到相关支持论据,请大家指教。
沙发
NE5532|  楼主 | 2012-11-19 17:01 | 只看该作者
补充,上面的程序末尾加了两个NOP,只加1个的时候或者不加的时候程序就出问题,表现就是LED不闪烁。

使用特权

评论回复
板凳
airwill| | 2012-11-19 18:13 | 只看该作者
不是太能理解怎么会出现这样的问题呢?!
楼主何不借助仿真器, 帮助你检查两次执行的结果有啥区别, 或者串口把 状态寄存器发出来对比.

使用特权

评论回复
地板
李富贵| | 2012-11-19 18:50 | 只看该作者
用寄存器不用库函数的代码一点看的兴趣都没有。

使用特权

评论回复
5
NE5532|  楼主 | 2012-11-19 19:19 | 只看该作者
用寄存器不用库函数的代码一点看的兴趣都没有。
李富贵 发表于 2012-11-19 18:50


是呀,不然就不值50分了。

使用特权

评论回复
6
NE5532|  楼主 | 2012-11-19 19:22 | 只看该作者
不是太能理解怎么会出现这样的问题呢?!
楼主何不借助仿真器, 帮助你检查两次执行的结果有啥区别, 或者串口把 状态寄存器发出来对比.
airwill 发表于 2012-11-19 18:13


下午下班以前用仿真器看了一下,如果在GPIOB_ODR ^= 0x000000C0;这一句打断点,是可以进中断的,单步执行也可以正确取反端口,但是去掉断点执行,LED就只在一个状态。

用示波器检查LED驱动端,发现有1uS的脉冲,所以中断很有可能连续进了2次。

这个帖子就是来踢馆的,看多少人在搞低层,而不是只会用库函数哈。

使用特权

评论回复
7
NE5532|  楼主 | 2012-11-19 22:05 | 只看该作者
8
IJK| | 2012-11-19 22:20 | 只看该作者
或许答案在errata sheet上面

使用特权

评论回复
9
NE5532|  楼主 | 2012-11-19 22:31 | 只看该作者
或许答案在errata sheet上面
IJK 发表于 2012-11-19 22:20


有一定道理,明天看下。

使用特权

评论回复
10
bald| | 2012-11-20 11:09 | 只看该作者
本帖最后由 bald 于 2012-11-20 11:12 编辑

如果没有这个语句,CPU结束中断服务程序返回后举会立刻重新进入该程序反复循环执行。
那么唯一个可能就是硬件清除中断请求标志的速度低于程序运行的速度。导致程序返回中断处时先前的中断请求标志还处于被挂起的状态,因而再次进入中断服务程序。
这个问题,不止ST有,NXP的LPC系列也有同样现象。
其实可以把这条指令放在中断入口处,后面两条空操作指令也省了。

使用特权

评论回复
11
NE5532|  楼主 | 2012-11-20 11:19 | 只看该作者
怀疑到这一点了,但是找不到论据支持。把清标志指令放在首部,确实可以正常运行。

使用特权

评论回复
12
LingTian| | 2012-11-20 11:42 | 只看该作者
看看清标志位是置1还是置0。

使用特权

评论回复
13
bald| | 2012-11-20 11:51 | 只看该作者
这个不难,算一下退出时间,再查一下EBI的时钟频率。只要退出时间小于EBI时钟周期的2倍,这个现象就有可能发生。
如果可以实时仿真,单步运行到程序退出再查一下定时器的中断是否挂起。

使用特权

评论回复
14
IJK| | 2012-11-20 12:36 | 只看该作者
10L的想法是有道理的。
以前讨论过这个问题。
问题的原因是,外设通常挂在APB总线上,APB总线比较慢,CPU写外设寄存器要经过 AHB、APB再到外设,如果AHB到APB经过较大的分频,这种情况会更严重。
ARM有解决办法,就是专门的指令 DMB/DSB。

往大里说,其实这是一致性问题(coherence)的其中一个方面。

使用特权

评论回复
15
yinchunhua| | 2012-11-20 13:27 | 只看该作者
嗯,14楼说得有道理。CPU通过APB写外设寄存器是需要时间的。

使用特权

评论回复
16
xinzha| | 2012-11-20 14:55 | 只看该作者
本帖最后由 xinzha 于 2012-11-20 15:02 编辑
10L的想法是有道理的。
以前讨论过这个问题。
问题的原因是,外设通常挂在APB总线上,APB总线比较慢,CPU写外设寄存器要经过 AHB、APB再到外设,如果AHB到APB经过较大的分频,这种情况会更严重。
ARM有解决办法,就 ...
IJK 发表于 2012-11-20 12:36

在符合规范的良好设计中这不应该是问题,如果真是这样的话,那不同速度外设之间的问题就大了。
当写慢速apb时,cpu会被拉住在原地一直等待操作完成,除非是他们的apb模块做了这样的设计:立即给总线回个OK,而真正的操作要等很久才能完成。而如果中断控制器采用这样的设计对于AMBA总线规范来说就是非法的。一般可以这么做的都是有大缓存的设备,相当于write buffer的原理。
个人理解DMB和DSB只能保证到cache和总线这个级别,也就是说只能保证在DMB/DSB之前的指令和总线操作完成,而总线操作完成的标准就是slave回了OK(需需要slave参与的情况),在上面那种情况下是中断控制器不应该回OK时回了OK,应该一样会出问题。

使用特权

评论回复
17
huadongat| | 2012-11-20 15:53 | 只看该作者
怀疑是你的中断没有跑到清标志位的地方,另一个中断请求又引起中断了导致程序死循环一个状态。

使用特权

评论回复
18
NE5532|  楼主 | 2012-11-20 19:27 | 只看该作者
勘误表里没有发现什么有价值的东西,没有跑到清标志的地方这种假设不是太可能,因为没有其他中断开放,而且ISR里是线性程序,仍然没有明确满意的答案,召唤原厂大人啊。

使用特权

评论回复
19
NE5532|  楼主 | 2012-11-21 15:08 | 只看该作者
最新测试结果通报:

1.将Timer的溢出周期设置为100uS,示波器观察到ISR在退出后1uS左右又进入了一次,就是说每间隔100uS会进两次ISR。

2.在ISR里调用一个空函数,例如

void dummy (void)
{
;
}

无论放在清标志之前还是之后,程序都可以正常运行,通过反汇编观察输出代码,发现编译器使用了

POP {R0,PC}

指令实现中断返回;

当ISR内不调用任何函数时,编译器使用了

BX LR

指令实现中断返回;

当使用POP指令返回时,清标志在最末位一句也是正确的,当使用BX指令返回时,清标志指令后必须有2条语句,中断返回才能正常。

请裸奔爱好者们继续讨论。

使用特权

评论回复
20
xinzha| | 2012-11-21 16:05 | 只看该作者
本帖最后由 xinzha 于 2012-11-21 16:08 编辑

cortex-M3中不太应该使用POP {R0,PC}这样的指令来实现中断返回,因为在M系列架构中,中断返回的方式是根据不同类型的返回,向LR寄存器根据不同情况写入不同的几个固定模式值后执行bx lr,然后cpu会根据lr中的内容进行状态切换,堆栈切换以及现场恢复等。M3中每次中断会硬件压栈八个int32,而不是一个。或者说stm32不是标准M3,自己做了些改动就不知道了。
个人理解像POP {R0,PC}这样的指令并没有实现中断返回,程序依然还在中断模式下运行,至于为啥不崩溃也不好说了。

使用特权

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

本版积分规则

个人签名:††††看NE5532教学视频,炼就工程技术研发功力†††††††††† 《跟我学DC-DC电源管理技术》【从只会写软件成长为软硬兼施】 《印刷电路板设计进阶》【12年一线设计经验大放送】 《印刷电路板设计基础》【新手别怕,老工程师带你入门!】

159

主题

13769

帖子

586

粉丝