发布于2021-05-30 19:16 阅读(1183) 评论(0) 点赞(1) 收藏(5)
外部中断部分相对简单,库函数也相对较少,以下,根据函数名字基本可以看出其作用。
void EXTI_DeInit(void);
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
void EXTI_ClearFlag(uint32_t EXTI_Line);
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
对于互联型产品,外部中断/事件控制器由20个产生事件/中断请求的边沿检测器组成,对于其它
产品,则有19个能产生事件/中断请求的边沿检测器。每个输入线可以独立地配置输入类型(脉冲
或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏
蔽。挂起寄存器保持着状态线的中断请求。
EXTI控制器的主要特性如下:
● 每个中断/事件都有独立的触发和屏蔽
● 每个中断线都有专用的状态位
● 支持多达20个软件的中断/事件请求
● 检测脉冲宽度低于APB2时钟宽度的外部信号。
外部中断/事件控制器框图, 如下所示
中断屏蔽寄存器(EXTI_IMR)
0:屏蔽
1:开放
事件屏蔽寄存器(EXTI_EMR)
0:屏蔽
1:开放
上升沿触发选择寄存器(EXTI_RTSR)
0:禁止上升沿触发
1:允许上升沿触发
下降沿触发选择寄存器(EXTI_FTSR)
0:禁止下降沿触发
1:允许下降沿触发
软件中断事件寄存器(EXTI_SWIER)
挂起寄存器(EXTI_PR)
0:没有中断产生
1:有中断产生
外部中断通用I/O映像
● EXTI线16连接到PVD输出
● EXTI线17连接到RTC闹钟事件
● EXTI线18连接到USB唤醒事件
● EXTI线19连接到以太网唤醒事件(只适用于互联型产品)
外部中断/事件寄存器映像
中断初始化函数
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
{
uint32_t tmp = 0;
/* Check the parameters */
assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode));
assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger));
assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line));
assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd));
tmp = (uint32_t)EXTI_BASE;
if (EXTI_InitStruct->EXTI_LineCmd != DISABLE)
{
/* Clear EXTI line configuration */
EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line;
EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line;
tmp += EXTI_InitStruct->EXTI_Mode;
*(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
/* Clear Rising Falling edge configuration */
EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line;
EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line;
/* Select the trigger for the selected external interrupts */
if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling)
{
/* Rising Falling edge */
EXTI->RTSR |= EXTI_InitStruct->EXTI_Line;
EXTI->FTSR |= EXTI_InitStruct->EXTI_Line;
}
else
{
tmp = (uint32_t)EXTI_BASE;
tmp += EXTI_InitStruct->EXTI_Trigger;
*(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
}
}
else
{
tmp += EXTI_InitStruct->EXTI_Mode;
/* Disable the selected external lines */
*(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line;
}
}
EXTI_InitTypeDef
EXTI_Line
EXTI_Mode
EXTI_Trigger
EXTI_LineCmd
初始化示例
EXTI_InitTypeDef EXTI_InitStructure; //EXTI_InitStructure 结构体定义
EXTI_InitStructure.EXTI_Line = EXTI_Line3; // 中断线3
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //中断线使能
//以上理解为:依次为EXTI_InitStructure 结构体中的成员赋值
EXTI_Init(&EXTI_InitStructure); //调用中断初始化函数 (参数:结构体指针)
获取中断标志位
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
{
ITStatus bitstatus = RESET;
uint32_t enablestatus = 0;
/* Check the parameters */
assert_param(IS_GET_EXTI_LINE(EXTI_Line));
enablestatus = EXTI->IMR & EXTI_Line; //检查中断是否被屏蔽,即中断是否使能:0屏蔽,1:开放。
if (((EXTI->PR & EXTI_Line) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
//EXTI->PR & EXTI_Line 中断线上是否产生了中断
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
清除中断标志位
void EXTI_ClearITPendingBit(uint32_t EXTI_Line)
{
/* Check the parameters */
assert_param(IS_EXTI_LINE(EXTI_Line));
EXTI->PR = EXTI_Line;
}
以上两个函数成对使用,用例如下
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生
{
中断逻辑…
EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE 上的中断标志位
}
}
EXTI_TypeDef
在这里需要说明一下,
1、固件库还提供了两个函数用来判断外部中断状态以及清除外部状态标志位的函数 EXTI_GetFlagStatus 和 EXTI_ClearFlag,他们的作用和前面两个函数的作用类似。
2、只是在 EXTI_GetITStatus 函数中会先判断这种中断是否使能,使能了才去判断中断标志位,而EXTI_GetFlagStatus 直接用来判断状态标志位。
EXTI_GetFlagStatus
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_GET_EXTI_LINE(EXTI_Line));
if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET) //没有判断中断是否使能
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
外部中断线有20个,可是中断函数却只有7个,分别是:
1、EXTI0_IRQHandler
2、EXTI1_IRQHandler
3、EXTI2_IRQHandler
4、 EXTI3_IRQHandler
5、EXTI4_IRQHandler
6、EXTI9_5_IRQHandler
7、EXTI15_10_IRQHandler
中断线 0-4 每个中断线对应一个中断函数, 中断线 5-9 共用中断函数 EXTI9_5_IRQHandler,中
断线 10-15 共用中断函数 EXTI15_10_IRQHandler。
1、同一个中断函数中 如何判断是哪个中断线上的中断
在同一个中断处理函数中,有多条中断线时常用到以下两个函数:
1、ITStatus EXTI_GetITStatus(uint32_t EXTI_Line) ;
中断服务函数的开头判断中断是否发生
2、void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
清除某个中断线上的中断标志位
举例:
void EXTI9_5_IRQHandler(void)
{
//中断线5
if(EXTI_GetITStatus(EXTI_Line5)!=RESET)//判断中断线5上的中断是否发生
{
中断逻辑…
EXTI_ClearITPendingBit(EXTI_Line5); //清除 LINE5 上的中断标志位
}
//中断线6
if(EXTI_GetITStatus(EXTI_Line6)!=RESET)//判断中断线6上的中断是否发生
{
中断逻辑…
EXTI_ClearITPendingBit(EXTI_Line6); //清除 LINE6 上的中断标志位
}
//中断线7
if(EXTI_GetITStatus(EXTI_Line7)!=RESET)//判断中断线7上的中断是否发生
{
中断逻辑…
EXTI_ClearITPendingBit(EXTI_Line7); //清除 LINE7 上的中断标志位
}
.
.
.
.
}
2、同一个中断线,可以配置多个中断么?
答案:不可以
以中断线0为例
中断线0 有 A、B、C、D、E、F、G 7个端口,每个端口的0号管脚构成了一条中断线,可以看出来,这是一个多路选择器,7路输入,1路输出,意味着同一时刻这7个管脚只有一个能在中断线0上
总结:
1.同一pin口不可同时配置外部中断
2.不同pin口可以同时配置外部中断
3.共用中断服务函数,以中断标志位区分
4.外部中断的本质是某中断线得到信号触发,进入对应的中断服务函数的过程。
5.某一路中断线只能同时跟一个pin口搭上
stm32f10x_it.c 里面是用来编写中断服务函数,但是中断服务函数也可以随意编写在工程
里面的任意一个文件里面。
原文链接:https://blog.csdn.net/weixin_45633643/article/details/117323177
作者:动漫魔动
链接:http://www.phpheidong.com/blog/article/86845/21bc5a942cd3787f6b82/
来源:php黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 php黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-4
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!