找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 908|回复: 0
打印 上一主题 下一主题
收起左侧

状态机PWM的电机调速单片机程序哪里出了问题?

[复制链接]
跳转到指定楼层
楼主
ID:748480 发表于 2020-5-10 17:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 求学长 于 2020-5-10 20:07 编辑

想用状态机搞一个PWM的电机调速,并且用一个按键设置做两种功能,1S内短按则打开或者关闭电机,长按PWM调速,1~6S内PWM是一直加速,6~11S是减速,大于11秒则PWM为0
#include <reg52.h>


#define Key_State_0   0                                        //定义按键动作时的状态0
#define Key_State_1   1                                        //定义按键动作时的状态1
#define Key_State_2   2                                        //定义按键动作时的状态2
#define Key_State_3   3                                        //定义按键动作时的状态3
#define Key_State_4   4                                        //定义按键动作时的状态4


sbit Key_Input=P1^0;
sbit PWM=P2^0;


char Read_Key();
void Init_timer0(void);
void Key_Scan();


static unsigned char Pwm_Count=0;                  //定义PWM进入中断的次数
static unsigned char Pwm_Vlaue=50;                //定义PWM占空比的值
char Key_Return;


/*----------------------------------------------
               主函数
------------------------------------------------*/


void main()
{
        Init_Timer0();                  //初始化定时器0
        while(1)
        {        
                Key_Scan();                        
        }        
}


/*------------------------------------------------
              定时器初始化函数
------------------------------------------------*/


void Init_Timer0(void)
{
TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响                     
TH0=0xff;              //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
TL0=0xa4;
EA=1;            //总中断打开
ET0=1;           //定时器中断打开
TR0=1;           //定时器开关打开
}


/*------------------------------------------------
              定时器中断函数
------------------------------------------------*/
void PWM_Timer0() interrupt 1 using 1
{
        
        TH0=0xff;                  //重新赋值
        TL0=0xa4;
        Pwm_Count++;                  //PWM进入中断的次数自加1
        IF(Pwm_Count==100)                                 //如果PWM进入中断的次数=100
        {
                Pwm_Count=0;                                //次数归0
                Read_Key();                                   //按键函数10ms扫描一次        
        }
        if(Pwm_Count<Pwm_Vlaue)                   //改变Pwm_Vlaue可以改变占空比的值
        {
                PWM=1;                                 //电机打开
        }
        else
        {
                PWM=0;                                 //电机关闭
        }
}


/*------------------------------------------------
              读按键状态函数
------------------------------------------------*/


char Read_Key()                                  //按键状态处理函数
{
        static char Key_State=0,Key_Time=0;                  //按键状态值Key_State初始化为0,按键按下的时间Key_Time初始化为0
        unsigned char Key_Press;                                  //Key_Press为按键状态储存值,Key_Return为按键的状态返回值


        Key_Press=Key_Input;                                        //读按键I/O口的电平
        switch(Key_State)
        {        
               
                case 0:                           //按键的初始状态0
                                if(Key_Press!=1)                                            //按键按下
                                {
                                        Key_State=Key_State_1;                  //状态切换到确认态1
                                        Key_Return=1;                                //按键的状态返回值输出“1”                          
                                }
                                break;                                
                case 1:                          //按键的确认状态1
                                if(Key_Press!=1)                                          //按键仍然按下
                                {
                                        Key_State=Key_State_2;                 //状态切换到计时状态2
                                        Key_Time=0;                                         //按键时间计数器清0
                                }
                                else                                           //按键已经松开
                                {
                                        Key_State=Key_State_0;                 //状态切换到初始状态0
                                       
                                }
                                break;


                case 2:                          //按键的计时状态2
                                if(Key_Press)                                        //按键已经松开          --短按
                                {
                                        Key_State=Key_State_0;                //状态切换到初始状态0
                                        Key_Return=1;                                //按键的状态返回值输出“1”        
                                }
                                else if(Key_Time>=100)                //按键按下的时间计数          --长按
                                {
                                        Key_State=Key_State_3;                   //按键按下的时间大于1S,状态切换到计时状态3
                                        Key_Time=0;                                          //按键时间计数器清0
                                        Key_Return=2;                                  //按键的状态返回值输出“2”        
                                       
                                }
                                break;
                                
                case 3:                          //按键的计时状态3
                                if(Key_Press)                                        //按键已经松开
                                {
                                        Key_State=Key_State_0;                //状态切换到初始状态0
                                }
                                else
                                {
                                        Key_Time++;
                                        if(Key_Time>=0&&Key_Time<500)                         //按键按下的时间计数
                                        {
                                                Key_State=Key_State_4;                   //按键按下的时间大于6S,状态切换到计时状态4
                                                Key_Time=0;
                                                Key_Return=3;                                  //按键的状态返回值输出“3”
                                        }
                                }
                                break;
                case 4:                          //按键的计时状态3
                                if(Key_Press)                                        //按键已经松开
                                {
                                        Key_State=Key_State_0;                //状态切换到初始状态0
                                }
                                else
                                {
                                        Key_Time++;
                                        if(++Key_Time>=100&&++Key_Time<500)                         //按键按下的时间计数
                                        {
                                                Key_State=Key_State_4;                   //按键按下的时间大于6S,状态切换到计时状态4
                                                Key_Time=0;
                                                Key_Return=4;                                   //按键的状态返回值输出“4”
                                        }
                                }
                                break;
                default:Key_Time=0;        break;
                                                        
        }
        return Key_Return;
}


void Key_Scan()
{
        switch(Key_Return)
        {
                case 0:break;
                case 1:PWM=~PWM;break;
                case 2:break;
                case 3:Pwm_Vlaue++;break;                         //PWM占空比自减
                case 4:Pwm_Vlaue--;break;                         //PWM占空比自减
                default:break;
        }        
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表