OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 16734|回复: 22

stm32 定时器一旦启动立即进入中断吗

[复制链接]

15

主题

34

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
283
金钱
283
注册时间
2015-11-16
在线时间
92 小时
发表于 2016-3-4 13:01:49 | 显示全部楼层 |阅读模式
各位工程师你好

请问 stm32 定时器一旦启动立即进入中断吗?
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

1097

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3571
金钱
3571
注册时间
2014-12-2
在线时间
365 小时
发表于 2016-3-4 20:21:31 | 显示全部楼层
本帖最后由 xkwy 于 2016-3-4 20:24 编辑

在启动之前使用TIM->EGR[UG]触发一次更新就行了:
[mw_shl_code=c,true]void TIM3_init(uint32_t ms)
{
    /* Enable TIM3 Clock */
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
   
    TIM3->PSC = 7200 - 1;               /* CNT clock: 0.1 ms  */
    TIM3->ARR = (ms*10) - 1;            /* period */
    TIM3->CR1 = TIM_CR1_CEN;            /* Counter enable */
    TIM3->DIER = TIM_DIER_UIE;          /* Update interrupt enable */
   
    TIM3->EGR = TIM_EGR_UG;
    TIM3->SR = 0;
    NVIC_ClearPendingIRQ(TIM3_IRQn);
   
    NVIC_EnableIRQ(TIM3_IRQn);
}[/mw_shl_code]
(使用UG会触发一次UIF,所以随后必须清除TIM->SR[UIF],并清除NVIC的中断等待)

---------分割线-------------

如果没有问题,还可以使用TIM->CR1[URS]静默方式Update(这样就不必清除中断标志了):
[mw_shl_code=c,true]void TIM3_init(uint32_t ms)
{
    /* Enable TIM3 Clock */
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
   
    TIM3->PSC = 7200 - 1;               /* CNT clock: 0.1 ms  */
    TIM3->ARR = (ms*10) - 1;            /* period */
    TIM3->CR1 = (TIM_CR1_URS|TIM_CR1_CEN);  /* URS, Counter enable */
    TIM3->DIER = TIM_DIER_UIE;          /* Update interrupt enable */
   
    TIM3->EGR = TIM_EGR_UG;
   
    NVIC_EnableIRQ(TIM3_IRQn);
}
[/mw_shl_code]

附:TIM->CR1[URS]:

s.png


至于非得为什么这样,或许ST有他的考量吧。。。


