stm32——EXTI外部中断

发布于:2025-05-23 ⋅ 阅读:(25) ⋅ 点赞:(0)

NVIC优先级分组

  1. 抢占优先级
    可以进行中断嵌套的优先级,即可以不等上一个中断执行完成就进入下一个中断

  2. 响应优先级
    决定中断发生的顺序,但不可嵌套

程序实现

对射式红外传感计次

#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);
	}
}


网站公告

今日签到

点亮在社区的每一天
去签到