[技术问答]

非自锁按键控制输出PWM占空比的程序问题

[复制链接]
933|11
手机看帖
扫描二维码
随时随地手机跟帖
安娜12345|  楼主 | 2017-9-20 14:38 | 显示全部楼层 |阅读模式
我想写的程序是根据两个按键SW1,SW2的按下次数控制输出PWM的占空比
主程序如下:
INT32 main(VOID)
{
        UINT8 ucRecord=0; //记录SW1按下的奇偶次,按下奇次时为1,按下偶次时为0,即按键SW1控制PWM波的输出与否
        INT32 ucSpeed=0;

        KeyInit(); //按键SW1(P3.2口),SW2(P3.6口)的初始化
        
        LEDShowInit(); //用于显示的LED灯的初始化
        
        /*PWM初始化,输出频率为10kHz*/
        PWMInit();//用到PWM2345,即单片机要输出四路PWM波
               
        TMR0Init(); //定时器0初始化,设计程序每隔20ms扫描一次按键,20ms的间隔用定时器中断实现
        
        while(1)
        {
                /*每隔20ms进行一次按键检测*/
                if(g_bTimer0IRQEvent)
                {
                        g_bTimer0IRQEvent = 0; //进入定时器中断函数
                        
                        ucRecord = KeyRead(); //按键扫描函数,检测SW1,SW2是否按下,SW1和SW2按下时ucRecord的第2位
                                                             //和第六位分别为1

                        if(ucRecord)  //如果有按键按下
                        {
                                 if(ucRecord & (1<<2)) //如果SW1按下
                                 {
                                         if(ucSpeed)     //如果SW1之前按下过(按下偶数次)
                                         {
                                                 ucSpeed = 0;  //PWM停止输出控制
                                         }
                                         else
                                         {
                                                 ucSpeed = 1; //如果SW1之前未按下过(按下奇数次),PWM开始输出
                                         }
                                 }
                                 if((ucRecord & (1<<6)) && (ucSpeed)) //如果SW2按下,且SW1按下奇数次,
                                                                                             //即PWM是允许输出状态
                                 {
                                         ucSpeed = ucSpeed + 1; //SW2按键用于控制改变占空比,此时改变ucSpeed值表示切换占空比
                                         ucSpeed = ucSpeed % 4;//设置三种PWM波占空比模式
                                         if(!ucSpeed)
                                         {
                                                 ucSpeed = 1;    //多次按下SW2时,三种PWM波占空比模式循环设置
                                         }
                                 }
                        }
                        
                        switch(ucSpeed)
                        {
                                case 0: //PWM波停止输出状态
                                {
                                        CMR2A = 0;
                                        CMR3A = 0;
                                        CMR0B = 0;
                                        CMR1B = 0;
                                }break;
                                case 1://占空比40%
                                {
                                        CMR2A = 96;//PWM2,PWM为中心对齐模式
                                        CMR3A = 96;
                                        CMR0B = 144; //PWM4,PWM45设置为反向输出,实现PWM23和PWM45之间的180度相位差
                                        CMR1B = 144;
                                        P0_DOUT &=~ (1<<1); //点亮LED6
                                        P3_DOUT |= (3<<4);  //LED78灭
                                }break;
                                case 2://占空比60%
                                {
                                        CMR2A = 144;//PWM2
                                        CMR3A = 144;
                                        CMR0B = 96; //PWM4
                                        CMR1B = 96;
                                        P0_DOUT |= (1<<1);
                                        P3_DOUT &=~ (1<<4);  //LED7亮
                                        P3_DOUT |= (1<<5);
                                }break;
                                case 3://占空比80%
                                {
                                        CMR2A = 192;//PWM2
                                        CMR3A = 192;
                                        CMR0B = 48; //PWM4
                                        CMR1B = 48;
                                        P0_DOUT |= (1<<1);
                                        P3_DOUT |= (1<<4);
                                        P3_DOUT &=~ (1<<5); //LED8亮
                                }break;
                                default:break;
                        }
                }               
        }
}

问题,该程序烧写到板子上的时候,按下SW1键,松开瞬间LED6会亮,然后就一直不亮了。按下SW1后,再按SW2时板子没有任何反应,即LED78均不会亮。
程序中,有if语句判断,理论上应该是,在没有按键按下时,ucRecord为0,不进入if语句,那么各参数的配置不会变,也就是,LED灯可以一直亮,但从板子实现来看,好像是各参数的值在每次循环中都会初始化
求解决办法(完整的工程在附件中,程序是在keil4上写的,芯片信息M052ZDN)

MOTOR20170919.zip

246.53 KB

