器件:EC11编码器
1 序
编码器型号为"黄海电子有限公司"的"EC11A-227";参数特性和ALPS的EC11B区别不大,EC11A性能较好;
出于图片规整考虑,本文截取ALPS的EC11B的datasheet来分析EC11A,推荐电路截取自"黄海电子"的"EC11B";
2 编码原理
EC11编码器为增量式编码器;由encoderA和encoderB两个光电传感器构成,光栅盘上的传感器位置相位差90度,通过脉冲计数;
假设光栅盘转一圈时,光源亮灭半圈;那么光电传感器就产生一个方波信号,encoderA和encoderB产生的方波相位相差90度;
[这里合成一张图,outputwave的触点图+顺时针波形图 + slidingNoise的触点抖动图+test circuit图]
2.1 旋转方向
顺时针方向:当encoderA为上升沿时,encoderB为低电平;当encoderA为下降沿时,encoderB为高电平;
当encoderB为上升沿时,encoderA为高电平;当encoderB为下降沿时,encoderA为低电平;
逆时针方向:当encoderA为上升沿时,encoderB为高电平;当encoderA为下降沿时,encoderB为低电平;
当encoderB为上升沿时,encodeA为低电平;当encoderB为下降沿时,encoderA为高电平;
总结:顺时针旋转>>往encoderA方向旋转>>所以时序图A方波先出现,B方波后出现>>现象如上;
逆时针旋转>>往encoderB方向旋转>>所以时序图B方波先出现,A方波后出现>>现象如上;
判断方向时配置encoderA或encoderB其中一个触发外部中断,另外一个搭配判断方向;
3 推荐电路
推荐电路使用了RC滤波电路,硬件过滤了触点抖动,没有用示波器抓取波形,不过软件实测确实没有触点抖动;
如果没有使用RC滤波电路,那么chattering触点抖动时间需要软件延时消除;
3.1 RC滤波电路
3.1.1 低通滤波
电路:RC串联在电路中,Vin >> R >>C >>GND;Vout接在R与C之间;
当Vin较低假设为100Hz时,电容阻抗Xc = 1/2πfC=160KΩ;所以Vin都从Vout出去;低频导通,几乎不衰减;
当Vin为截止频率1600Hz时,电容阻抗Xc = 10KΩ;Vout=0.707Vin;Vout导通根号2,衰减1-根号2;
当Vin较高为100KHz时,电容阻抗Xc = 1/2πfC=16Ω;所以Vin都从电容接地;高频几乎衰减完了;
3.1.2 高通滤波
电路:CR串联在电路中,Vin >> C >> R>>GND;Vout接在C与R之间;
导通特性刚好和低通滤波反过来;
3.1.3 截止频率
作用:决定信号是否开始衰减的分界频率;计算公式为Fcutout = 1/( 2πRC );
公式:网友的截至频率推导:Xc=1/jωC = 1/2πfC = R;f = 1/2πRC;(这里也把j给去掉了;)
角频率ω = 2πf;容抗Xc = 1/jωC ; j是虚数单位,所以Xc自带了一个单位;
在低通滤波中Vout = Vin( Xc/ (R+jXc) ) = Vin( R/(R+jR) ) = Vin(1/(1+j)); (这里电路中的Xc没有保留 j ?)
Vout = Vin( 1/(1+j) )乘以共轭复数(1-j)/(1-j),得到Vout = Vin( (1-j)/(1+1) )=Vin( (1-j)/2 );
Vout =Vin( (1-j)/2 )取模,|Vout| = |Vin| 根号2/2 ≈0.707|Vin|
Xc=1/jωC=1/2πfC (把j去掉了?)
ques:为什么在电容中,电流会领先于电压90度,先放着;
ques:为什么截至频率可以作为信号衰减的分解频率呢?大概实测出来就是这么回事把;
这怎么算呢?具体得拿本教材,老是有个j时有时没有的,搞不懂为什么这里保留,那里又没有;
4 软件编写
配置encoderA为外部中断,上升沿下降沿都触发;于是encoderA产生边沿后就会进入中断函数;
中断函数中,通过对旋转方向的判断来加声音或者减声音;中断函数退出前清个标志位;就完了;
以上就是编码器的代码流程了,还是比较简单的;那可不可以配置成encodeB为外部中断呢?当然也是可以的;
查看代码
/***
ec11旋钮
encode-A作为外部中断输入,encode-B作为方向判断;
调用ec11的初始化函数初始化完之后就可以了;
每次旋转ec11,自动触发外部中断,在中断函数中修改音量值;
每次按下ec11,那边循坏读取的引脚值变化了,就视作按下按键;
***/
#ifndef BSP_ENCODE_H_
#define BSP_ENCODE_H_
#define GPIO_ENA_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE
#define ENA_GPIO GPIOB
#define ENA_PIN GPIO_PIN_0
#define GPIO_ENB_CLK_ENABLE __HAL_RCC_GPIOC_CLK_ENABLE
#define ENB_GPIO GPIOC
#define ENB_PIN GPIO_PIN_5
#define EXTI_TRQn_encoder EXTI0_IRQn
#define EXTI_IRQHandler_encoder EXTI0_IRQHandler
extern uint8_t flag_scrollMaxPrint;
extern uint8_t flag_scrollMinPrint;
void volumeMinimumPrint(void);
void volumeMaximumPrint(void);
void bsp_encode_Init();
#endif
float* pCurrVolume = NULL;
uint8_t flag_scrollMaxPrint = 0;
uint8_t flag_scrollMinPrint = 0;
//[0] 静音; [1-100]声音范围
void EXTI_IRQHandler_encoder(void){
float percentVol = 0;
//CAE("IT:%x ",__HAL_GPIO_EXTI_GET_IT(ENA_PIN));
//如果面板锁定,旋转和按键都不执行;
if(CurProduct->VideoOutput[0].key_1unlock==0){
CAE("lock.");
__HAL_GPIO_EXTI_CLEAR_IT(ENA_PIN);
return;
}
//开机时
if( (CurProduct->IsPowOn) ){
//挪动旋钮取消静音;
if(CurProduct->VideoOutput[0].key_MuteFlag==TRUE){
CurProduct->VideoOutput[0].key_MuteFlag = FALSE;
CAE("M");
}
pCurrVolume = getChanneldBVolumeAddr(CurProduct->VideoOutput[0].key_volume0LINE1MSTR);
if (HAL_GPIO_ReadPin(ENA_GPIO, ENA_PIN)){
if (HAL_GPIO_ReadPin(ENB_GPIO, ENB_PIN)){
(*pCurrVolume) = (*pCurrVolume) -1.25;
CAE("+-");
}
else{
(*pCurrVolume) = (*pCurrVolume) +1.25;
CAE("++");
}
}
else{
if (HAL_GPIO_ReadPin(ENB_GPIO, ENB_PIN)){
(*pCurrVolume) = (*pCurrVolume) +1.25;
CAE("-+");
}
else{
(*pCurrVolume) = (*pCurrVolume) -1.25;
CAE("--");
}
}
//旋钮最值打印;
if ( ((*pCurrVolume) <1) || ((*pCurrVolume)>200) ){
*pCurrVolume = 1;
flag_scrollMinPrint = 1;
}
else if ((*pCurrVolume) >100){
(*pCurrVolume) = 100;
flag_scrollMaxPrint = 1;
}
CAE("*pCurrVolume %f",(*pCurrVolume));
CurProduct->SaveEEP_tick = 10;
}
__HAL_GPIO_EXTI_CLEAR_IT(ENA_PIN);
}
void bsp_encode_Init(){
CAE("bsp_encode_Init() ");
GPIO_ENA_CLK_ENABLE();
GPIO_ENB_CLK_ENABLE();
//下降沿触发, 这种通过边沿触发的都默认是nopull模式吗?
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = ENA_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ENA_GPIO, &GPIO_InitStruct);
GPIO_InitStruct.Pin = ENB_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(ENB_GPIO, &GPIO_InitStruct);
// EXTI线配置
//文文这里有个exti线的配置的,但是这个没有也能跑先放着;
//使能中断
HAL_NVIC_SetPriority(EXTI_TRQn_encoder, 2, 1);
HAL_NVIC_EnableIRQ(EXTI_TRQn_encoder);
}
5 规格特性
EC11A额定电压为5V;最大额定电流10mA;绝缘阻抗在250V DC时,为100MΩ以上;耐电压300V持续1min,绝缘良好;
EC11A旋转寿命可达旋转20000周;
编码器还提供了一个self return switch自复位按键,还原的bounce回弹时间最大2ms;
6 小结
有的现象就是这么回事,总结出来就行了,至于因果关联性,许多现象不具备因果关联性;
这个编码器的数据手册主要需要看什么呢?
前面是产品线系列product Line和尺寸dimensions;然后是各系列的电气特性,主要是使用寿命,工作温度,绝缘特性;
需要看的就是后面的波形时序,和"黄海电子"规格书的推荐电路了;
关于滤波电路的相关电分定义先放着;