赞
踩
NVIC:Nested Vectored Interrupt Controller【嵌套向量中断控制器】
管理内核外设和片上外设的所有中断功能;
EXTI:External Interrupt 【外部中断控制器】
管理GPIO的中断;
STM32F103ZET6总共19个外部中断
PA0~PG0,7个引脚中只有一个可以映射到EXTI0;
外部中断EXTI 9 ~ 5 合并为EXTI9_5中断;
外部中断EXT 15~10 合并为EXT15_10中断;
用2个按键控制2个LED状态翻转,用外部中断方式
main.c: 主程序
int main(void)
{
LED_Init();
KEY_Init();
LED_Off();
while(1) /* stop */;
//return 0;
}
bsp_led.c: LED灯初始化及开关函数
void LED_Init(void) { GPIO_InitTypeDef gpio_Struct_tmp = {0}; // 使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); // PB5 gpio_Struct_tmp.GPIO_Pin = GPIO_Pin_5; gpio_Struct_tmp.GPIO_Speed = GPIO_Speed_50MHz; gpio_Struct_tmp.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 GPIO_Init(GPIOB, &gpio_Struct_tmp); // PE5 gpio_Struct_tmp.GPIO_Pin = GPIO_Pin_5; gpio_Struct_tmp.GPIO_Speed = GPIO_Speed_50MHz; gpio_Struct_tmp.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 GPIO_Init(GPIOE, &gpio_Struct_tmp); } void LED_On(void) { GPIO_ResetBits(GPIOB, GPIO_Pin_5); GPIO_ResetBits(GPIOE, GPIO_Pin_5); } void LED_Off(void) { GPIO_SetBits(GPIOB, GPIO_Pin_5); GPIO_SetBits(GPIOE, GPIO_Pin_5); }
bsp_key.c: 按键初始化
void KEY_Init(void) { GPIO_InitTypeDef GPIO_tmp; EXTI_InitTypeDef EXTI_tmp; NVIC_InitTypeDef NVIC_tmp; /*-------------Step 1> 配置GPIO ---------------*/ // 2话不说开启时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); GPIO_tmp.GPIO_Mode = GPIO_Mode_IPU; GPIO_tmp.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_3; // PE4, PE3 GPIO_tmp.GPIO_Speed = GPIO_Speed_50MHz; // PE4, PE3 上拉输入 GPIO_Init(GPIOE, &GPIO_tmp); /*------------- Step 2> 配置AFIO ------------*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4); // EXTI_Line4 GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource3); // EXTI_Line3 /*------------- Step 3> 配置EXTI ------------*/ EXTI_tmp.EXTI_Line = EXTI_Line4; EXTI_tmp.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_tmp.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_tmp.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_tmp); // EXTI_Line4 EXTI_tmp.EXTI_Line = EXTI_Line3; EXTI_tmp.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_tmp.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_tmp.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_tmp); // EXTI_Line3 /*------------- Step 4> 配置NVIC ------------*/ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 中断优先级分组 NVIC_tmp.NVIC_IRQChannel = EXTI4_IRQn; NVIC_tmp.NVIC_IRQChannelPreemptionPriority = 0; NVIC_tmp.NVIC_IRQChannelSubPriority = 0; NVIC_tmp.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_tmp); NVIC_tmp.NVIC_IRQChannel = EXTI3_IRQn; NVIC_tmp.NVIC_IRQChannelPreemptionPriority = 0; NVIC_tmp.NVIC_IRQChannelSubPriority = 0; NVIC_tmp.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_tmp); }
4步配置GPIO的外部中断:
Step 1> 配置GPIO
Step 2> 配置AFIO
Step 3> 配置EXTI
Step 4> 配置NVIC
stm32f10x_it.c: 中断处理函数
// EXTI3 处理函数, key1; void EXTI3_IRQHandler(void) { EXTI_ClearITPendingBit(EXTI_Line3); LED_On(); } // EXTI4 处理函数, key0; void EXTI4_IRQHandler(void) { EXTI_ClearITPendingBit(EXTI_Line4); LED_Off(); }
中断数量:70个
STM32F103ZET6有70个中断 = 60外设中断 + 10个系统中断;
// 文件core_cm3.h:
static __INLINE void __enable_irq() { __ASM volatile ("cpsie i"); }
static __INLINE void __disable_irq() { __ASM volatile ("cpsid i"); }
GPIO, AFIO, EXTI, NVIC等功能模块,学习它们们时各个击破;
了解他们内部结构,内部寄存器,找点感觉,
重点看看每个模块的函数如何使用,
会使用后,看看内部如何编写的,非常能提高编程技能;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。