历史上的今天
返回首页

历史上的今天

今天是:2025年08月14日(星期四)

正在发生

2019年08月14日 | 基于stm32单片机的Grayhill编码器/开关软件设计

2019-08-14 来源:eefocus

1、初识编码器,像示波器的旋转按钮,可左旋右旋,还可以按下,我们使用的是Grayhill编码器,如下图所示:


从图中可以看出,该编码器一共有6个IO,从1-6分别为GND,GND,C,B,A,VCC,。


其中VCC和GND接3.3V和GND,A、B对应旋转时电平的跳变IO,C对应按下时电平的跳变IO。


(1) 硬件电路设计上,为了方便代码编写与理解,最好把编码器的A、B接到单片机相邻的GPIO中,即使用同一个中断处理函数,比如本设计A、B分别接到PB12和PB11。C接任一个GPIO,当成中断使用。


(2) 顺时针和逆时针旋转编码器时,慢慢旋转一个单位(手指头会有明显旋转到位的感觉),用万用表测量A、B对应的IO电平,并记录下来。旋转一圈为止。如下表是我使用的编码器,在顺、逆时针旋转一圈时所记录下的IO电平(旋4次即满一圈):


(实际使用中,旋转了24小格才满一圈,这里只记录方法,不记录确切的值,需要自己测量)


2、A、B对应的IO初始化成中断双边沿触发方式,如下所示:


void KeyA_Init(void)


{


GPIO_InitTypeDef GPIO_InitStructure;


EXTI_InitTypeDef EXTI_InitStructure;


NVIC_InitTypeDef NVIC_InitStructure;


 


/* Enable the EXTI_PB1 Clock */


RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB , ENABLE);


 


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;    //浮空输入   


GPIO_Init(GPIOB, &GPIO_InitStructure);


 


GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);   //配置PB12管脚为外部中断线路用


  


EXTI_InitStructure.EXTI_Line = EXTI_Line12;      //配置为外部中断线2


EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;        //配置为中断请求


EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;      //输入线路下降沿为中断请求


EXTI_InitStructure.EXTI_LineCmd = ENABLE;   //使能中断


   EXTI_Init(&EXTI_InitStructure);


 


NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //NVIC_Group:先占优先级2位,从优先级2位  


NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;   //配置为外部中断2中断


NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级为1


NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;   //从优先级为2


NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;      //使能中断通道


NVIC_Init(&NVIC_InitStructure);


}


void KeyB_Init(void)


{


GPIO_InitTypeDef GPIO_InitStructure;


EXTI_InitTypeDef EXTI_InitStructure;


NVIC_InitTypeDef NVIC_InitStructure;


 


/* Enable the EXTI_PB1 Clock */


RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB , ENABLE);


 


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;    //浮空输入   


GPIO_Init(GPIOB, &GPIO_InitStructure);


 


GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource11);   //配置PB11管脚为外部中断线路用


  


EXTI_InitStructure.EXTI_Line = EXTI_Line11;      //配置为外部中断线11


EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;        //配置为中断请求


EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;      //输入线路下降沿为中断请求


EXTI_InitStructure.EXTI_LineCmd = ENABLE;   //使能中断


   EXTI_Init(&EXTI_InitStructure);


 


NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //NVIC_Group:先占优先级2位,从优先级2位  


NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;   //配置为外部中断2中断


NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级为1


NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;   //从优先级为2


NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;      //使能中断通道


NVIC_Init(&NVIC_InitStructure);


}


 


 


3、根据表1设计的中断处理函数如下所示,使用TurningDir变量来标识检测到的旋转方向,TurnLeft表示逆时针(对应数值可以理解为减),TurnRight表示顺时针(对应数值可以理解为加):


typedef enum {TurnNone=0,TurnRight , TurnLeft}TurnDir ;


TurnDir TurningDir=TurnNone;//default turning dir = none


void EXTI15_10_IRQHandler(void)


{


u8 KeyAValue=0;


u8 KeyBValue=0;


 


//key left & right  


if (EXTI_GetITStatus(EXTI_Line12) != RESET)


{


EXTI_ClearITPendingBit(EXTI_Line12);   


  KeyAValue=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12);


KeyBValue=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11);


// printf("AB=%d,%drn",KeyAValue,KeyBValue);


 


 


if(KeyAValue==1)


{


if(KeyBValue==0)


{


TurningDir=TurnLeft;


}


else


{


TurningDir=TurnRight;


}


}


else if(KeyAValue==0)


{


if(KeyBValue==1)


{


TurningDir=TurnLeft;


}


else


{


TurningDir=TurnRight;


}


}


}


 


if (EXTI_GetITStatus(EXTI_Line11) != RESET)


{


EXTI_ClearITPendingBit(EXTI_Line11);


 


  KeyAValue=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12);


KeyBValue=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11);


if(KeyBValue==1)


{


if(KeyAValue==0)


{


TurningDir=TurnRight;


}


else


{


TurningDir=TurnLeft;


}


}


else if(KeyBValue==0)


{


if(KeyAValue==1)


{


TurningDir=TurnRight;


}


else


{


TurningDir=TurnLeft;


}


}


  }


}



编码器旋钮的按下功能,即C,可以把它当成一个普通的按键,软件设置成上拉输入,按下时为低电平,弹起时为高,同样也使用中断操作,这里就不再描述。


