按键控制PWM
时间:10-02
整理:3721RD
点击:
想编一个程序,来判定按键长按,短按,来实现不同的作用。并且改变PWM。
说起来简单,但尝试了好多种方法才实现。
期间遇到好多不同的问题:
1.按键按下了PWM不动了
2.长按无法实现
3.连续短按误判为长按
4.长按短按无法实现想要的参数变更
5.按键判定OK但无PWM输出
还有好多。要做个简单的事也有好多的情况会出现啊!
看别人的程序一看就懂,但要自己写一个严谨的程序真不容易。
给初学者参考使用。
#include<reg51.h> //51头文件,
#include<intrins.h>
//---------常用的两个宏定义--------------
#define uint8 unsigned char
#define uint16 unsigned int
//------------函数的声明-----------------
void DelayMS(uint16 dly);
//--定义使用的IO口--//
sbit KEY=P1^0;
sbit KEY1=P1^1;
sbit PWM=P0^1;
//--定义一个全局变量--//
unsigned char timer1,pwm,i; //定时器返回值
void Timer0Interrupt();
void InitTimer1();
void Keyscan();
void Delay10ms(unsigned int c) //误差 0us
{
unsigned char a, b;
//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
for (;c>0;c--)
{
for (b=38;b>0;b--)
{
for (a=130;a>0;a--);
}
}
}
void InitTimer1(void)
{
TMOD = 0x10;
TH1 = 0x0FE;
TL1 = 0x0C;
EA = 1;
ET1 = 1;
TR1 = 1;
}
void main(void)
{
int k=2,num;
InitTimer1();
i=10;
while(1)
{
int j;
if (KEY==0) //检测按键K1是否按下
{
Delay10ms(1); //消除抖动
num=0;
while (KEY==0) //再次检测按键是否按下
{
Delay10ms(1);
num++;//记录按键按下的时间
}
if(5<num&&num<50)//此处一定不能定成0<num<50否则程序会认为是0<num而不会判定num<50;
i=i+5;
if(num>50)
k++;
while(!KEY)
{}
}
else if (KEY1==0)
{
Delay10ms(1);
if (KEY1==0)
{
i = i-5;
j=0;
while ((j<30) && (KEY1==0)) //检测按键是否松开
{
Delay10ms(1);
j++;
}
}
}
P2=~k;
}
}
void Timer1Interrupt(void) interrupt 3
{
TH1 = 0x0FE;
TL1 = 0x0C;
pwm++;
if(i>=60)
{i=60;}
if(pwm>100) //PWM周期为100*0.5ms
{
pwm=0;
}
if(pwm <i) //改变30这个值可以改变直流电机的速度
{
PWM=1;
}
else
{
PWM=0;
}
//add your code here!
}
说起来简单,但尝试了好多种方法才实现。
期间遇到好多不同的问题:
1.按键按下了PWM不动了
2.长按无法实现
3.连续短按误判为长按
4.长按短按无法实现想要的参数变更
5.按键判定OK但无PWM输出
还有好多。要做个简单的事也有好多的情况会出现啊!
看别人的程序一看就懂,但要自己写一个严谨的程序真不容易。
给初学者参考使用。
#include<reg51.h> //51头文件,
#include<intrins.h>
//---------常用的两个宏定义--------------
#define uint8 unsigned char
#define uint16 unsigned int
//------------函数的声明-----------------
void DelayMS(uint16 dly);
//--定义使用的IO口--//
sbit KEY=P1^0;
sbit KEY1=P1^1;
sbit PWM=P0^1;
//--定义一个全局变量--//
unsigned char timer1,pwm,i; //定时器返回值
void Timer0Interrupt();
void InitTimer1();
void Keyscan();
void Delay10ms(unsigned int c) //误差 0us
{
unsigned char a, b;
//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
for (;c>0;c--)
{
for (b=38;b>0;b--)
{
for (a=130;a>0;a--);
}
}
}
void InitTimer1(void)
{
TMOD = 0x10;
TH1 = 0x0FE;
TL1 = 0x0C;
EA = 1;
ET1 = 1;
TR1 = 1;
}
void main(void)
{
int k=2,num;
InitTimer1();
i=10;
while(1)
{
int j;
if (KEY==0) //检测按键K1是否按下
{
Delay10ms(1); //消除抖动
num=0;
while (KEY==0) //再次检测按键是否按下
{
Delay10ms(1);
num++;//记录按键按下的时间
}
if(5<num&&num<50)//此处一定不能定成0<num<50否则程序会认为是0<num而不会判定num<50;
i=i+5;
if(num>50)
k++;
while(!KEY)
{}
}
else if (KEY1==0)
{
Delay10ms(1);
if (KEY1==0)
{
i = i-5;
j=0;
while ((j<30) && (KEY1==0)) //检测按键是否松开
{
Delay10ms(1);
j++;
}
}
}
P2=~k;
}
}
void Timer1Interrupt(void) interrupt 3
{
TH1 = 0x0FE;
TL1 = 0x0C;
pwm++;
if(i>=60)
{i=60;}
if(pwm>100) //PWM周期为100*0.5ms
{
pwm=0;
}
if(pwm <i) //改变30这个值可以改变直流电机的速度
{
PWM=1;
}
else
{
PWM=0;
}
//add your code here!
}
建议把按钮的状态读取放入定时器中,10ms中断读取,这样就不会影响其他的工作了
顶顶顶顶顶顶顶顶顶顶顶顶顶顶
按键用鸿哥的思想写,很不错哦
结果怎样?我也有此想法啊
学习,学习,学习,学习
可否设置两个按键,其中一个按下,led灯变亮,另一个反之,都是设为五档。可以这样吗?
这个要想和led结合起来该加点啥,改点啥
这个要想和led结合起来该加点啥,改点啥