STM32 EC11 旋转编码器

这篇具有很好参考价值的文章主要介绍了STM32 EC11 旋转编码器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

**先给大家看看我选用的EC11元器件**

代码在最后,复制可直接食用
stm32 ec11,stm32,单片机,嵌入式硬件

stm32 ec11,stm32,单片机,嵌入式硬件
以及我的电路图

stm32 ec11,stm32,单片机,嵌入式硬件

在研究EC11的时序之前首先要了解一点,EC11按旋转的输出动作可以分为两种。一种是转两格,A、B对C端输出一个完整脉冲(转一格就只是由低电平->高电平或由高电平->低电平);另一种就是转一格,A、B对C端输出一个完整脉冲。

一定位一脉冲的EC11按测试电路图的接法,在静止的时候AB两线输出都是高电平。转动一格,AB两线各自输出一个低电平脉冲,然后又回到高电平状态。对应于EC11内部AB两个触点开关的动作为断开–>闭合–>断开。

两定位一脉冲的EC11稍微复杂一些,转动一格只会输出半个脉冲。静止时,AB触点开关可以是断开的也可以是闭合的。若初始状态时AB都是高电平,转动一格就输出从高电平到低电平的下降沿,随后一直输出低电平。对应于EC11内部AB两个触电开关的动作为断开–>闭合。
若初始状态时AB都是低电平,转动一格就输出从低电平到高电平的上升沿,随后一直输出低电平。对应于EC11内部AB两个触点开关的动作为闭合–>断开。
由于两脉冲一定位的EC11会有两种初始状态,写驱动程序就需要考虑多一些情况。再者,这类EC11在转动到内部AB触点一直闭合的时候,就相当于把上拉电阻的另一端接地,无形中加大了系统的功耗(若外接10K上拉电阻到5V电源就是500uA的电流),这对于低功耗应用来说是非常不利的。
因此对于无特殊要求的人机输入应用来说,我都推荐使用一定位一脉冲的EC11。
当然了,有一些质量比较差的EC11会有一些额外的问题要考虑,例如开关的抖动问题,例如转动定位不清晰,静止时AB两个触点都要闭合或者都要断开才对,但是定位点不清晰,转动的角度不到位导致一个触点已经闭合(断开)了,另一个触点却还保持在断开(闭合)。对于这些问题我们在后面再做考虑。

时序图

要写驱动程序,得先了解EC11的工作过程。使用逻辑分析仪(LA)抓取时序可以很方便的从单片机的角度了解EC11的工作过程并依此来编写驱动程序。
  EC11的编码器部分有3个引脚,A,B,和C。通常可以把C端接GND,A,B端接到输入上拉模式的IO口。可以取A或B任意一根线作为时钟线,另一根作为信号输出线。我个人习惯把A线作为时钟线,B线作为信号线。
  本文中出现的逻辑分析仪抓取的时序图中均是最上方通道为EC11的A线,视为时钟;下方一个通道为EC11的B线,视为数据输出。

stm32 ec11,stm32,单片机,嵌入式硬件

就不啰嗦太多,我就直接上代码,我使用STM32F103系列

#include "ec11.h"
#include "sys.h"

void TIM4_Int_Init(u16 arr,u16 psc)
{	
	NVIC_InitTypeDef NVIC_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//TIM2时钟使能    
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM7中断,允许更新中断

	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		//子优先级2
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
	
	TIM_Cmd(TIM4,ENABLE);//开启定时器4
}

//定时器4中断服务程序		    
void TIM4_IRQHandler(void)
{ 	
	if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)//是更新中断
	{	 		
		Encoder_EC11_Analyze(Encoder_EC11_Scan());
		
		TIM_ClearITPendingBit(TIM4, TIM_IT_Update);  //清除TIM4更新中断标志    
	}	    
}

