【用音量控制器介绍GD32F330C8T6单片机外设应用(三)——编码开关程序/M62429控制程序/PWM定时器程序实现介绍】


前言

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;
            }
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值