坚决不用寄存器,拒绝重复造轮子。
回复 支持 3 反对 0

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2021-4-23
在线时间
2 小时
发表于 2021-4-23 16:52:13 | 显示全部楼层
xkwy 发表于 2016-3-4 20:21
在启动之前使用TIM->EGR触发一次更新就行了:
[mw_shl_code=c,true]void TIM3_init(uint32_t ms)
{

我感觉还是会进入一次中断,只不过进入中断后寄存器SR=0(这点非常奇怪),因为如果我把中断例程中的if(TIM7->SR & 0x01)判断去掉,它还是会一上电就执行我的中断代码,唯一的原因我感觉只能是:

       不管怎么折腾,定时器总是会一上电就进入中断,只不过用TIM->EGR触发更新的方式可以使得在进入第一次中断时,SR寄存器=0(这点非常奇怪,但也是我能想到的唯一原因了),而判断SR=1的语句碰巧滤掉了这次中断。
        至于网上另一种较为普遍的库函数做法(初始化后再清除中断标志位),其实也包含了TIM->EGR触发更新这步骤,因为定时器初始化库函数里有TIM->EGR触发更新语句,然后再加上清除中断标志位的语句,实际效果一样。
回复 支持 1 反对 0

使用道具 举报

4

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
149
金钱
149
注册时间
2013-10-11
在线时间
28 小时
发表于 2016-3-4 13:25:18 | 显示全部楼层
是的啊,一旦启动,到达时间就进入中断了!
回复 支持 反对

使用道具 举报

15

主题

34

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
283
金钱
283
注册时间
2015-11-16
在线时间
92 小时
 楼主| 发表于 2016-3-4 13:38:27 | 显示全部楼层
根号九LOVE 发表于 2016-3-4 13:25
是的啊,一旦启动,到达时间就进入中断了!

可是我感觉还没等到计时溢出就提前进入了一次
回复 支持 反对

使用道具 举报

22

主题

751

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1605
金钱
1605
注册时间
2015-6-10
在线时间
222 小时
发表于 2016-3-4 13:52:06 | 显示全部楼层
确实提前进了  而且怎么清标志都不好使

调试时候是这样,不调试不知道
回复 支持 反对

使用道具 举报

21

主题

299

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1834
金钱
1834
注册时间
2013-7-29
在线时间
278 小时
发表于 2016-3-4 14:29:16 | 显示全部楼层
我也遇到了这种情况,也不知道怎样解决。坐着高人给出解决方法。
回复 支持 反对

使用道具 举报

3

主题

548

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1383
金钱
1383
注册时间
2015-2-3
在线时间
197 小时
发表于 2016-3-4 16:16:25 | 显示全部楼层
是不是需要关中断?我之前做RTC也是这个问题
回复 支持 反对

使用道具 举报

21

主题

299

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1834
金钱
1834
注册时间
2013-7-29
在线时间
278 小时
发表于 2016-3-4 16:28:28 | 显示全部楼层
我用时过程如下:先清中断标志,再使能定时器,最后使能定时器中断,但是还第一次会不达到定时器就中断,后面就会按设定中断。
回复 支持 反对

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
发表于 2016-3-4 22:44:15 | 显示全部楼层
你说的这句话,严格意义上是不对的,必须得先使能定时的中断,比如溢出更新中断,然后才会在定时器计数溢出时,产生更新中断
回复 支持 反对

使用道具 举报

22

主题

147

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3983
金钱
3983
注册时间
2015-4-18
在线时间
403 小时
发表于 2016-3-5 20:20:03 | 显示全部楼层
配置好后清除中断
回复 支持 反对

使用道具 举报

21

主题

299

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1834
金钱
1834
注册时间
2013-7-29
在线时间
278 小时
发表于 2016-3-8 09:57:01 | 显示全部楼层
xkwy 发表于 2016-3-4 20:21
在启动之前使用TIM->EGR触发一次更新就行了:
[mw_shl_code=c,true]void TIM3_init(uint32_t ms)
{

能不能提供完整的代码看下?谢谢了!
回复 支持 反对

使用道具 举报

6

主题

1097

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3571
金钱
3571
注册时间
2014-12-2
在线时间
365 小时
发表于 2016-3-8 13:30:36 | 显示全部楼层
xuyan021 发表于 2016-3-8 09:57
能不能提供完整的代码看下?谢谢了!

这就是完整的初始化代码,你还想要啥?
坚决不用寄存器,拒绝重复造轮子。
回复 支持 反对

使用道具 举报

6

主题

1097

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3571
金钱
3571
注册时间
2014-12-2
在线时间
365 小时
发表于 2016-3-8 13:31:20 | 显示全部楼层
q546163199 发表于 2016-3-4 22:44
你说的这句话,严格意义上是不对的,必须得先使能定时的中断,比如溢出更新中断,然后才会在定时器计数溢出 ...

实践是检验真理的唯一标准
坚决不用寄存器,拒绝重复造轮子。
回复 支持 反对

使用道具 举报

6

主题

1097

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3571
金钱
3571
注册时间
2014-12-2
在线时间
365 小时
发表于 2016-3-8 13:32:00 | 显示全部楼层
752151619 发表于 2016-3-5 20:20
配置好后清除中断

尝试过这样做,但未果。

只有我在8楼提供的两种方法能解决问题
坚决不用寄存器,拒绝重复造轮子。
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2016-3-9
在线时间
0 小时
发表于 2016-3-9 13:20:21 | 显示全部楼层
楼主你好,你这个问题我当初在参加电子设计大赛的时候,也遇到过,就是启动STM32定时器的时候,一打开,定时器就进入了一次中断。  反正也折腾了我一段时间,后来我直接在程序里面设计一个标记位,就是刚开始启动的时候,那一次中断不执行动作,然后下一次中断才执行动作。  不知道能不能帮到楼主!!
回复 支持 反对

使用道具 举报

35

主题

193

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2015-12-27
在线时间
116 小时
发表于 2016-3-9 21:59:24 | 显示全部楼层
xkwy 发表于 2016-3-8 13:31
实践是检验真理的唯一标准

什么意思?
回复 支持 反对

使用道具 举报

8

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
92
金钱
92
注册时间
2015-4-15
在线时间
11 小时
发表于 2016-3-10 10:29:14 | 显示全部楼层
本帖最后由 BrightSunnySky 于 2016-3-10 10:57 编辑

TIM_ClearITPendingBit(TIM3, TIM_IT_Update);        //清除TIM3更新中断标志
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );     //使能TIM3更新中断
TIM_Cmd(TIM3, ENABLE);                                 //使能TIM3

配置完定时器,这样启动就不会立即进入中断。
回复 支持 反对

使用道具 举报

42

主题

141

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
342
金钱
342
注册时间
2015-5-26
在线时间
49 小时
发表于 2016-6-6 17:38:16 | 显示全部楼层
xkwy 发表于 2016-3-4 20:21
在启动之前使用TIM->EGR触发一次更新就行了:
[mw_shl_code=c,true]void TIM3_init(uint32_t ms)
{

请问,那造成一打开定时器就进入中断的原因是什么啊?将ERG的UG置1的话,就相当于产生了一次更新事件,为什么这样操作就可以避免定时器一打开就进入中断呢
回复 支持 反对

使用道具 举报

5

主题

65

帖子

0

精华

初级会员

Rank: 2

积分
155
金钱
155
注册时间
2014-8-16
在线时间
34 小时
发表于 2016-7-24 19:28:35 | 显示全部楼层
BrightSunnySky 发表于 2016-3-10 10:29
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);        //清除TIM3更新中断标志
TIM_ITConfig(TIM3,TIM_IT_ ...

是的,谢谢
回复 支持 反对

使用道具 举报

0

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2016-6-1
在线时间
11 小时
发表于 2016-11-24 20:40:38 | 显示全部楼层
http://blog.csdn.net/wuhuijun165 ... tionNum=2&fps=1


特意登录给出帖子,希望对以后的人看了有帮助,推荐说的也是对的。

要想不立即进入中断的话,需要先清除中断标志位然后在TIM_ITConfig(TIM3,TIM_IT_ ...。顺序错误的话,就立即进入中断了。
回复 支持 反对

使用道具 举报

9

主题

57

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2017-1-6
在线时间
32 小时
发表于 2017-1-20 15:23:57 | 显示全部楼层
同问一句,我启动定时器的时候是3s进入中断,但是下一次使用的时候就是立即进入中断,有人解决郭这种问题吗
回复 支持 反对

使用道具 举报

29

主题

338

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1181
金钱
1181
注册时间
2018-4-13
在线时间
170 小时
发表于 2018-10-23 13:43:19 | 显示全部楼层
爱娟娟 发表于 2017-1-20 15:23
同问一句,我启动定时器的时候是3s进入中断,但是下一次使用的时候就是立即进入中断,有人解决郭这种问题吗

你在中断处理中是否有耗时操作?比如处理所需时间大于等于3s,这样结束处理后其实就已经发生中断事件了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-25 05:29

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表