//*******************************************************************/
//功能:初始化EC11旋转编码器相关参数
//形参:EC11旋转编码器的类型-->>  unsigned char Set_EC11_TYPE  <<--  :0----一定位对应一脉冲;1(或非0)----两定位对应一脉冲。
//返回:无
//详解:对EC11旋转编码器的连接IO口做IO口模式设置。以及将相关的变量进行初始化
//*******************************************************************/
void EC11_Init(unsigned char Set_EC11_TYPE)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;        //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_SetBits(GPIOB,GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9);	

	//EC11类型选择:0-一定位一脉冲;1-两定位一脉冲
	if (Set_EC11_TYPE == 0)
	{
		EC11_Type = 0;
	}
	else
	{
		EC11_Type = 1;
	}
	//避免上电时EC11旋钮位置不确定导致一次动作误判
	EC11_A_Last = EC11_A_Now;
	EC11_B_Last = EC11_B_Now;

	//--------清除按键计数器和标志位--------//
	EC11_KEY_COUNT = 0;                     //EC11按键动作计数器
	EC11_KEY_DoubleClick_Count = 0;         //EC11按键双击动作计数器
	FLAG_EC11_KEY_ShotClick = 0;            //EC11按键短按动作标志
	FLAG_EC11_KEY_LongClick = 0;            //EC11按键长按动作标志
	FLAG_EC11_KEY_DoubleClick = 0;          //EC11按键双击动作标志
		
	TIM4_Int_Init(9,7199);	//初始化定时器4 1ms中断 
}



