【STM32】STM32学习笔记-对射式红外传感器计次 旋转编码器计次(12)

avatar
作者
筋斗云
阅读量: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;  } 

07. 示例程序下载

07-对射式红外传感器计次.rar

08-旋转编码器计次.rar

08. 附录

参考: 【STM32】江科大STM32学习笔记汇总

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!