xinpian101| | 2017-9-20 15:14 | 显示全部楼层
人家都是两个按键,一个是增加,一个是减少。

使用特权

评论回复
安娜12345|  楼主 | 2017-9-20 15:19 | 显示全部楼层
这样子啊,那我的这种设计方式不可行吗?感觉我的程序没有错,但是实现效果显然不对,求解答

使用特权

评论回复
xinpian101| | 2017-9-20 15:44 | 显示全部楼层
你这种设计,操作起来就很费劲,写代码更费劲。不建议你这么弄,还是用通用的吧,就是两个,一个增加占空比,一个减小占空比。如果用3个按键,还可以一个用于功能选择,比如切换到调整占空比,切换到调整周期。

使用特权

评论回复
xinpian101| | 2017-9-20 15:45 | 显示全部楼层
要做的符合大众化操作思维。

使用特权

评论回复
安娜12345|  楼主 | 2017-9-20 15:54 | 显示全部楼层
xinpian101 发表于 2017-9-20 15:14
人家都是两个按键,一个是增加,一个是减少。

我把main函数改成这样,SW1减小占空比,SW2增加占空比
#define ChangWidth   CNR2A*0.2
#define MaxValue     CNR2A
#define ChangeThreshold CNR2A*0.8

INT32 main(VOID)
{
        UINT8 ucRecord=0;

        KeyInit(); //按键SW1,SW2初始化
       
        LEDShowInit();
       
        /*PWM初始化,频率为10kHz*/
        PWMInit();
               
        TMR0Init();
       
        while(1)
        {
                /*每20ms进行按键检测*/
                if(g_bTimer0IRQEvent)
                {
                        g_bTimer0IRQEvent = 0; //进入定时器中断函数                       
                       
                        ucRecord = KeyRead();

                        if(ucRecord)
                        {
                                 if(ucRecord & (1<<2)) //SW1按下,减小PWM23的占空比
                                 {
                                         if(CMR2A < ChangWidth)
                                         {
                                                 CMR2A = 0;
                                         }
                                         else
                                         {
                                                 CMR2A = CMR2A - ChangWidth;
                                         }
                                         CMR3A = CMR2A;
                                         CMR0B = MaxValue - CMR2A;
                                         CMR1B = CMR0B;
                                         P0_DOUT &=~ (1<<1);
                                         P3_DOUT |= (1<<4);
                                 }
                                 if(ucRecord & (1<<6)) //SW2按下,增加PWM23的占空比
                                 {
                                         if(CMR2A > ChangeThreshold)
                                         {
                                                 CMR2A = MaxValue;
                                         }
                                         else
                                         {
                                                 CMR2A = CMR2A + ChangWidth;
                                         }
                                         CMR3A = CMR2A;
                                         CMR0B = MaxValue - CMR2A;
                                         CMR1B = CMR0B;
                                         P0_DOUT |= (1<<1);
                                         P3_DOUT &=~ (1<<4);
                                 }
                        }
                }
        }
}

改成这样后,按下SW1时LED灯可长亮,按下SW2时对应的LED灯还是在松开按键时闪烁,不能长亮。请问这个要怎么解决?

使用特权

评论回复
xinpian101| | 2017-9-20 16:02 | 显示全部楼层
你是想让按下时候一直亮,还是亮一下,你没说清楚你要干啥。

使用特权

评论回复
安娜12345|  楼主 | 2017-9-20 16:17 | 显示全部楼层
xinpian101 发表于 2017-9-20 16:02
你是想让按下时候一直亮,还是亮一下,你没说清楚你要干啥。

是按下之后一直亮

使用特权

评论回复
安娜12345|  楼主 | 2017-9-20 16:21 | 显示全部楼层
xinpian101 发表于 2017-9-20 16:02
你是想让按下时候一直亮,还是亮一下,你没说清楚你要干啥。

我设置LED的亮灭是为了辅助显示程序的运行状态,就是看看PWM的设置是否发生改变。
按下SW2,松开时LED只是闪烁一下,是不是可以说明,在同一段if语句中设置CMR的参数的语句没有成功执行?

使用特权

评论回复
dongnanxibei| | 2017-9-20 20:31 | 显示全部楼层
应该在按键检测里测试那个是否点亮,如果点亮,不动作,没有点亮点亮。

使用特权

评论回复
zhuomuniao110| | 2017-9-22 18:01 | 显示全部楼层
最不喜欢的就是帮人看代码了,你可以用流程图来表述一眼就懂。。

使用特权

评论回复
598330983| | 2017-9-24 09:22 | 显示全部楼层
这年头,搞一堆代码让人看,你要说谁帮你分析,你打赏,立马就一堆人来。主要看代码太费劲

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

11

帖子

0

粉丝