登录
首页 单片机论坛
回帖 发帖
正文

主题:各位大神看看程序哪里有问题了???

点击:889 回复:7

各位大神帮我看看程序哪里出了问题,想用状态机搞一个PWM的电机调速,并且用一个按键设置做两种功能,1S内短按则打开或者关闭电机,长按PWM调速,1~6S内PWM是一直加速,6~11S是减速,大于11秒则PWM为0
#include
#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=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
20-05-10 17:15
还不如直接把程序工程文件发出来,这样发出来可读性不好,很少有人有耐心仔细去看。
20-05-11 11:52
if(Pwm_Count==100) //如果PWM进入中断的次数=100
{
Pwm_Count=0; //次数归0
Read_Key();   //按键函数10ms扫描一次
}
1秒钟检测一次按键输入状态?
Good Luck~
20-05-11 13:49
10ms检测一次
20-05-11 18:05

引用 645504699 在 2020/5/11 18:05:03 发言【内容省略】

显然,if逻辑中的按钮输入处理需要一秒钟才能被执行一次。
20-05-12 05:42
额,我的时钟是100us中断一次的,100次就是10ms
20-05-12 17:51
这个应该在定时器中断里去计时判断,在主程序里执行,这样比较准确。
20-07-01 20:05
话说,你的按键就这么紧张吗?如果实在是太紧张的话,可以用一个模拟量口,用电阻分压的方式去检测哪个按键,这样可以一个端口做出很多个按键出来,没有必要一个按键搞那么多的功能出来,使用者要疯掉。
20-07-01 20:07

工控新闻

更多新闻资讯