嵌入式外设集 -- 旋钮编码器(360度)

目录

一、介绍

关注微信公众号--星之援工作室 发送关键字(360旋钮编码器)

使用的注意事项

技术参数

二、关键代码讲解

rotary.h

rotary.c

main.c 

三、参考

完整代码请关注卫星公众号进行获取和咨询


一、介绍

旋钮电位器是一种电子元器件,通常用于控制电路中的电阻值。它包括一个旋转式旋钮和一个电阻体。通过旋转旋钮,可以改变电阻体的阻值,从而改变电路中的电流、电压或功率等参数。旋钮电位器常用于音量控制、亮度控制、温度控制等应用领域。一般来说,旋钮电位器的阻值和功率是其最主要的性能指标。常见的旋钮电位器类型包括单轨、双轨、三轨等,同时还有分别用于直流和交流电路的电位器。

嵌入式外设集 -- 旋钮编码器(360度)_第1张图片

关注微信公众号--星之援工作室 发送关键字(360旋钮编码器)

➡️➡️

嵌入式外设集 -- 旋钮编码器(360度)_第2张图片

使用的注意事项

1. 本文章使用的编码器位360度,主要使用的外部中断已经io口的高低电平的判断进行电位器左右旋转的状态进行实时刷新和获取。

2. 主要哦本文章使用的电位器额定电压为5V,需要主要接入的电源部分。

技术参数

额定电压: DC 5V;

各相导线: 0.5mA(Max 5mA;Min 0.5mA)

公共导线:1mA(Max 10mA;Min 0.5mA)

使用温度范围::-30℃ to+80℃

二、关键代码讲解

 1.我们首先再rotary.h文件里进行io口的定义,并且使用一个结构体来储存我们的旋转变量,示例代码如下

rotary.h

#ifndef __EXTI_H
#define	__EXTI_H


#include "stm32f10x.h"
#include "sys.h"

//引脚定义
#define KEY1_INT_GPIO_PORT         GPIOB
#define KEY1_INT_GPIO_CLK          (RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO)
#define KEY1_INT_GPIO_PIN          GPIO_Pin_8
#define KEY1_INT_EXTI_PORTSOURCE   GPIO_PortSourceGPIOB
#define KEY1_INT_EXTI_PINSOURCE    GPIO_PinSource8
#define KEY1_INT_EXTI_LINE         EXTI_Line8
#define KEY1_INT_EXTI_IRQ          EXTI9_5_IRQn

#define KEY1_IRQHandler            EXTI9_5_IRQHandler


#define KEY2_INT_GPIO_PORT         GPIOB
#define KEY2_INT_GPIO_CLK          (RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO)
#define KEY2_INT_GPIO_PIN          GPIO_Pin_9
#define KEY2_INT_EXTI_PORTSOURCE   GPIO_PortSourceGPIOB
#define KEY2_INT_EXTI_PINSOURCE    GPIO_PinSource9
#define KEY2_INT_EXTI_LINE         EXTI_Line9
#define KEY2_INT_EXTI_IRQ          EXTI9_5_IRQn

#define KEY2_IRQHandler            EXTI9_5_IRQHandler

typedef struct
{
    u8 Left_State;  // 左旋转的标志位
    u8 Right_State; // 右旋转的标志位
		u16 Turn_Num; 	// 旋转度数

} Left_Right_Typedef; // 电导模式定义

extern Left_Right_Typedef turn_init;    // 旋转模式

#define Turn_Left  PBin(8) 
#define Turn_Right PBin(9) 


void EXTI_Key_Config(void);
//监测是否停止旋转
void Check_Turn(void);

#endif /* __EXTI_H */

2.通过io口的外部中端来监测那一边先触发,并将触发的状态进行更新,之后再通过轮询的方式监测io口高低电平的触发情况,以此来推断出我们的电位器是否处于旋转中,本代码都有详细的注释,示例代码如下

嵌入式外设集 -- 旋钮编码器(360度)_第3张图片

rotary.c

#include "rotary.h"
Left_Right_Typedef turn_init;    // 旋转模式
 /**
  * @brief  配置嵌套向量中断控制器NVIC
  * @param  无
  * @retval 无
  */
static void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 配置NVIC为优先级组1 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 配置中断源:按键1 */
  NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
  /* 配置抢占优先级 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /* 配置子优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /* 使能中断通道 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  /* 配置中断源:按键2,其他使用上面相关配置 */  
  NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;
  NVIC_Init(&NVIC_InitStructure);
}

 /**
  * @brief  配置 IO为EXTI中断口,并设置中断优先级
  * @param  无
  * @retval 无
  */
