基于stm32单片机的Grayhill编码器/开关软件设计

发布者:Xiaohan521最新更新时间:2019-08-14 来源: eefocus关键字:stm32  单片机  Grayhill编码器  开关软件 手机看文章 扫描二维码
随时随地手机看文章

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,可以把它当成一个普通的按键,软件设置成上拉输入,按下时为低电平,弹起时为高,同样也使用中断操作,这里就不再描述。


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



关键字:stm32  单片机  Grayhill编码器  开关软件 引用地址:基于stm32单片机的Grayhill编码器/开关软件设计

上一篇:MDK5+CH340驱动安装
下一篇:STM32学习记录之cubemx配置IIC+逻辑分析仪的学习

推荐阅读最新更新时间:2024-11-17 13:07

AVR单片机定时器、PWM、ICP范例
/*********************************************** **** AVR 定时器使用范例 *** **** *** **** 编译器:WINAVR20050214 *** ***********************************************/ /* 本程序简单的示范了如何使用ATMEGA16的定时器 AVR定时器的要点介绍 T0工作于CTC模式,输出1KHz/2KHz 50%占空比的方波 T1工作于快速PWM模式兼输入捕捉 T2工作于相位修正
[单片机]
简单热敏电阻测温电路
单片机在电子产品中的应用已经越来越广泛,在很多的电子产品中也用到了温度检测和温度控制,但那些温度检测与控制电路通常较复杂,成本也高,本文提供了一种低成本的利用单片机多余I/O口实现的温度检测电路,该电路非常简单,且易于实现,并且适用于几乎所有类型的单片机。其电路如图1所示: P1.0、P1.1和P1.2是单片机的3个I/O脚; RK为100k的精密电阻; RT为100K-精度为1%的热敏电阻; R1为100Ω的普通电阻; C1为0.1μ的瓷介电容。 其工作原理为: 先将P1.0、P1.1、P1.2都设为低电平输出,使C1放电至放完。 将P1.1、P1.2设置为输入状态,P1.0设为高电平输出,通过RK电阻对C1充电,单片机内部计时器
[测试测量]
基于AVR单片机捕获中断实现红外线解码的方法介绍
  AVR单片机是Atmel公司推出的一个单片机系列。由于该系列单片机的集成度高,因此,其软/硬件设计都变得更加简洁。文中介绍通过AVR单片机的捕获中断来实现 红外线通讯 解码的一种方法。   1 红外线编码   家电遥控中常用的红外线编码电路有μPD6121G型HT622型和7461型等。本文就以这些电路的编码格式来讨论怎样使用AVR单片机的捕获中断功能来实现其解码。   红外线通讯的发送部分主要是把待发送的数据转换成一定格式的脉冲,然后驱动红外发光管向外发送数据。接收部分则是完成红外线的接收、放大、解调,还原成同步发射格式相同(但高、低电位刚好相反的脉冲信号。这些工作通常由一体化的接收头来完成,主要输出TTL兼容电平
[单片机]
基于AVR<font color='red'>单片机</font>捕获中断实现红外线解码的方法介绍
STM32:ADC采集数据实例(采用DMA模式)
SOC:STM32F103RCT6 软件平台:STM官方库V3.5.0 开发工具:Keil 1. 摘要 本文章将给出STM32F103RCT6控制AT24C02的代码。如有疑问和错误,欢迎留言告之。 2.硬件连接 AT24C02使用I2C进行数据访问,板子上使用STM32的I2C控制器2和AT24C02进行连接。 具体来说,PB10作为SCL和AT24C02相连,PB11作为SDL和AT24C02相连。 这里就不给出硬件连接图了,比较简单。 3. AT24C022C访问代码(轮询) I2C这里使用轮询方法,不是中断,请留意。 首先,给出I2C控制器的初始化代码,和读写代码,一共三个函数,对应三个功能。 注意
[单片机]
利用基于闪存的MCU实现用户数据存储
采用微控制器的大多数设备还需要某种机制来存储在断电时仍要被记住的那些设置数据。例如,在更换电池后记不住预设电台的收音机肯定不会在市场上取得很大的成功。用户希望喜爱的电台、预设温度、参数选择和其他永久性信息能长久保存下来供每次开机时直接取用。 为了满足这种用户需求,设计师一般使用串行EEPROM。这些器件又小又便宜,具有很长的历史,设计工程师用起来得心应手。但在今天对成本极其敏感的市场下,即使这样一个廉价的器件也可能突破成本预算。因此许多设计师试图寻求并利用已经包含在微控制器芯片中的资源:程序闪存中剩余的空间。 过去,许多微控制器使用ROM或可紫外线擦除的EPROM来存储程序指令。但现在越来越多的微控制器转用闪存技术存储代码。选择
[单片机]
利用基于闪存的<font color='red'>MCU</font>实现用户数据存储
PIC单片机红外遥控编码与解码的问题分享
一般常用的红外遥控器编码规则都差不多,基本上都同6221原理一样 PIC单片机接收时: 如果用54,57这类片子做的话有一定的难度(假如要做成实时控制的;比如说你还要驱动显示,驱动步进电机,在加上几个按键)原因就是这类片子没有中断 例程如下(用来解6221;分频比为256) RF: BTFSC PORTB,2;;B2口用做接收口 GOTO RF1 BTFSS DOWNBIT;;检测下降沿标制 CLRF RTCCOUNT BSF DOWNBIT;制下降沿标制 BTFSS UPBIT;;检测上升沿标制 RETLW 0 BTFSC IDBIT;;检测码头标制 GOTO RF3 MOVLW 2AH SUBWF R
[单片机]
空调温控电子膨胀阀驱动电路的设计
1 引言 电子膨胀阀是用电子电路控制的膨胀阀,它是变频空调制冷设备中的关键部件。由于电子膨胀阀能够根据CPU的指令迅速调节阀的开启度,快速控制制冷剂的流量,减小房间内的温差,因而既能增强空调房间的舒适程度,又可最大限度地节能。电子膨胀阀的驱动部件是一个4相8拍步进电机。本文给出了一种电子膨胀阀的驱动电路。 2 系统硬件设计 整个系统采用模块化设计。系统硬件电路主要由单片机、温度传感器、电池供电的RAM、步进电机驱动部件、RS485等组成,其单片机硬件电路如图1所示。 由于程序比较大和中间变量比较多,这里采用了Atmel公司的AT89C55型单片机。它具有20 KB的Flash程序存储空间和256字节的RAM。
[单片机]
空调温控电子膨胀阀驱动电路的设计
英飞凌推出新型高性能微控制器AURIX™ TC4Dx
【2024年11月13日, 德国慕尼黑讯】 全球功率系统和物联网领域的半导体领导者英飞凌科技股份公司近日宣布推出最新AURIX™ TC4x系列的首款产品AURIX™ TC4Dx微控制器(MCU)。AURIX™ TC4Dx基于28nm技术,可提供更强大的性能和高速连接 。它将功率和性能方面的改进与虚拟化、人工智能(AI)、功能安全、网络安全和网络功能方面的最新趋势相结合,为实现新型电子/电气(E/E)架构和下一代软件定义汽车奠定了基础。像AURIX™ TC4Dx 这样的 MCU 对于控制和监测汽车中的各种系统至关重要,例如车辆运动控制、高级驾驶辅助系统(ADAS)和底盘。 英飞凌AURIX™ TC4x 英飞凌科技微控制
[网络通信]
英飞凌推出新型高性能<font color='red'>微控制器</font>AURIX™ TC4Dx
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved