NVIC优先级分组
-
抢占优先级
可以进行中断嵌套的优先级,即可以不等上一个中断执行完成就进入下一个中断 -
响应优先级
决定中断发生的顺序,但不可嵌套
程序实现
对射式红外传感计次
#include "stm32f10x.h" // Device header
#include "delay.h"
#include "oled.h"
#include "countsensor.h"uint8_t key_val, key_old, key_up;
int main(){ OLED_Init();CountSensorInit();OLED_ShowString(1, 1, "Count:");while(1){OLED_ShowNum(1, 7, CountSenorGet(), 5);}
}
/*
countsensor.c
*/
#include "stm32f10x.h" // Device header
#include "delay.h"uint16_t count_sensor_count;void CountSensorInit(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);GPIO_InitTypeDef gpio_struc;gpio_struc.GPIO_Mode = GPIO_Mode_IPU;gpio_struc.GPIO_Pin = GPIO_Pin_14;gpio_struc.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &gpio_struc);GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);EXTI_InitTypeDef exti_init_struc;exti_init_struc.EXTI_Line = EXTI_Line14;exti_init_struc.EXTI_LineCmd = ENABLE;exti_init_struc.EXTI_Mode = EXTI_Mode_Interrupt;exti_init_struc.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_Init(&exti_init_struc); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef nvic_init_struc;nvic_init_struc.NVIC_IRQChannel = EXTI15_10_IRQn;nvic_init_struc.NVIC_IRQChannelCmd = ENABLE;nvic_init_struc.NVIC_IRQChannelPreemptionPriority = 1;nvic_init_struc.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&nvic_init_struc);
}uint16_t CountSenorGet(void){return count_sensor_count;
}void EXTI15_10_IRQHandler(void){// 该中断通道10~15共用,需判断Line14if(EXTI_GetITStatus(EXTI_Line14) == SET){if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0){ // 再次检验电平// 1 遮挡时计数 0 拿开时计数count_sensor_count ++;EXTI_ClearITPendingBit(EXTI_Line14);} }// 注意,该处数据乱跳很正常,光敏电阻变化导致PB14口的高低电平变化// 但是由于存在抖动,电平在很短时间变化多次,从而产生了多次计数
}
旋转编码器计次
#include "stm32f10x.h" // Device header
#include "delay.h"
#include "oled.h"
#include "encoder.h"uint8_t key_val, key_old, key_up;
int16_t num;
int main(){ OLED_Init();EncoderInit();OLED_ShowString(1, 1, "num:");while(1){num += EncoderGet();OLED_ShowSignedNum(1, 5, num, 5);}
}
/*
encoder.c
*/#include "stm32f10x.h" // Device headerint16_t encoder_count;void EncoderInit(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);GPIO_InitTypeDef gpio_struc;gpio_struc.GPIO_Mode = GPIO_Mode_IPU;gpio_struc.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;gpio_struc.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &gpio_struc);GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);EXTI_InitTypeDef exti_init_struc;exti_init_struc.EXTI_Line = EXTI_Line0 | EXTI_Line1;exti_init_struc.EXTI_LineCmd = ENABLE;exti_init_struc.EXTI_Mode = EXTI_Mode_Interrupt;exti_init_struc.EXTI_Trigger = EXTI_Trigger_Rising;EXTI_Init(&exti_init_struc); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef nvic_init_struc;nvic_init_struc.NVIC_IRQChannel = EXTI0_IRQn;nvic_init_struc.NVIC_IRQChannelCmd = ENABLE;nvic_init_struc.NVIC_IRQChannelPreemptionPriority = 1;nvic_init_struc.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&nvic_init_struc);nvic_init_struc.NVIC_IRQChannel = EXTI1_IRQn;nvic_init_struc.NVIC_IRQChannelCmd = ENABLE;nvic_init_struc.NVIC_IRQChannelPreemptionPriority = 1;nvic_init_struc.NVIC_IRQChannelSubPriority = 2;NVIC_Init(&nvic_init_struc);
}int16_t EncoderGet(void){int16_t temp;temp = encoder_count;encoder_count = 0;return temp;
}void EXTI0_IRQHandler(void){if(EXTI_GetFlagStatus(EXTI_Line0) == SET){ // 检查中断标志if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0){encoder_count --;}EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志}
}void EXTI1_IRQHandler(void){if(EXTI_GetFlagStatus(EXTI_Line1) == SET){if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0){encoder_count ++;}EXTI_ClearITPendingBit(EXTI_Line1);}
}