完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
之前学过机械按键与电容式触摸按键,均可以用来调节数值大小。在某些需求中,譬如需要快速调节音量数值大小或速度数值大小等,此时用按键方式则十分麻烦。于是引入了旋转编码器这种器件,可以快速调节数值大小,在工业领域较常应用。
开发板接线 实物图 旋转编码器共有3种操作:逆时针旋转、顺时针旋转、向下按 旋转是有格段的,每旋转一个格段,大小加一或减一。按下旋转编码器时清零。 原理图 与模拟量摇杆共用三个引脚,在使用旋转编码器时短接旋转编码器,断开模拟量摇杆。 左右旋转的波形图 每一个低电平都表示旋转了一个格段,通过计数低电平的个数就可以知道旋转了多少个格段。 在旋转格段时会有机械抖动,360度有20个格段。 如何判断向左旋转还是向右旋转 方法:先判断K2是否是低电平,如果是低电平,再判断K3是高电平还是低电平,如果K3是高电平则是向右旋转,如果K3是低电平则是向左旋转。 判断旋转格段是否锁死 方法:用一定的时间来计数,譬如1.2秒,在规定时间内完成旋转并回到高电平则未锁死,如果在规定时间内还没有完成旋转格段回到高电平,则判断为锁死。 代码如下: main函数 #include "stm32f10x.h" //STM32头文件 #include "sys.h" #include "delay.h" #include "rtc.h" #include "TM1640.h" #include "encoder.h" int main (void) { u8 a=0,b=0,c=0x01; RCC_Configuration(); //系统时钟初始化 RTC_Config(); //RTC初始化 ENCODER_Init(); //旋转编码器初始化 TM1640_Init(); //TM1640初始化 TM1640_display(0,a/10); //显示数值 TM1640_display(1,a%10); TM1640_display(2,20); //20表示不显示 TM1640_display(3,20); TM1640_display(4,20); TM1640_display(5,20); TM1640_display(6,20); TM1640_display(7,20); while(1) { b=ENCODER_READ(); //读出旋转编码器值 if(b==1){a++;if(a>99)a=0;} //分析按键值,并加减计数器值。 if(b==2){if(a==0)a=100;a--;} if(b==3)a=0; if(b!=0) //如果有旋转器的操作 { TM1640_display(0,a/10); //显示数值 TM1640_display(1,a%10); } } } encoder.c函数 #include "encoder.h" u8 KUP; //旋钮锁死标志(1为锁死) u16 cou; //锁死时间计数 //接口初始化 void ENCODER_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO的初始化枚举结构 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE); GPIO_InitStructure.GPIO_Pin = ENCODER_L | ENCODER_D; //选择端口号 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //选择IO接口工作方式 //上拉电阻 GPIO_Init(ENCODER_PORT_A,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = ENCODER_R; //选择端口号 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //选择IO接口工作方式 //上拉电阻 GPIO_Init(ENCODER_PORT_B,&GPIO_InitStructure); } //读出旋转编码器的旋转数据 u8 ENCODER_READ(void) { u8 a;//存放按键的值 u8 kt; a=0; //判断旋钮是否解除锁死 if(GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_L))KUP=0; //判断是否旋转旋钮,同时判断是否有旋钮锁死 if(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_L)&&(KUP==0)) { delay_us(100); kt=GPIO_ReadInputDataBit(ENCODER_PORT_B,ENCODER_R); //把旋钮另一端电平状态记录 delay_ms(3); //延时 if(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_L)) //去抖 { if(kt==0) //用另一端判断左或右旋转 { a=1;//右转 } else { a=2;//左转 } cou=0; //初始锁死判断计数器 //等待放开旋钮,同时累加判断锁死,如果在1.2S内回到高电平则退出while循环 while(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_L)&&(cou<60000)) { cou++; KUP=1; delay_us(20); //共延时1.2S来判断是否锁死 } } } if(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_D)&&(KUP==0)) //判断旋钮是否按下 { delay_ms(20); if(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_D)) //去抖动 { a=3;//在按键按下时加上按键的状态值 //while(ENCODER_D==0); 等等旋钮放开 } } return a; } encoder.h文件 #ifndef __ENCODER_H #define __ENCODER_H #include "sys.h" #include "delay.h" #define ENCODER_PORT_A GPIOA //定义IO接口组 #define ENCODER_L GPIO_Pin_6 //定义IO接口 #define ENCODER_D GPIO_Pin_7 //定义IO接口 #define ENCODER_PORT_B GPIOB //定义IO接口组 #define ENCODER_R GPIO_Pin_2 //定义IO接口 void ENCODER_Init(void);//初始化 u8 ENCODER_READ(void); #endif main函数中用到了上一节学过的数码管显示,在调用TM1640_display(7,20)函数中,7表示显示的位为第七位,20表示不显示。本节只用到了数码管的第0位与第1位来显示旋转编码器的数据,其余6位全部不显示。 使用旋转编码器时需要注意判断左右旋转和旋转格段锁死的问题。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
711 浏览 0 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
464 浏览 1 评论
301 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
260 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
634 浏览 2 评论
1396浏览 9评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
92浏览 3评论
50浏览 3评论
STM32CUBEMX4.22.1在main函数里面添加一行语句就死机的原因?
59浏览 3评论
52浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-5-8 15:51 , Processed in 0.783418 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号