//*******************************************************************/
//功能:对EC11旋转编码器的动作进行分析,并作出相应的动作处理代码
//形参:无
//返回:char AnalyzeResult = 0;目前无用。若在该函数里做了动作处理,则函数的返回值无需理会
//详解:对EC11旋转编码器的动作进行模式分析,是单击还是双击还是长按松手还是一直按下。形参从 [ char Encoder_EC11_Scan(unsigned char Set_EC11_TYPE) ] 函数传入。在本函数内修改需要的动作处理代码
//*******************************************************************/
char Encoder_EC11_Analyze(char EC11_Value)
{
	char AnalyzeResult = 0;
  static unsigned int TMP_Value = 0;  //中间计数值,用于连续长按按键的动作延时间隔
  //>>>>>>>>>>>>>>>>编码器正转处理程序<<<<<<<<<<<<<<<<//
  if(EC11_Value == 1) //正转
  {
      //--------编码器正转动作代码--------//
     printf("正转!!")
  }
  //>>>>>>>>>>>>>>>>编码器反转处理程序<<<<<<<<<<<<<<<<//
  if(EC11_Value == 8)    //反转
  {
      //--------编码器反转动作代码--------//
     printf("反转!!");
  }

	//>>>>>>>>>>>>>>>>编码器按键按下并正转处理程序<<<<<<<<<<<<<<<<//
	if(EC11_Value == 3)
	{
		//--------编码器按键按下并正转动作代码--------//
			
	}

	//>>>>>>>>>>>>>>>>编码器按键按下并反转处理程序<<<<<<<<<<<<<<<<//
	if(EC11_Value == 9)
	{
		//--------编码器按键按下并反转动作代码--------//
//		printf("按下反转!!");
	}
	//>>>>>>>>>>>>>>>>编码器按键按下处理程序<<<<<<<<<<<<<<<<//
	if(EC11_Value == 2)     //====检测到按键按下====//
	{
		if(EC11_KEY_COUNT<10000)    //打开按键按下时间定时器
			 EC11_KEY_COUNT++;
		if(EC11_KEY_COUNT == KEY_COUNT_DESHAKING)   //按下按键时间到达消抖时间时
		{                                           //置位短按按键标志
			FLAG_EC11_KEY_ShotClick = 1;	
		}
		if((EC11_KEY_DoubleClick_Count > 0)&&(EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME))   //松开按键后,又在定时器在双击时间内按下按键
		{                                                                                               //置位双击按键标志
			FLAG_EC11_KEY_DoubleClick = 1;
		}

		if(EC11_KEY_COUNT == KEY_COUNT_LONGTIME)    //按下按键时间到达长按时间
		{                                           //置位长按按键标志并复位短按按键标志
			FLAG_EC11_KEY_LongClick = 1;
			FLAG_EC11_KEY_ShotClick = 0;
		}
	}
	else                    //====检测到按键松开====//     
	{
		if(EC11_KEY_COUNT < KEY_COUNT_DESHAKING)    //没到消抖时长就松开按键,复位所有定时器和按键标志
		{	
			EC11_KEY_COUNT = 0;
			FLAG_EC11_KEY_ShotClick = 0;
			FLAG_EC11_KEY_LongClick = 0;
			FLAG_EC11_KEY_DoubleClick = 0;
			EC11_KEY_DoubleClick_Count = 0;
		}
    else
    {     
			if(FLAG_EC11_KEY_ShotClick == 1)        //短按按键定时有效期间
      {
				if((FLAG_EC11_KEY_DoubleClick == 0)&&(EC11_KEY_DoubleClick_Count >= 0)) 
						EC11_KEY_DoubleClick_Count++;
				if((FLAG_EC11_KEY_DoubleClick == 1)&&(EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME))   //如果在规定双击时间内再次按下按键
        {                                                                                               //认为按键是双击动作
					FLAG_EC11_KEY_DoubleClick = 2;
        }   
        if((FLAG_EC11_KEY_DoubleClick == 0)&&(EC11_KEY_DoubleClick_Count > KEY_COUNT_DUALCLICKTIME))    //如果没有在规定双击时间内再次按下按键
            FLAG_EC11_KEY_ShotClick = 0;                                                                //认为按键是单击动作
       }
       if(FLAG_EC11_KEY_LongClick == 1)        //检测到长按按键松开
			 {
        FLAG_EC11_KEY_LongClick = 0;
			 }
     }
	}
    //>>>>>>>>>>>>>>>>编码器按键分析处理程序<<<<<<<<<<<<<<<<//
	
	if(EC11_KEY_COUNT > KEY_COUNT_DESHAKING)    //短按按键延时到了时间
	{
		//短按按键动作结束代码
		if((FLAG_EC11_KEY_ShotClick == 0)&&(EC11_KEY_DoubleClick_Count > KEY_COUNT_DUALCLICKTIME)&&(EC11_KEY_COUNT < KEY_COUNT_LONGTIME))   //短按按键动作结束代码
    {
      //--------短按按键动作结束代码--------//
			EC11_NUM_SW++;
			if(EC11_NUM_SW >= 4)
				 EC11_NUM_SW = 1;
			AnalyzeResult = 1;
			
			//--------清除标志位--------//
			EC11_KEY_COUNT = 0;
			EC11_KEY_DoubleClick_Count = 0;
			FLAG_EC11_KEY_DoubleClick = 0;
		}
    //双击按键动作结束代码
		if((FLAG_EC11_KEY_DoubleClick == 2)&&(EC11_KEY_DoubleClick_Count > 0)&&(EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME)) //双击按键动作结束代码
    {
			//--------双击按键动作结束代码--------//
			if(EC11_NUM_SW == 5)
				 EC11_NUM_SW = 0;
			if(EC11_NUM_SW == 4)
				 EC11_NUM_SW = 5;
			if(EC11_NUM_SW <4)
			{
				EC11_NUM_SW = 4;
			}
			AnalyzeResult = 2;
			//--------清除标志位--------//
			EC11_KEY_COUNT = 0;
			EC11_KEY_DoubleClick_Count = 0;
			FLAG_EC11_KEY_ShotClick = 0;
			FLAG_EC11_KEY_DoubleClick = 0;    
		}

		//连续长按按键按下代码
		if((FLAG_EC11_KEY_LongClick == 1)&&(EC11_KEY_COUNT >= KEY_COUNT_LONGTIME))  //连续长按按键按下代码
    {
			TMP_Value ++;
			if(TMP_Value % KEY_LONG_REPEAT_TIME == 0)
			{
				TMP_Value = 0;
				//-------连续长按按键按下代码--------//
				AnalyzeResult = 4;
			}
		}

		//长按按键动作结束代码
		if((FLAG_EC11_KEY_LongClick == 0)&&(EC11_KEY_COUNT >= KEY_COUNT_LONGTIME))  //长按按键动作结束代码
		{                                                                           
			//--------长按按键按下动作结束代码--------//
			EC11_NUM_SW = 0;
			AnalyzeResult = 3;
			//--------清除标志位--------//
			EC11_KEY_COUNT = 0;
		}
	}
	return AnalyzeResult;
}

