C51单片机如何利用矩阵键盘上的一个键实现一个设备的启停---下面的程序是想实现在矩阵键盘检测到13#键时,第一次为打开照明灯,松开后灯继续亮,第二次按这个键时,松开手灯灭的功能,单独运行本程序正常,加到switch--case语句中就不能运行了,怎样解决此问题,我测试时用过取反程序--由于按键持续按住,灯不停亮灭实现不了此功能。
case 13: ///*照明控制*/
if(step==13)
{
Delay_ms(10);
if(step==13)
{
// LCD_ShowString(1,1," ");
LCD_ShowString(1,1,"lighting control");//在第1行照明控制
LIGKZ_cnt++;
if(LIGKZ_cnt==1)
{
LIGKZ=1;
LCD_ShowString(2,1,"Status: LightOn");//在第2行灯亮
}
if(LIGKZ_cnt==2)
{
LIGKZ=0;
LCD_ShowString(2,1,"Status: LightOff");//在第2行灯亮
LIGKZ_cnt=0;
}
while(step==13)
{
Delay_ms(20);
// LIGKZ=~LIGKZ;
led0=1; //测试灯
}
//// LIGKZ=~LIGKZ;
}
}
// led0=~led0; //测试灯
break;
case 13: ///*照明控制*/
if(step==13)
{
Delay_ms(10);
if(step==13)
{
// LCD_ShowString(1,1," ");
LCD_ShowString(1,1,"lighting control");//在第1行照明控制
LIGKZ_cnt++;
if(LIGKZ_cnt==1)
{
LIGKZ=1;
LCD_ShowString(2,1,"Status: LightOn");//在第2行灯亮
}
if(LIGKZ_cnt==2)
{
LIGKZ=0;
LCD_ShowString(2,1,"Status: LightOff");//在第2行灯亮
LIGKZ_cnt=0;
}
while(step==13)
{
Delay_ms(20);
// LIGKZ=~LIGKZ;
led0=1; //测试灯
}
//// LIGKZ=~LIGKZ;
}
}
// led0=~led0; //测试灯
break;
1:step是采用矩阵键盘中的键输入数据,松键step=0.
2:好像问题在于松手检测--跳不出来:
while(step==13)
{
Delay_ms(20);
// LIGKZ=~LIGKZ;
led0=1; //测试灯
}
2:好像问题在于松手检测--跳不出来:
while(step==13)
{
Delay_ms(20);
// LIGKZ=~LIGKZ;
led0=1; //测试灯
}
下面是全部的程序
void main(void)
{
uchar PWKZ_cnt=0;//电源控制标志位,按钮次数
uchar LIGKZ_cnt=0;//照明控制标志位,按钮次数
PWKZ=0;//24V电源控制
LIGKZ=0;//照明控制初始化
P2=0;//所有电机不工作
LCD_Init();//LCD初始化
while(1)
{
if(S1==0) {step=13;} else {step=0;}//S1临时测试按钮,测试完成后由矩阵键盘输入step值
switch(step)
{
case 0:{
M1ZZ=0; //所有电机停止转动
M1FZ=0;
M2ZZ=0;
M2FZ=0;
M3ZZ=0;
M3FZ=0;
M4ZZ=0;
M4FZ=0;
LCD_ShowNum(1,13,step,2);
break;
}
case 1:M1ZZ=1;LCD_ShowNum(1,13,step,2);break; //电机M1正转
case 2:M2ZZ=1;LCD_ShowNum(1,13,step,2);break; //电机M2正转
case 3:M3ZZ=1;M4ZZ=1;LCD_ShowNum(1,13,step,2);break; //电机M3,M4正转
case 4:M3ZZ=1;M4FZ=1;LCD_ShowNum(1,13,step,2);break; //电机M3正转,M4反转
case 5:M1FZ=1;LCD_ShowNum(1,13,step,2);break; //电机M1反转
case 6:M2FZ=1;LCD_ShowNum(1,13,step,2);break; //电机M2发转
case 7:M3FZ=1;M4FZ=1;LCD_ShowNum(1,13,step,2);break; //电机M3,M4反转
case 8:M3FZ=1;M4ZZ=1;LCD_ShowNum(1,13,step,2);break; //电机M3反转,M4正转
case 9:M1ZZ=1;M2ZZ=1;LCD_ShowNum(1,13,step,2);break; //电机M1与M2正转
case 10:M1FZ=1;M2FZ=1;LCD_ShowNum(1,13,step,2);break; //电机M1与M2反转
case 11:M1FZ=1;M2FZ=1;M3FZ=1;M4FZ=1;LCD_ShowNum(1,13,step,2);break; //所有电机电机M1,M2,M3,M4反转
case 12:M1ZZ=1;M2ZZ=1;M3ZZ=1;M4ZZ=1;LCD_ShowNum(1,13,step,2);break; //所有电机电机M1,M2,M3,M4正转
case 13: /*照明控制程序*/
if(step==13)
{
Delay_ms(10);
if(step==13)
{
// LCD_ShowString(1,1," ");
LCD_ShowString(1,1,"lighting control");//在第1行照明控制
LIGKZ_cnt++;
if(LIGKZ_cnt==1)
{
LIGKZ=1; //灯亮
LCD_ShowString(2,1,"Status: LightOn");//在第2行灯亮
}
if(LIGKZ_cnt==2)
{
LIGKZ=0;//灯灭
LCD_ShowString(2,1,"Status: LightOff");//在第2行灯亮
LIGKZ_cnt=0;
}
while(step==13)
{
Delay_ms(20);
}
}
}
break;
case 14:
if(step==14)
{
Delay_ms(10);
if(step==14)
{
// LCD_ShowString(1,1," ");
LCD_ShowString(1,1,"At stopped state");//在第1行照明控制-LCD显示
PWKZ_cnt++;
if(PWKZ_cnt==1)
{
PWKZ=1;
LCD_ShowString(2,1,"Status:Operation");//在第2行灯亮-LCD显示
}
if(PWKZ_cnt==2)
{
PWKZ=0;
LCD_ShowString(2,1," Please unlock ");//在第2行灯亮-LCD显示
PWKZ_cnt=0;
}
while(step==14)
{
Delay_ms(10);
}
}
}
break;
case 15:break; //备用
case 16:break; //备用
}
}
}
本帖最后由 lss9310 于 2024-4-12 11:02 编辑
本意是松手检测,我的想法是这样的,如没有这句while(step==13)则LIGKZ_cnt++;一直在加。具体这个功能能实现吗,麻烦给一个程序。谢谢
本意是松手检测,我的想法是这样的,如没有这句while(step==13)则LIGKZ_cnt++;一直在加。具体这个功能能实现吗,麻烦给一个程序。谢谢
case:后面加{},我还是不太习惯。
既然你要在松手时动作,那就放case 0:里面才对吧。
你试试看
uchar kt;
然后在case 13:里面kt = 13;
然后在case 0:里面
if(kt==13){}
这样行不行
谢谢!这样用S1键模拟,达到同一个键按二次实现了设备的启动与停止。我的程序本意是通过485通信,主机接收到数据是13,即step=13,这个值二次实现设备的启动与停止,此程序修改为下面没能实现想要的控制: key_val=re_buf[0];//key_val--接收485传过来的数据
// if(key_val!=13) {step=key_val;s2=1;}
if(key_val==13) {s2=0;}
if(s2==0)
{
Delay_ms(10);
if(s2==0)
{
step=13; //S1临时测试按钮,测试完成后由矩阵键盘输入step值
while(key_val==0);
}
}
else
{
step=key_val;
s2=1;
}
请教我怎么能实现此功能呢,麻烦给一个程序,谢谢!