至此,编码器软件设计完成。经过实测,能完美检测左旋右旋。



推荐阅读

史海拾趣

Ericsson公司的发展小趣事

Ericsson非常重视人才培养和团队建设。公司设立了专门的培训机构为员工提供全面的培训和发展机会帮助他们不断更新知识和技能以适应快速变化的市场环境。此外Ericsson还注重营造积极向上的企业文化鼓励员工创新创造和发挥潜力为公司的发展贡献自己的力量。这种注重人才培养和团队建设的策略也为Ericsson的长期发展提供了有力保障。

DAYA公司的发展小趣事

在环保意识日益增强的今天,大雅智能积极响应国家节能减排政策,推动绿色环保生产。通过采用环保材料和节能技术,大雅智能有效降低了产品生产和使用过程中的能耗和排放。同时,大雅智能还积极参与环保公益活动,倡导绿色消费理念。这些举措不仅提高了大雅智能的社会责任感形象,也为其可持续发展奠定了坚实基础。

以上五个故事均基于虚构的DAYA公司(大雅智能)在电子行业中的发展经历,旨在展示一个电子科技公司可能面临的市场挑战、机遇以及发展策略。这些故事虽然并非真实事件,但其中蕴含的商业逻辑和发展趋势对于电子行业的其他公司也具有一定的借鉴意义。

ANYSOLAR LTD.公司的发展小趣事

近年来,随着全球能源结构的调整和光伏产业的快速发展,市场竞争日益激烈。ANYSOLAR也面临着来自同行的竞争压力和成本上升的挑战。为了应对这些变革和危机,ANYSOLAR积极调整战略,优化生产流程,降低成本。

同时,公司还加大了对新兴市场的开拓力度,通过参加国际展会、建立海外销售渠道等方式,拓展新的业务增长点。这些措施有效缓解了公司的经营压力,为公司的持续发展注入了新的活力。

迈翔科技(COILMX)公司的发展小趣事

随着技术的不断进步和产品线的不断丰富,迈翔科技开始积极拓展国内外市场。公司不仅在国内市场取得了良好的销售业绩,还成功打入了欧美、东南亚等国际市场。同时,公司也与众多知名企业建立了长期稳定的合作关系,进一步提升了品牌影响力和市场竞争力。

HP(Keysight)公司的发展小趣事

随着技术的不断进步和产品线的不断丰富,迈翔科技开始积极拓展国内外市场。公司不仅在国内市场取得了良好的销售业绩,还成功打入了欧美、东南亚等国际市场。同时,公司也与众多知名企业建立了长期稳定的合作关系,进一步提升了品牌影响力和市场竞争力。

Bellnix Co Ltd公司的发展小趣事

随着产品线的不断丰富,Bellnix开始积极拓展市场。公司通过与各大电子厂商建立合作关系,将产品应用于手机、电脑、家电等多个领域。同时,Bellnix还加强品牌建设,通过参加国际电子展会、举办技术研讨会等方式,提升品牌知名度和影响力。这些举措有效地推动了公司的市场拓展,为公司的持续发展奠定了坚实基础。

问答坊 | AI 解惑

代码出错,高手帮忙看看

--8位10进制频率计 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity ftctrl3 is   port(clkk:in std_logic;        cnt_en:out std_log ...…

查看全部问答>

菜鸟求教:6410串口驱动

最近在看6410的串口驱动,看得一头雾水,希望各位大侠传授点经验,这个方面应该怎么看,一般要看到什么程度? 有关mdd层和pdd层的驱动程序怎么处理?还是只要看BSP中的seriar的程序?…

查看全部问答>

STM32103中关于AFIO和USART的问题!

                                 在一个小系统中调试发现,如果在时钟初始化中里把AFIO打开,那么USART2就进入不了接收中断,关闭AFIO后,USART2接 ...…

查看全部问答>

EXTI如何判断是中断是上升还是下降

                                 EXTI口线设置成上升沿与下下降沿中断,中断进去后,如何判断是上升沿引起的,还是下降沿引起的?读口线高低电平不 ...…

查看全部问答>

伺服控制系统的组成及种类

  什么是伺服控制系统,衡量伺服控制系统性能的主要指标系统精度、稳定性、响应特性、工作频率四大方面,特别在频带宽度和精度方面。频带宽度简称带宽,由系统频率响应特性来规定,反映伺服系统的跟踪的快速性。带宽越大,快速性越好。伺服系统 ...…

查看全部问答>

测试实践之 为 碎碎念问答 设计一个简单测试

这不是一个单纯的 为论坛提出BUG什么的帖子。 这只是一个实践,一个关于测试的实践。 我很久没打开个人空间了,无意打开,发现了这个新功能。 叫 碎碎念一下 是个小问答。挺有爱的,我就试试咯 结果至今尚未成功过一次。 于是我想到,给这个小 ...…

查看全部问答>

AM335x 关于eeprom使用i2c1接口问题

在我的开发板上,eeprom使用的是i2c1接口,内核版本是linux3.2,问题如下 : [ 1.496795] omap_i2c omap_i2c.2: Arbitration lost [ 2.513793] omap_i2c omap_i2c.2: timeout waiting for bus ready root@am335x-evm:~# i2cdetect -r 2 WARNING! ...…

查看全部问答>

求资料

做遥控小车,求指导,用单片机…

查看全部问答>