//*******************************************************************/
//功能:扫描EC11旋转编码器的动作并将参数返回给动作分析函数使用
//形参:EC11旋转编码器的类型-->>  unsigned char Set_EC11_TYPE  <<--  :0----一定位对应一脉冲;1(或非0)----两定位对应一脉冲
//返回:EC11旋转编码器的扫描结果-->>  char ScanResult  -->>  0:无动作;1:正转; -1:反转;2:只按下按键;3:按着按键正转;-3:按着按键反转
//详解:只扫描EC11旋转编码器有没有动作,不关心是第几次按下按键或长按或双击。返回值直接作为形参传给 [ void Encoder_EC11_Analyze(char EC11_Value); ] 函数使用
//*******************************************************************/
char Encoder_EC11_Scan()
{
		//以下储存A、B上一次值的变量声明为静态全局变量,方便对EC11对应的IO口做初始化
		//  static char EC11_A_Last = 0;
		//  static char EC11_B_Last = 0;
	char ScanResult = 0;    //返回编码器扫描结果,用于分析编码器的动作
                          //返回值的取值:   0:无动作;      1:正转;           8:反转;  
                          //                 2:只按下按键;  3:按着按键正转;   9:按着按键反转
                          //======================================================//
	if(EC11_Type == 0)      //================一定位对应一脉冲的EC11================//
	{                     	//======================================================//
		if(EC11_A_Now != EC11_A_Last)   //以A为时钟,B为数据。正转时AB反相,反转时AB同相
		{
			if(EC11_A_Now == 0)
			{
				if(EC11_B_Now ==1)      //只需要采集A的上升沿或下降沿的任意一个状态,若A下降沿时B为1,正转                    
					 ScanResult = 1;     //正转
				else                    //反转
					 ScanResult = 8;
			}
			EC11_A_Last = EC11_A_Now;   //更新编码器上一个状态暂存变量
			EC11_B_Last = EC11_B_Now;   //更新编码器上一个状态暂存变量
		}
	}   
                          //======================================================//
	else                    //================两定位对应一脉冲的EC11================//
	{                       //======================================================//
		if(EC11_A_Now !=EC11_A_Last)        //当A发生跳变时采集B当前的状态,并将B与上一次的状态进行对比。
		{                                   //若A 0->1 时,B 1->0 正转;若A 1->0 时,B 0->1 正转;
                                        //若A 0->1 时,B 0->1 反转;若A 1->0 时,B 1->0 反转
			if(EC11_A_Now == 1)     					//EC11_A和上一次状态相比,为上升沿
			{
				if((EC11_B_Last == 1)&&(EC11_B_Now == 0))   //EC11_B和上一次状态相比,为下降沿
						ScanResult = 1;                         //正转
        if((EC11_B_Last == 0)&&(EC11_B_Now == 1))   //EC11_B和上一次状态相比,为上升沿               
            ScanResult = 8;                        //反转
                //>>>>>>>>>>>>>>>>下面为正转一次再反转或反转一次再正转处理<<<<<<<<<<<<<<<<//
        if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 0))  //A上升沿时,采集的B不变且为0
            ScanResult = 1;                                 //正转
        if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 1))  //A上升沿时,采集的B不变且为1
            ScanResult = 8;                                 //反转
			}
			else                    //EC11_A和上一次状态相比,为下降沿
			{
				if((EC11_B_Last == 1)&&(EC11_B_Now == 0))   //EC11_B和上一次状态相比,为下降沿
						ScanResult = 8;                        //反转
				if((EC11_B_Last == 0)&&(EC11_B_Now == 1))   //EC11_B和上一次状态相比,为上升沿
						ScanResult = 1;                         //正转
				//>>>>>>>>>>>>>>>>下面为正转一次再反转或反转一次再正转处理<<<<<<<<<<<<<<<<//
				if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 0))  //A上升沿时,采集的B不变且为0
						ScanResult = 8;                                //反转
				if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 1))  //A上升沿时,采集的B不变且为1   
						ScanResult = 1;                                 //正转
			}               
				EC11_A_Last = EC11_A_Now;   //更新编码器上一个状态暂存变量
				EC11_B_Last = EC11_B_Now;   //更新编码器上一个状态暂存变量
		}
	}                                                                       
	if(EC11_Key == 0)   //如果EC11的按键按下,并且没有EC11没有转动,
	{
//		if(ScanResult == 0)         //按下按键时未转动
			 ScanResult = 2;         //返回值为2
//		else
//		{
//			if(ScanResult == 1)     //按下按键时候正转
//				 ScanResult = 3;     //返回值为3
//			if(ScanResult == 8)    //按下按键时候反转
//				 ScanResult = 9;    //返回值为-3
//		}
	}
    return ScanResult;      //返回值的取值:   0:无动作;      1:正转;           8:反转;
}                           //             		 2:只按下按键;  3:按着按键正转;   9:按着按键反转


