音响设备的音量调节,以往通常采用电位器,通过可调电位器阻值大小,调节电流的大小,控制音量大小;
而编码器(encoder)是将 信号 或 数据 进行编制、转换为可用以通讯、传输和存储的信号形式的设备。更多用于频段选择,场景识别等应用。
目前,很多高端音响功放等设备都采用了 旋转编码器 来实现音量大小的调节。
那么, 编码器如何实现音量调节?
简而言之,旋转编码器 通过与 单片机(MCU)的配合使用,可实现音量大小的调节。
原理如图所示:
当 顺时针旋转 编码器时,编码器 A端子 的输出信号A 信号相位超前;
当 逆时针旋转 编码器时,编码器 B端子 的输出信号B 信号相位超前;
我们把 A/B端信号 分别接到 MCU的 两个输入端口,同时在MCU内 设置一个音量计数器;
就可以用软件来判别编码器是 顺时针旋转 还是 逆时针旋转;
通过此方法来识别是增加还是减少音量计数器的值,
最后把这个计数值送到相应的电子音量控制芯片即可实现音量(或者其他需要增量/减量的)控制。
编码器一般音量调节操作
1.机械的编码器要24脉冲/每转,牵强能够分辩3到4种速度(每隔100ms核算一次速度),机械的缺陷是有毛刺,并且寿命短,通常在1万转左右,不过LJV旋转编码器通常为30000次。
由于旋转编码器的寿命长达几十万次之多,比普通的电位器使用寿命长很多,还不会因为机械的磨损导致阻值偏差,影响音响设备声音正常输出,调节精度取决于与MCU配合的音量控制芯片的控制级数,与旋转编码器本身无关,这也是普通一般电位器无法做到的。2.期望编码器每转的脉冲越多越好,LJV的编码器和旋转编码器脉冲都许多,并且性价比很高。旋转编码器检测转变方向的电路,在检测转变方向时,用数字输出检测马达轴旋转,方向的传感器,输出相位相差90℃的两相(A相和B相)数字信号,使用两相信号检测出现在方向,对每个A相和B相信号的各沿(前沿和后沿)外加时标脉冲,脉冲的前沿同步输出旋转方向检测信号。
#include <reg52.h> sbit BMA = P1^4; // 编码开关A引脚 sbit BMB = P1^5; // 编码开关B引脚 sbit BMC = P1^6; // 编码开关 下按引脚 unsigned char display[3]; unsigned char code LEDData[ ] = { 0xC0,0xF9,0xA4,0xB0,0x99,0x92, 0x82,0xF8,0x80,0x90,0xff }; unsigned char counter = 0; //编码器脉冲计数 unsigned char n,shift; /********************************************************** ms延时子函数 **********************************************************/ void delayms(unsigned int ms) { unsigned char k; while (ms--) { for (k = 0; k < 114; k++) ; } } /********************************************************** 扫描编码器子函数 在编码器 引脚A 为 低电平期间: 编码器 引脚B 从0到1为 正转,编码器引脚 B从1到0为 反转。 **********************************************************/ void scan_encoder(void) { static bit Curr_b; //定义一个变量来储存 当前B 信号 static bit Last_b; //定义一个变量来储存 上次B脚 信号 static bit update= 0; if( BMA && BMB) //编码器无转动退出 { update = 0; return; } Last_b = BMB; //记录B信号 while(!BMA) //等待 A由低变高 { Curr_b = BMB; //记录等待期间的B信号(指当前B信号) update = 1; if(!BMC) //当按下旋钮时 { counter = 0; //计数单元清零(归位) delayms(10); } } if(update) { update = 0 ; if( (Last_b == 0)&&(Curr_b== 1) ) //B从0到1为正转 { if(counter == 255) { return; } counter++; //正转计数加 } else if((Last_b == 1)&&(Curr_b == 0)) //B从1到0为反转 { if(counter == 0) { return; } counter--; //反转计数减 } } } /********************************************************** 主函数 **********************************************************/ void main(void) { P0 = 0xff; P1 = 0xff; P2 = 0xff; T2CON = 0x00; // 设置T2CON寄存器 TH2 = 0xfc; // 1ms定时 TL2 = 0x66; ET2 = 1; // 启用Timer2中断 EA = 1; // 总中断允许 TR2 = 1; // 启动 定时器2 counter = 0; // 计数单元清零 while(1) { scan_encoder(); if(!BMC) //当按下旋钮时 { counter = 0; //计数单元清零(归位) delayms(10); } } } /********************************************************* Timer2中断函数 **********************************************************/ void timer2() interrupt 5 { TR2 = 0; TF2 = 0; //手工清中断标志 TH2 = 0xfc; //1ms定时常数 TL2 = 0x66; if(n >= 3) //3位数码管显示 { n = 0; shift = 0x7f; //送位码初值 P2 = 0xff; //关闭显示 } else { display[0] = counter%10; //个位数据 display[1] = (counter%100)/10; //十位数据 display[2] = counter/100; //百位数据 if(display[2] == 0) { display[2] = 0x0a; //百位为0,不显示 if(display[1] == 0) { display[1] =0x0a; //十位为0,不显示 } } P0 = LEDData[display[n++]]; //送段码 P2 = shift; //送位码 shift = (shift>>1)|0x80; //调整位码 } TR2 = 1; } /*********************************************************/
联系人:客服在线
手机:全工:13903011251
电话:李R:13530006400
邮箱:729986191@qq.com
地址: GUANGDONG PROVINCE