阅读量:0
00. 目录
文章目录
01. NVIC相关函数
相关头文件: misc.h
1.1 NVIC_PriorityGroupConfig函数
/** * @brief Configures the priority grouping: pre-emption priority and subpriority. * @param NVIC_PriorityGroup: specifies the priority grouping bits length. * This parameter can be one of the following values: * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority * 4 bits for subpriority * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority * 3 bits for subpriority * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority * 2 bits for subpriority * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority * 1 bits for subpriority * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority * 0 bits for subpriority * @retval None */ void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); 功能: 设置优先级分组:先占优先级和从优先级 参数: NVIC_PriorityGroup:优先级分组位长度 返回值: 无
1.2 NVIC_PriorityGroup类型
/** @defgroup Preemption_Priority_Group * @{ */ #define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority 4 bits for subpriority */ #define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority 3 bits for subpriority */ #define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority 2 bits for subpriority */ #define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority 1 bits for subpriority */ #define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority 0 bits for subpriority */
1.3 NVIC_Init函数
/** * @brief Initializes the NVIC peripheral according to the specified * parameters in the NVIC_InitStruct. * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains * the configuration information for the specified NVIC peripheral. * @retval None */ void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) 功能: 根据 NVIC_InitStruct 中指定的参数初始化外设 NVIC 寄存器 参数: NVIC_InitStruct:指向结构 NVIC_InitTypeDef 的指针,包含了外设 GPIO 的配置信息 返回值: 无
1.4 NVIC_InitTypeDef类型
typedef struct { uint8_t NVIC_IRQChannel; //指定要启用或禁用的IRQ通道 uint8_t NVIC_IRQChannelPreemptionPriority;//指定的IRQ通道的抢占优先级 uint8_t NVIC_IRQChannelSubPriority; //指定的IRQ通道的次级优先级 FunctionalState NVIC_IRQChannelCmd; //IRQ通道是启用还是禁用 } NVIC_InitTypeDef;
NVIC_IRQChannel取值
#ifdef STM32F10X_MD ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */ USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ USART1_IRQn = 37, /*!< USART1 global Interrupt */ USART2_IRQn = 38, /*!< USART2 global Interrupt */ USART3_IRQn = 39, /*!< USART3 global Interrupt */ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ #endif /* STM32F10X_MD */
成员NVIC_IRQChannelPreemptionPriority可赋的值:最大取值15,具体有上面设置的优先级组中规定的位数决定
成员NVIC_IRQChannelSubPriority可赋的值:最大取值15,具体有上面设置的优先级组中规定的位数决定
成员NVIC_IRQChannelCmd可赋的值:ENABLE or DISABLE
02. 外部中断相关API
2.1 GPIO_EXTILineConfig
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); 功能: 选择 GPIO 管脚用作外部中断线路 参数: GPIO_PortSource: 选择用作外部中断线源的 GPIO 端口 GPIO_PinSource:待设置的外部中断线路 返回值: 无
参数:GPIO_PortSource 选择用于EXTI线的GPIO端口
/** @defgroup GPIO_Port_Sources * @{ */ #define GPIO_PortSourceGPIOA ((uint8_t)0x00) #define GPIO_PortSourceGPIOB ((uint8_t)0x01) #define GPIO_PortSourceGPIOC ((uint8_t)0x02) #define GPIO_PortSourceGPIOD ((uint8_t)0x03) #define GPIO_PortSourceGPIOE ((uint8_t)0x04) #define GPIO_PortSourceGPIOF ((uint8_t)0x05) #define GPIO_PortSourceGPIOG ((uint8_t)0x06)
参数:GPIO_PortSource 选择用于EXTI线的GPIO端口
/** @defgroup GPIO_Pin_sources * @{ */ #define GPIO_PinSource0 ((uint8_t)0x00) #define GPIO_PinSource1 ((uint8_t)0x01) #define GPIO_PinSource2 ((uint8_t)0x02) #define GPIO_PinSource3 ((uint8_t)0x03) #define GPIO_PinSource4 ((uint8_t)0x04) #define GPIO_PinSource5 ((uint8_t)0x05) #define GPIO_PinSource6 ((uint8_t)0x06) #define GPIO_PinSource7 ((uint8_t)0x07) #define GPIO_PinSource8 ((uint8_t)0x08) #define GPIO_PinSource9 ((uint8_t)0x09) #define GPIO_PinSource10 ((uint8_t)0x0A) #define GPIO_PinSource11 ((uint8_t)0x0B) #define GPIO_PinSource12 ((uint8_t)0x0C) #define GPIO_PinSource13 ((uint8_t)0x0D) #define GPIO_PinSource14 ((uint8_t)0x0E) #define GPIO_PinSource15 ((uint8_t)0x0F)
2.2 EXTI_Init
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct); 功能: 根据 EXTI_InitStruct 中指定的参数初始化外设 EXTI 寄存器 参数: EXTI_InitStruct:指向结构 EXTI_InitTypeDef 的指针,包含了外设 EXTI 的配置信息 返回值: 无
EXTI_InitTypeDef类型
typedef struct { uint32_t EXTI_Line; //中断线 EXTIMode_TypeDef EXTI_Mode; //中断模式 EXTITrigger_TypeDef EXTI_Trigger; //中断触发方式 FunctionalState EXTI_LineCmd; //中断功能使能 }EXTI_InitTypeDef;
EXTI_Line
/** @defgroup EXTI_Lines * @{ */ #define EXTI_Line0 ((uint32_t)0x00001) /*!< External interrupt line 0 */ #define EXTI_Line1 ((uint32_t)0x00002) /*!< External interrupt line 1 */ #define EXTI_Line2 ((uint32_t)0x00004) /*!< External interrupt line 2 */ #define EXTI_Line3 ((uint32_t)0x00008) /*!< External interrupt line 3 */ #define EXTI_Line4 ((uint32_t)0x00010) /*!< External interrupt line 4 */ #define EXTI_Line5 ((uint32_t)0x00020) /*!< External interrupt line 5 */ #define EXTI_Line6 ((uint32_t)0x00040) /*!< External interrupt line 6 */ #define EXTI_Line7 ((uint32_t)0x00080) /*!< External interrupt line 7 */ #define EXTI_Line8 ((uint32_t)0x00100) /*!< External interrupt line 8 */ #define EXTI_Line9 ((uint32_t)0x00200) /*!< External interrupt line 9 */ #define EXTI_Line10 ((uint32_t)0x00400) /*!< External interrupt line 10 */ #define EXTI_Line11 ((uint32_t)0x00800) /*!< External interrupt line 11 */ #define EXTI_Line12 ((uint32_t)0x01000) /*!< External interrupt line 12 */ #define EXTI_Line13 ((uint32_t)0x02000) /*!< External interrupt line 13 */ #define EXTI_Line14 ((uint32_t)0x04000) /*!< External interrupt line 14 */ #define EXTI_Line15 ((uint32_t)0x08000) /*!< External interrupt line 15 */ #define EXTI_Line16 ((uint32_t)0x10000) /*!< External interrupt line 16 Connected to the PVD Output */ #define EXTI_Line17 ((uint32_t)0x20000) /*!< External interrupt line 17 Connected to the RTC Alarm event */ #define EXTI_Line18 ((uint32_t)0x40000) /*!< External interrupt line 18 Connected to the USB Device/USB OTG FS Wakeup from suspend event */ #define EXTI_Line19 ((uint32_t)0x80000) /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */
成员EXTI_Mode可赋的值:(中断模式)
typedef enum { EXTI_Mode_Interrupt = 0x00,//中断 EXTI_Mode_Event = 0x04 //事件 }EXTIMode_TypeDef;
成员EXTI_Trigger可赋的值(中断)
typedef enum { EXTI_Trigger_Rising = 0x08, //上升沿触发 EXTI_Trigger_Falling = 0x0C, //下降沿触发 EXTI_Trigger_Rising_Falling = 0x10 //双边延触发 }EXTITrigger_TypeDef;
成员EXTI_LineCmd可赋的值: ENABLE or DISABLE
2.3 EXTI_GetITStatus
/** * @brief Checks whether the specified EXTI line is asserted or not. * @param EXTI_Line: specifies the EXTI line to check. * This parameter can be: * @arg EXTI_Linex: External interrupt line x where x(0..19) * @retval The new state of EXTI_Line (SET or RESET). */ ITStatus EXTI_GetITStatus(uint32_t EXTI_Line) 功能: 检查指定的 EXTI 线路触发请求发生与否 参数: EXTI_Line:待检查 EXTI 线路的挂起位 返回值: EXTI_Line 的新状态(SET 或者 RESET)
2.4 EXTI_ClearITPendingBit
/** * @brief Clears the EXTI's line pending bits. * @param EXTI_Line: specifies the EXTI lines to clear. * This parameter can be any combination of EXTI_Linex where x can be (0..19). * @retval None */ void EXTI_ClearITPendingBit(uint32_t EXTI_Line) 功能: 清除 EXTI 线路挂起位 参数: EXTI_Line:待清除 EXTI 线路的挂起位 返回值: 无
2.5 中断回调函数
EXPORT EXTI0_IRQHandler EXPORT EXTI1_IRQHandler EXPORT EXTI2_IRQHandler EXPORT EXTI3_IRQHandler EXPORT EXTI4_IRQHandler EXPORT EXTI9_5_IRQHandler EXPORT EXTI15_10_IRQHandler
常用的中断服务函数格式为:
void EXTI3_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生 { //中断逻辑… EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE 上的中断标志位 } }
03. 对射式红外传感器计次接线图
04. 对射式红外传感器计次程序示例
CountSensor.h
#ifndef __COUNT_SENSOR_H__ #define __COUNT_SENSOR_H__ #include "stm32f10x.h" void count_sensor_init(void); uint16_t CountSensor_Get(void); #endif /*__COUNT_SENSOR_H__*/
CountSensor.c
#include "CountSensor.h" uint16_t CountSensor_Count = 0; //初始化 void count_sensor_init(void) { GPIO_InitTypeDef GPIO_InitStruct; EXTI_InitTypeDef EXTI_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; //使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //初始化GPIO GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU ; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStruct); //初始化外部中断线 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14); //初始化外部中断 EXTI_InitStruct.EXTI_Line = EXTI_Line14; EXTI_InitStruct.EXTI_LineCmd = ENABLE ; EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_Init(&EXTI_InitStruct); //初始化NVIC NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE ; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStruct); } uint16_t CountSensor_Get(void) { return CountSensor_Count; } void EXTI15_10_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line14) == SET) { /*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/ if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0) { CountSensor_Count ++; } EXTI_ClearITPendingBit(EXTI_Line14); } }
main.c
#include "stm32f10x.h" #include "delay.h" #include "oled.h" #include "CountSensor.h" int main(void) { //初始化 OLED_Init(); OLED_ShowString(1, 1, "Count:"); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); count_sensor_init(); while(1) { OLED_ShowNum(1 , 7, CountSensor_Get(), 5); } return 0; }
05. 旋转编码器计次接线图
【其它】
06. 旋转编码器计次程序示例
encode.h
#ifndef __ENCODE_H__ #define __ENCODE_H__ #include "stm32f10x.h" void Encoder_Init(void); int16_t Encoder_Get(void); #endif /*__ENCODE_H__*/
encode.c
#include "encode.h" int16_t Encoder_Count; void Encoder_Init(void) { NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0); GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_Init(&NVIC_InitStructure); } int16_t Encoder_Get(void) { int16_t Temp; Temp = Encoder_Count; Encoder_Count = 0; return Temp; } void EXTI0_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line0) == SET) { /*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/ if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0) { if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) { Encoder_Count --; } } EXTI_ClearITPendingBit(EXTI_Line0); } } void EXTI1_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line1) == SET) { /*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/ if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) { if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0) { Encoder_Count ++; } } EXTI_ClearITPendingBit(EXTI_Line1); } }
main.c
#include "stm32f10x.h" #include "delay.h" #include "oled.h" #include "CountSensor.h" #include "encode.h" int16_t Num; int main(void) { //初始化 OLED_Init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); Encoder_Init(); OLED_ShowString(1, 1, "Num:"); while (1) { Num += Encoder_Get(); OLED_ShowSignedNum(1, 5, Num, 5); } return 0; }