#ifndef __ec11_H
#define __ec11_H


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

//----------------IO口定义----------------//
#define EC11_A_Now           PBin(9)                             //EC11的A引脚,视为时钟线
#define EC11_B_Now           PBin(8)                           	 //EC11的B引脚,视为信号线
#define	EC11_Key             PBin(7)                           	 //EC11的按键


//----------------编码器动作代码相关定义----------------//

static unsigned char EC11_NUM_SW = 0;

//----------------编码器参数微调宏定义----------------//
#define EC11_SCAN_PERIOD_MS            1                            //EC11编码器扫描周期
#define KEY_COUNT_DESHAKING         ( 10/EC11_SCAN_PERIOD_MS)       //按键消抖时间
#define KEY_COUNT_LONGTIME          (150/EC11_SCAN_PERIOD_MS)       //长按按键判断时间
#define KEY_COUNT_DUALCLICKTIME     (150/EC11_SCAN_PERIOD_MS)       //双击按键判断时间
#define KEY_LONG_REPEAT_TIME        (200/EC11_SCAN_PERIOD_MS)       //长按按键的回报率的倒数,即一直长按按键时响应的时间间隔

//----------------局部文件内变量列表----------------//
static  char    EC11_A_Last = 0;                        //EC11的A引脚上一次的状态
static  char    EC11_B_Last = 0;                        //EC11的B引脚上一次的状态
static  char    EC11_Type = 1;                          //定义变量暂存EC11的类型---->>>>----  0:一定位对应一脉冲;  1:两定位对应一脉冲
//所谓一定位对应一脉冲,是指EC11旋转编码器每转动一格,A和B都会输出一个完整的方波。
//而  两定位对应一脉冲,是指EC11旋转编码器每转动两格,A和B才会输出一个完整的方波,只转动一格只输出A和B的上升沿或下降沿

static   int    EC11_KEY_COUNT = 0;                     //EC11按键动作计数器
static   int    EC11_KEY_DoubleClick_Count = 0;         //EC11按键双击动作计数器
static  char    FLAG_EC11_KEY_ShotClick = 0;            //EC11按键短按动作标志
static  char    FLAG_EC11_KEY_LongClick = 0;            //EC11按键长按动作标志
static  char    FLAG_EC11_KEY_DoubleClick = 0;          //EC11按键双击动作标志

