STM32笔记之 EXIT(外部中断)
程序员文章站
2022-04-01 21:49:23
...
写在前面:
本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
目录
在上一篇 STM32笔记之 GPIO引脚中,有用到 EXIT外部中断作为 Key输入触发,所以本篇来诠释一下 EXIT外部中断的功能
一、EXIT控制原理
二、外部中断的 I/O映像
从上面图中我们可以发现,每一组端口都对应着相应的 “ 线 ”,先称之为线吧!
其中,还有 4条 EXIT线是特殊的,看上图
三、中断服务
#define EXTI_Line0 ((uint32_t)0x00001) /*!< External interrupt line 0 */
#define EXTI_Line1 ((uint32_t)0x00002) /*!< External interrupt line 1 */
#define EXTI_Line2 ((uint32_t)0x00004) /*!< External interrupt line 2 */
#define EXTI_Line3 ((uint32_t)0x00008) /*!< External interrupt line 3 */
#define EXTI_Line4 ((uint32_t)0x00010) /*!< External interrupt line 4 */
#define EXTI_Line5 ((uint32_t)0x00020) /*!< External interrupt line 5 */
#define EXTI_Line6 ((uint32_t)0x00040) /*!< External interrupt line 6 */
#define EXTI_Line7 ((uint32_t)0x00080) /*!< External interrupt line 7 */
#define EXTI_Line8 ((uint32_t)0x00100) /*!< External interrupt line 8 */
#define EXTI_Line9 ((uint32_t)0x00200) /*!< External interrupt line 9 */
#define EXTI_Line10 ((uint32_t)0x00400) /*!< External interrupt line 10 */
#define EXTI_Line11 ((uint32_t)0x00800) /*!< External interrupt line 11 */
#define EXTI_Line12 ((uint32_t)0x01000) /*!< External interrupt line 12 */
#define EXTI_Line13 ((uint32_t)0x02000) /*!< External interrupt line 13 */
#define EXTI_Line14 ((uint32_t)0x04000) /*!< External interrupt line 14 */
#define EXTI_Line15 ((uint32_t)0x08000) /*!< External interrupt line 15 */
#define EXTI_Line16 ((uint32_t)0x10000) /*!< External interrupt line 16 Connected to the PVD Output */
#define EXTI_Line17 ((uint32_t)0x20000) /*!< External interrupt line 17 Connected to the RTC Alarm event */
#define EXTI_Line18 ((uint32_t)0x40000) /*!< External interrupt line 18 Connected to the USB Device/USB OTG FS
Wakeup from suspend event */
#define EXTI_Line19 ((uint32_t)0x80000) /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */
以上的 EXIT线的宏都可以在 stm32f10x_exti.h文件中找到
上图的中断函数表可以在参考手册中找到,下面用一个表格来整合官方划分的中断函数
I/O 口外部中断函数 | 中断线 |
EXTI0_IRQHandler | EXIT0 Line |
EXTI1_IRQHandler | EXIT1 Line |
EXTI2_IRQHandler | EXIT2 Line |
EXTI3_IRQHandler | EXIT3 Line |
EXTI4_IRQHandler | EXIT4 Line |
EXTI9_5_IRQHandler | EXIT5 - 9 Line |
EXTI15_10_IRQHandler | EXIT10 - 15 Line |
因为在官方提供的 stm32f10x_it.c文件中,所列出来的中断函数只有下图的部分重要的中断,其他外设中断函数需要我们自己添加
外设的中断需要我们自己添加,官方在 stm32f10x_it.c文件的底部也有注释说明,看下图
四、配置流程(代码解析)
在上一篇配置 Key输入检测的代码中,如下进行配置
其中,上图框选的部分是跟 EXIT是相关联的,你可能会问 NVIC是干嘛的,别急,下篇再解释;
在分析 EXTI函数之前先来了解一下两个组定义
/**
* @brief EXTI Trigger enumeration
*/
typedef enum
{
EXTI_Trigger_Rising = 0x08, // 上升沿触发
EXTI_Trigger_Falling = 0x0C, // 下降沿触发
EXTI_Trigger_Rising_Falling = 0x10 // 上下沿触发
}EXTITrigger_TypeDef;
/**
* @brief EXTI Init Structure definition
*/
typedef struct
{
uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled.
This parameter can be any combination of @ref EXTI_Lines */
EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines.
This parameter can be a value of @ref EXTIMode_TypeDef */
EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
This parameter can be a value of @ref EXTIMode_TypeDef */
FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines.
This parameter can be set either to ENABLE or DISABLE */
}EXTI_InitTypeDef;
1、GPIO_EXTILineConfig() 函数
/* Connect EXTI1 Line to PB.01 pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); // 将 EXTI1线连接到 PB.01引脚
↓↓ 函数实现 ↓↓
/**
* @brief Selects the GPIO pin used as EXTI Line.
* @param GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines.
* This parameter can be GPIO_PortSourceGPIOx where x can be (A..G).
* @param GPIO_PinSource: specifies the EXTI line to be configured.
* This parameter can be GPIO_PinSourcex where x can be (0..15).
* @retval None
*/
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
{
uint32_t tmp = 0x00;
/* Check the parameters */
assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource));
assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03));
AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp;
AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)));
}
2、EXTI_Init()函数
/* Configure EXTI1 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line1; // 选着 EXIT1线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 配置为输入模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能 EXIT1线
EXTI_Init(&EXTI_InitStructure);
↓↓ 函数实现 ↓↓
/**
* @brief Initializes the EXTI peripheral according to the specified
* parameters in the EXTI_InitStruct.
* @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure
* that contains the configuration information for the EXTI peripheral.
* @retval None
*/
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;
}
}
3、EXTI_GenerateSWInterrupt()函数
/* Generate software interrupt: simulate a falling edge applied on EXTI1 line */
EXTI_GenerateSWInterrupt(EXTI_Line1); // 生成软件中断:模拟应用于 EXTI1线路的下降沿
↓↓ 函数实现 ↓↓
/**
* @brief Generates a Software interrupt.
* @param EXTI_Line: specifies the EXTI lines to be enabled or disabled.
* This parameter can be any combination of EXTI_Linex where x can be (0..19).
* @retval None
*/
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line)
{
/* Check the parameters */
assert_param(IS_EXTI_LINE(EXTI_Line));
EXTI->SWIER |= EXTI_Line;
}
五、中断函数处理
/**
* @brief This function handles External line 1 interrupt request.
* @param None
* @retval None
*/
void EXTI1_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line1) != RESET) // 检测 EXIT线路是否触发
{
/* Clear the EXTI line 1 pending bit */
EXTI_ClearITPendingBit(EXTI_Line1); // 清除 EXIT线路触发标志
}
}
上一篇: mybaits 分页查询
下一篇: JS将unicode码转中文的实例代码