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共用,需判断Line14
if(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 header
int16_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);
}
}