文章目录
前言
1、本章节介绍旋转编码开关的程序实现过程,能采集三路甚至更多路旋转编码开关的触发信号;
2、通过LED渐变,介绍定时器x的PWM信号输出功能:改变分频值,改变输出信号的占空比,在本项目中,LED渐变表示旋转编码开关的旋转步数增减程度;
3、将M62429的控制功能封装成函数,该函数包括音频衰减值的数组(步进1dB),和控制时序代码;入参包括音频衰减数组的序号,(0-84),和声道选择序号;
旋转编码开关演示
视频展示了三个旋转开关分别控制M62429芯片音量衰减的过程,电路板左下角是音频信号输入,右下角是输出;LED渐暗同步表示音量变小,变亮表示音量变大
一、旋转编码开关控制时序
本程序多年前从贵站获得,在众多控制时序代码中,笔者认为该代码效果最好,不仅能够准确旋转方向,而且不会产生误动作。但是代码较长,经过实践和分析,笔者将分为三个部分分别讲解:
1、对开关状态进行采集——得到四个组合状态
旋转编码开关动作一次,A,B两个端分别产生一个方波,由于其特殊结构设计,这两个方波信号正好相差90°,这样就能经过四个组合状态:
A=1,B=1 状态1
A=1,B=0 状态4
A=0,B=1 状态2
A=0,B=0 状态3
uint8_t EncoderProcess( uint8_t SWA , uint8_t SWB, uint8_t SWNum )
{
if(SWA) //buttonA代表编码开关旋转是产生的信号A
{
if(SWB) //buttonB为信号B
{
input_status[SWNum] = 1; //A=1;B=1 ;input_status用1,2,3,4代表两信号的状态
}
else if(!SWB)
{
input_status[SWNum] = 4; //A=1;B=0
}
}
else if(!SWA)
{
if(SWB)
{
input_status[SWNum] = 2; //A=0;B=1
}
else if(!SWB)
{
input_status[SWNum] = 3; //A=0;B=0
}
}
每一次执行(执行间隔时间1ms即可)此函数,第一件事就是更新input_status这个变量,看看当前旋转开关在哪个状态,注意的是: A=1,B=1是稳定状态,其他三个状态都是暂时状态。
2、判断一个完整旋转步进过程的标准——pulse0[]或者pulse1[]累加超过4次
//如果状态为 1 因为开关旋转后 电平会停在 1 状态,在此执行所需要的东西
if(scanf_status[SWNum] == 1) //若scanf_status为1,说明旋转开关正向旋转了一个步进(20个步进是一圈)
{
if(pulse0[SWNum] >= 4)
{
pulse0[SWNum] = 0;
if (counter[SWNum] >= 84 )//限制在84个步进,与使用的编码开关型号有关
{
counter[SWNum] = 84;}
else counter[SWNum] ++;
return counter[SWNum] ;//确定正转,返回1;
}
if(pulse1[SWNum] >= 4)
{
pulse1[SWNum] = 0;
if (counter[SWNum] < 2)
{
counter[SWNum] = 0;}
else counter[SWNum] --;
return counter[SWNum];//确定反转,返回2
}
//在状态1 的 前提下,判断是正旋转还是反旋转
if (input_status[SWNum] == 2) //正旋转
{
scanf_status[SWNum] = 2;
pulse0[SWNum]++;
pulse1[SWNum] = 0;
}
else if (input_status[SWNum] == 4) //反旋转
{
scanf_status[SWNum] = 4;
pulse1[SWNum]++;
pulse0[SWNum] = 0;
}
}
在scanf_status里记录第二次执行函数时开关的状态,因为只有开关动起来才能叫旋转开关,所以捕捉第二次动作才可能判断旋转的方向。
这里的逻辑是:如果第二次采集到开关时发现是稳定状态,也就是 A=1,B=1,那就再观察它是否还经历了 A=1,B=0、 A=0,B=1、 A=0,B=0,在如果经历了这些状态,分别表示方向的变量pulse0或者pulse1其中一个会累计到4;
一旦pulse0或者pulse1累计到4,说明旋转开关真正地完成了一次动作,计数变量counter可以加减数并且返回了,在这里counter可以自由定义变化幅度,加1还是加2随意;也可以定义循环加还是加到一定程度就不变了,这与项目需要而自由发挥。
3、在其他暂稳态里,用变量pulse0[]和pulse1[]记录开关变化行踪
//在状态1 的 前提下,判断是正旋转还是反旋转
if (input_status[SWNum] == 2) //正旋转
{
scanf_status[SWNum] = 2;
pulse0[SWNum]++;
pulse1[SWNum] = 0;
}
else if (input_status[SWNum] == 4) //反旋转
{
scanf_status[SWNum] = 4;
pulse1[SWNum]++;
pulse0[SWNum] = 0;
}