OpenEdv-开源电子网

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

中断服务函数里面为什么一定要有这些关于状态标志位的函数?

[复制链接]

10

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2018-9-28
在线时间
10 小时
发表于 2018-10-10 11:13:39 | 显示全部楼层 |阅读模式
1金钱
#include "time.h"
#include "sys.h"
#include "stm32f10x_tim.h"
#include "led.h"

void TIM3_Init(u16 ARR,u16 PSC)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBasestructure;
        NVIC_InitTypeDef NVIC_Initstructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
       
        TIM_TimeBasestructure.TIM_Period=ARR;
        TIM_TimeBasestructure.TIM_Prescaler=PSC;
        TIM_TimeBasestructure.TIM_ClockDivision=TIM_CKD_DIV1;
        TIM_TimeBasestructure.TIM_CounterMode=TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM3,&TIM_TimeBasestructure);
         
       
       
        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
       
        NVIC_Initstructure.NVIC_IRQChannel=TIM3_IRQn;
        NVIC_Initstructure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Initstructure.NVIC_IRQChannelSubPriority=3;
        NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority=3;
        NVIC_Init(&NVIC_Initstructure);
        TIM_Cmd(TIM3,ENABLE);
}
       
void TIM3_IRQHandler(void)
{
        if( TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET )  
        {
                LED0=!LED0;
                TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
        }
}




//画红线处:为什么这里面必须要清除标志位,不清楚程序就不能实现?标志位的含义到底是什么,这个功能又是什么?  ps:我是刚学的菜鸟

最佳答案

查看完整内容[请看2#楼]

发生了一次中断就会自动由硬件置位该标识,可以理解为系统检查该标识决定是否进入中断服务函数处理,但前提是该标识之前是复位的.如果处理后不复位该标识,当又发生中断事件时系统认为还在处理之前的中断,于是就不会重入服务函数了.
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

29

主题

338

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1181
金钱
1181
注册时间
2018-4-13
在线时间
170 小时
发表于 2018-10-10 11:13:40 | 显示全部楼层
发生了一次中断就会自动由硬件置位该标识,可以理解为系统检查该标识决定是否进入中断服务函数处理,但前提是该标识之前是复位的.如果处理后不复位该标识,当又发生中断事件时系统认为还在处理之前的中断,于是就不会重入服务函数了.
回复

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4307
金钱
4307
注册时间
2018-6-30
在线时间
808 小时
发表于 2018-10-10 11:59:14 | 显示全部楼层
开了中断,一般就需要清除中断,避免出现干扰,你可以把它去掉看下情况怎么样
业精于勤荒于嬉;行成于思毁于随!
回复

使用道具 举报

24

主题

695

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1666
金钱
1666
注册时间
2016-4-29
在线时间
266 小时
发表于 2018-10-10 12:29:42 | 显示全部楼层
之所以进中断是因为中断标志置位了,如果不清除会一直进中断
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2018-10-10 15:28:56 | 显示全部楼层
本帖最后由 edmund1234 于 2018-10-10 15:33 编辑

不清除就会重入中断函数, 所以是必须清的

如果说你确实只使能了update中断, 其它的TIM3的中断都没用到, 这一条是可以不要的 if( TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET )   
回复

使用道具 举报

3

主题

288

帖子

0

精华

高级会员

Rank: 4

积分
865
金钱
865
注册时间
2018-8-28
在线时间
130 小时
发表于 2018-10-10 15:51:50 | 显示全部楼层
实际上就是对SR清零,在 中断产生后,通过状态寄存器的值来判断此次产生的中断属于什么类型。然后执行相关的操作, 我们这里使用的是更新(溢出)中断,所以在状态寄存器 SR 的最低位。在处理完中断之后应 该向 TIM3_SR 的最低位写 0,来清除该中断标志。
回复

使用道具 举报

1

主题

13

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2018-10-9
在线时间
3 小时
发表于 2018-10-10 16:43:02 | 显示全部楼层
产生中断以后,对应的中断标志位并不会自动清除。你可以想象,如果你不去手动清除中断标志位,当程序退出后,MCU检测到该标志位仍为1,那么它又会再次进入该中断,这是我们程序中不希望看到的。
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
7
金钱
7
注册时间
2018-10-10
在线时间
1 小时
发表于 2018-10-10 17:03:05 | 显示全部楼层
这么说吧,中断发生后会设置这个中断标志位,由NVIC中断管理去控制现在触发哪一个,然后通过中断向量表调用相应中断函数,这些都是硬件帮你做的,在中断里就需要软件去告诉硬件我已经执行了这个中断,即清除相应标志位,否则会一直重复触发这个中断,表现为卡死在中断里或者直接跳到了hardfault中断的死循环里。为什么不让硬件帮你自动清除呢?我也想过这个问题,但是考虑到多个中断复用同一个中断函数的情况,你就会发现软件手动清除中断标志处理起来会非常灵活,另外就是进中断的清标志位和出中断再清标志位的执行效果在某些情况下是不同的。有例外,比如串口接收中断只要取走了数据会自动清标志位。另外如果你用的不是标准库,而是HAL库,没记错的话清标志是固件库帮你做了的,你只需要重写一个回调函数就行了。
回复

使用道具 举报

9

主题

165

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2018-4-6
在线时间
31 小时
发表于 2018-10-10 21:34:07 | 显示全部楼层
不清掉就一直卡中断
回复

使用道具 举报

10

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2018-9-28
在线时间
10 小时
 楼主| 发表于 2018-10-11 08:51:49 | 显示全部楼层
1208 发表于 2018-10-10 11:59
开了中断,一般就需要清除中断,避免出现干扰,你可以把它去掉看下情况怎么样

按照程序的原理,去掉这个就应该一直保持在中断里面,那么led还是应该闪烁,因为我是在中断服务函数中控制这个led灯亮的,但是我把这个清楚标志位删了之后这个灯就不亮了。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-20 20:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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