发表于:2020/5/10 17:15:51
#0楼
各位大神帮我看看程序哪里出了问题,想用状态机搞一个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=0; //定义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;
}
}
#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=0; //定义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;
}
}
[此贴子已经被作者于2020/5/10 20:06:06编辑过]
1分悬赏