赞
踩
中断问量表
。NVIC:嵌套中断向量控制器
在STM32中,NVIC用来统一分配中断优先级和管理中断,属于内核外设
中断优先级:值越小,优先级越高
中断响应是正常的流程,引脚电平变化触发中断
事件响应不会触发中断,而是触发别的外设(ADC,DMA等)操作,属于外设之间的联合工作
EXTI9_5和EXTI15_10:通过标志位区分哪个中断触发的
其它外设:用来触发其它外设操作的,也就是事件响应
\qquad
当挡光片在这个对射式红外传感器中间经过时,DO输出电平变化的信号,电平跳变的信号触发STM32 PB14号口的中断,在中断函数中,执行变量自加,主循环调用OLED显示该变量。
\qquad
接上模块后,使用挡光片在传感器中间槽上来回进出,进入时开关指示灯灭,出来后开关指示灯亮,说明高低电平输出没问题
步骤:
1.配置RCC,打开时钟
2.配置GPIO,选择端口为输入模式
3.配置AFIO,选择所使用的这一路GPIO,连接到EXTI
4.配置EXTI,选择边沿触发方式(上升,下降,双边),选择触发响应方式(中断响应,事件响应)
6.配置NVIC,给中断选择合适优先级
c文件:
#include "stm32f10x.h" // Device header static uint32_t countSensor = 0; static uint8_t flag_count = 0; void countSensor_init(void) { EXTI_InitTypeDef EXTI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* Enable GPIOB clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /* Enable AFIO clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); /* Configure PB14 pin as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Connect EXTI14 Line to PB14 pin */ GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14); /* Configure EXTI14 line */ EXTI_InitStructure.EXTI_Line = EXTI_Line14; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* Enable and set EXTI14 Interrupt to the lowest priority */ NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } uint32_t getCountValue(void) { if(flag_count==1){ if(countSensor<10){ countSensor++; }else{ countSensor=0; } flag_count = 0; } return countSensor; } void EXTI15_10_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line14) != RESET) { flag_count = 1; /* Clear the EXTI line 14 pending bit */ EXTI_ClearITPendingBit(EXTI_Line14); } }
h文件:
#ifndef __COUNTSENSOR_H
#define __COUNTSENSOR_H
extern void countSensor_init(void);
extern uint32_t getCountValue(void);
#endif
main.c
#include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include "countsensor.h" int main(void) { OLED_Init(); countSensor_init(); OLED_ShowString(1, 1, "count:"); while (1) { OLED_ShowNum(1,7,getCountValue(),2); } }
c文件:
#include "stm32f10x.h" // Device header int32_t Encoder_Count; void encoder_init(void) { EXTI_InitTypeDef EXTI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* Enable GPIOB clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /* Enable AFIO clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); /* Configure PB0/PB1 pin as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Connect EXTI0/1 Line to PB1/0 pin */ GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0); GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); /* Configure EXTI1/0 line */ EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* Enable and set EXTI0 Interrupt to the lowest priority */ NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable and set EXTI1 Interrupt to the lowest priority */ NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } int32_t Encoder_Get(void) { int32_t Temp; Temp = Encoder_Count; Encoder_Count = 0; return Temp; } void EXTI0_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line0) != RESET) { /*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/ if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0) { if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) { Encoder_Count --; } } /* Clear the EXTI line 0 pending bit */ EXTI_ClearITPendingBit(EXTI_Line0); } } void EXTI1_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line1) != RESET) { /*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/ if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) { if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0) { Encoder_Count ++; } } /* Clear the EXTI line 1 pending bit */ EXTI_ClearITPendingBit(EXTI_Line1); } }
h文件
#ifndef __ENCODER_H
#define __ENCODER_H
extern void encoder_init(void);
extern int32_t Encoder_Get(void);
#endif
main.c
#include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include "encoder.h" int32_t num ; int main(void) { OLED_Init(); encoder_init(); OLED_ShowString(1, 1, "count:"); while (1) { num += Encoder_Get(); OLED_ShowSignedNum(1,7,num,5); } }
注意:在配置外设GPIO时,如果不确定该配置为什么模式,可参阅参考手册外设的GPIO配置
,里面有每个外设的各个引脚所配置的模式 ,如下
\qquad 对于stm32,想要获取的信号是外部驱动的很快的突发信号,如旋转编码器,红外遥控接收头,按键等。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。