//----------------函数快速调用(复制粘贴)列表----------------//
//
/*******************************************************************
void Encoder_EC11_Init(unsigned char Set_EC11_TYPE);        //初始化EC11旋转编码器IO口和类型以及变量初始化
char Encoder_EC11_Scan();                                   //扫描旋转编码器的动作
void Encoder_EC11_Analyze(char EC11_Value);                 //分析EC11旋转编码器的动作以及动作处理代码
******************************************************************/
//-------->>>>>>>>--------注意事项:EC11旋转编码器的扫描时间间隔控制在1~4ms之间,否则5ms及以上的扫描时间在快速旋转时可能会误判旋转方向--------<<<<<<<<--------//
//-------->>>>>>>>--------注意事项:EC11旋转编码器的扫描时间间隔控制在1~4ms之间,否则5ms及以上的扫描时间在快速旋转时可能会误判旋转方向--------<<<<<<<<--------//
//-------->>>>>>>>--------注意事项:EC11旋转编码器的扫描时间间隔控制在1~4ms之间,否则5ms及以上的扫描时间在快速旋转时可能会误判旋转方向--------<<<<<<<<--------//

//----------------函数声明列表----------------//
//
//*******************************************************************/
//功能:初始化EC11旋转编码器相关参数
//形参:EC11旋转编码器的类型-->>  unsigned char Set_EC11_TYPE  <<--  :0----一定位对应一脉冲;1(或非0)----两定位对应一脉冲。
//返回:无
//详解:对EC11旋转编码器的连接IO口做IO口模式设置。以及将相关的变量进行初始化
//*******************************************************************/
void EC11_Init(unsigned char Set_EC11_TYPE);

//*******************************************************************/
//功能:扫描EC11旋转编码器的动作并将参数返回给动作分析函数使用
//形参:EC11旋转编码器的类型-->>  unsigned char Set_EC11_TYPE  <<--  :0----一定位对应一脉冲;1(或非0)----两定位对应一脉冲
//返回:EC11旋转编码器的扫描结果-->>  char ScanResult  -->>  0:无动作;1:正转; -1:反转;2:只按下按键;3:按着按键正转;-3:按着按键反转
//详解:只扫描EC11旋转编码器有没有动作,不关心是第几次按下按键或长按或双击。返回值直接作为形参传给 [ void Encoder_EC11_Analyze(char EC11_Value); ] 函数使用
//*******************************************************************/

char Encoder_EC11_Scan(void);

//*******************************************************************/
//功能:对EC11旋转编码器的动作进行分析,并作出相应的动作处理代码
//形参:无
//返回:char AnalyzeResult = 0;目前无用。若在该函数里做了动作处理,则函数的返回值无需理会
//详解:对EC11旋转编码器的动作进行模式分析,是单击还是双击还是长按松手还是一直按下。形参从 [ char Encoder_EC11_Scan(unsigned char Set_EC11_TYPE) ] 函数传入。在本函数内修改需要的动作处理代码
//*******************************************************************/
char Encoder_EC11_Analyze(char EC11_Value);

#endif

这个程序我只做了正转,反转和按下,有需要自行修改,我这里利用的是定时器1毫秒扫描,所以刷新函数Encoder_EC11_Analyze(Encoder_EC11_Scan());我写在中断里面,初始化函数 EC11_Init(1);在这里需要注意一定位对应一脉冲;1(或非0)----两定位对应一脉冲,前面有说过了,放心食用

转自:https://www.jianshu.com/p/41fa67ecb248文章来源地址https://www.toymoban.com/news/detail-781068.html