void EXTI_Key_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; 
	EXTI_InitTypeDef EXTI_InitStructure;

	/*开启按键GPIO口的时钟*/
	RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);
  RCC_APB2PeriphClockCmd(KEY2_INT_GPIO_CLK,ENABLE);
												
	/* 配置 NVIC 中断*/
	NVIC_Configuration();
	
/*--------------------------KEY1配置-----------------------------*/
	/* 选择按键用到的GPIO */	
  GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
  /* 配置为浮空输入 */	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);

	/* 选择EXTI的信号源 */
  GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE); 
  EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
	
	/* EXTI为中断模式 */
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	/* 上升沿中断 */
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  /* 使能中断 */	
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
	
  /*--------------------------KEY2配置-----------------------------*/
	/* 选择按键用到的GPIO */	
  GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;
  /* 配置为浮空输入 */	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);

	/* 选择EXTI的信号源 */
  GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, KEY2_INT_EXTI_PINSOURCE); 
  EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;
	
	/* EXTI为中断模式 */
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	/* 下降沿中断 */
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  /* 使能中断 */	
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
}
//监测是否停止旋转
void Check_Turn(void)
{
	//左转
	if(Turn_Left==0&&turn_init.Left_State>0){
		if(turn_init.Turn_Num<=360){
			turn_init.Turn_Num++;
		}
		//重置触发
		turn_init.Left_State=5;
	}
	//判断是否停止旋转
	else if(Turn_Left==1&&turn_init.Left_State>0)
	{
		turn_init.Left_State--;
	}
	// 右转
	if(Turn_Right==0&&turn_init.Right_State>0){
		if(turn_init.Turn_Num>0){
			turn_init.Turn_Num--;
		}
		//重置触发
		turn_init.Right_State=5;
	}
	//判断是否停止旋转
	else if(Turn_Right==1&&turn_init.Right_State>0)
	{
		turn_init.Right_State--;
	}
}
//外部中断触发
void KEY1_IRQHandler(void)
{
  //确保是否产生了EXTI Line中断
	if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) 
	{
		// 排除已触发状态
		if(turn_init.Right_State==0){
			// 左转	
			turn_init.Left_State=5;

		}

	
    //清除中断标志位
		EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);     
	}  
	
	 //确保是否产生了EXTI Line中断
	if(EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) 
	{
		// 排除已触发状态
		if(turn_init.Left_State==0){
			// 右转	
			turn_init.Right_State=5;

		}

    //清除中断标志位
		EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);     
	}  
}

/*********************************************END OF FILE**********************/

3.最后我们直接在主函数进行轮询判断即可,也可以放到我们的定时器中执行,在这个了我给了一个延时,让他大约每30ms执行一次监测,节约硬件的cup

嵌入式外设集 -- 旋钮编码器(360度)_第4张图片

main.c 

/*--------------------------------------------------------*
 *                                       								  *
 *   星之援网络科技工作室学习资料v1.0    									*
 *		 时间:2022.7.14                    								*
 *		 程序介绍:外部中断               								  *
 *		 实现效果:按键改变板载LED的状态   								  *
 *     需求请联系:13648103287                            *
 *--------------------------------------------------------*
*/

#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "rotary.h" 
#include "usart.h"
int main(void)
{
	u16 i;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	delay_init();
	// 串口初始化
	uart_init(115200);

	// LED 端口初始化 
	LED_GPIO_Config();
	/* 初始化EXTI中断,按下按键会触发中断,
	*  KEY1_IRQHandler和KEY2_IRQHandler,处理中断。
	*/
	EXTI_Key_Config(); 

	printf("init ok\n");
  while(1)
	{
		i++;
		if(i%3==0){
			//监测旋钮
			Check_Turn();
		}
		if(i%25==0){
			//监测旋钮
			i=0;
			printf("旋转数据: %d\n",turn_init.Turn_Num);
		}
		delay_ms(10);
	}
}

三、参考

STM32读取旋钮编码器icon-default.png?t=N7T8https://blog.csdn.net/qq_36958104/article/details/103577486?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170202402116800182182895%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=170202402116800182182895&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-6-103577486-null-null.nonecase&utm_term=%E6%97%8B%E9%92%AE%E7%BC%96%E7%A0%81%E5%99%A8&spm=1018.2226.3001.4450
STM32 编码器驱动/旋转编码器旋钮encodericon-default.png?t=N7T8https://blog.csdn.net/denghuajing/article/details/122683502?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170202402116800182119214%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170202402116800182119214&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~top_click~default-1-122683502-null-null.nonecase&utm_term=%E6%97%8B%E9%92%AE%E7%BC%96%E7%A0%81%E5%99%A8&spm=1018.2226.3001.4450


完整代码请关注卫星公众号进行获取和咨询


你可能感兴趣的:(嵌入式外设集,单片机,嵌入式硬件,stm32,嵌入式外设,c语言,编码器)