器件: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;然后是各系列的电气特性,主要是使用寿命,工作温度,绝缘特性;

  需要看的就是后面的波形时序,和"黄海电子"规格书的推荐电路了;

  关于滤波电路的相关电分定义先放着;

   

 

posted @ 2024-09-12 08:53  caesura_k  阅读(288)  评论(0编辑  收藏  举报