到了这里,关于STM32 EC11 旋转编码器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32单片机(五)第二节:EXTI外部中断练习2(旋转编码器计次)

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月11日
    浏览(45)
  • STM32单片机(五)第二节:EXTI外部中断练习(对射式红外传感器计次和旋转编码器计次)

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月09日
    浏览(47)
  • STM32移植LVGL+旋转编码器接口对接

    写在前面:本菜鸟结合了许多大佬的文章,成功实现了基于LVGL的GUI设计,小开心~浅浅记录一下!~ 本文以单片机STM32F103VET6为核心,利用ST7796芯片驱动分辨率为480*320的LCD液晶屏模块,移植LVGL,对接显示接口,对接外部接口——旋转编码器,完成以上两步,就可以实现LVGL的显

    2024年02月10日
    浏览(46)
  • STM32-微项目07-旋转编码器计数及测速

    一、微项目实现目标: 检测旋转编码器模式下,检测旋转编码器的转动计数值及转速。并且区分转向,一侧转动增加cout,转速值为正,一侧转动减少count,转速值为负;   二、微项目硬件配置需求: 1,stm32F103C8T6核心板一块 2,0.96寸OLED显示,用于显示计数 3,旋转编码器,

    2024年02月08日
    浏览(39)
  • 关于stm32旋转编码器计次乱跳问题(消抖)

    旋转编码器A口接GPIOB0,B口接GPIOB1。设置中断类型为上升下降沿均触发。 输出是用0.96寸oled输出 A脚设置为上升下降沿均会进中断,下降上升一个变换周期,判断这个周期的A脚,B脚的始末状态,来判断正反转一次。 A口输出的波形用来中断,B口输出的波形用来判断正转还是反转

    2024年02月16日
    浏览(39)
  • 【STM32】HAL库自学记录-旋转编码器的使用

    通过本文可学会两种实现判断旋转编码器正转反转的方法,可根据自己的应用场景来选择使用哪种方法。 1、芯片:STM32F103RCT6 2、STM32CubeMx软件 3、IDE: MDK-Keil软件 4、旋转编码器模块 5、XCOM V1.4串口软件 图中C端为GND。 方向 :A相和B相相差一个相位,一般来说是90°。A相信号在

    2024年02月11日
    浏览(53)
  • 【STM32】STM32学习笔记-对射式红外传感器计次 旋转编码器计次(12)

    相关头文件: misc.h 1.1 NVIC_PriorityGroupConfig函数 1.2 NVIC_PriorityGroup类型 1.3 NVIC_Init函数 1.4 NVIC_InitTypeDef类型 NVIC_IRQChannel取值 成员NVIC_IRQChannelPreemptionPriority可赋的值:最大取值15,具体有上面设置的优先级组中规定的位数决定 成员NVIC_IRQChannelSubPriority可赋的值:最大取值15,具体有

    2024年01月15日
    浏览(45)
  • stm32f103单片机—编码器测速

    stm32f103ZET6开发板(非指定) MG513P3012V型号电机(带霍尔编码器)(非指定) 此种测速方法要求单片机的定时器具有编码器模式,对于stm32f1系列,具备编码器模式的定时器有TIM1/2/3/4/5/8, 定时器使用通道1、2来实现编码器功能 ,接线时注意把A/B相接到定时器通道1/2的引脚。 电

    2024年02月06日
    浏览(76)
  • (STM32)PWM输出控制电机旋转并且使用编码器读取脉冲数

    目录  前言 一、pwm输出让电机转  1.电机的接线说明 2.驱动的接线说明 3.pwm输出代码  pwm.c pwm.h 4.输出pwm控制电机旋转 二、配置定时器编码器模式 1.定时器编码器模式 编码器原理 编码器相关的概念 2.编码器模式——代码部分 3.获取脉冲数 三、定时读取编码器读取的脉冲数

    2024年02月03日
    浏览(58)
  • STM32第五课:对射式红外线传感器计数和旋转编码器计数

    1.1 产品特性          使用ITR9606高灵敏度槽型光耦器件,它由一个红外发光二极管和一个NPN光电三极管组成,槽宽度为5mm。传感器特设M3固定安装孔,调节方向与固定方便易用,使用宽电压LM393比较器,信号干净,波形好,驱动能力强,超过15mA。广泛用于电机转速检测,

    2024年02月20日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包