找回密码
 立即注册

QQ登录

只需一步,快速开始

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

C51单片机如何利用矩阵键盘上的一个键实现一个设备的启停

[复制链接]
跳转到指定楼层
楼主
ID:65580 发表于 2024-4-9 09:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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;

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:161164 发表于 2024-4-9 13:25 | 只看该作者
代码不完整
盲猜
1. step 用完没清零
2. step 在delay期间在哪更新?
if(step==13)
{
Delay_ms(10);
if(step==13)
回复

使用道具 举报

板凳
ID:65580 发表于 2024-4-10 11:18 | 只看该作者
1:step是采用矩阵键盘中的键输入数据,松键step=0.
2:好像问题在于松手检测--跳不出来:     
                                                                           while(step==13)
                                                                                {        
                                                                                        Delay_ms(20);
//                                                                                        LIGKZ=~LIGKZ;
                                                                                        led0=1;  //测试灯         

                                                                                }
回复

使用道具 举报

地板
ID:65580 发表于 2024-4-10 14:13 | 只看该作者
lkc8210 发表于 2024-4-9 13:25
代码不完整
盲猜
1. step 用完没清零

下面是全部的程序
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;   //备用
                                               
                }
        }
}
回复

使用道具 举报

5#
ID:161164 发表于 2024-4-10 16:17 | 只看该作者
while(step==13)
step没地方更新,死循环了
回复

使用道具 举报

6#
ID:65580 发表于 2024-4-11 09:42 | 只看该作者
lkc8210 发表于 2024-4-10 16:17
while(step==13)
step没地方更新,死循环了

这句S1按钮松开后,step=0,
if(S1==0) {step=13;} else {step=0;}//S1临时测试按钮,测试完成后由矩阵键盘输入step值
回复

使用道具 举报

7#
ID:161164 发表于 2024-4-11 10:48 | 只看该作者
lss9310 发表于 2024-4-11 09:42
这句S1按钮松开后,step=0,
if(S1==0) {step=13;} else {step=0;}//S1临时测试按钮,测试完成后由矩阵键 ...

你了解while(step==13)是啥意思吗?
都死循环了,还咋跳出去跑if(S1==0) {step=13;} else {step=0;}?
回复

使用道具 举报

8#
ID:453974 发表于 2024-4-11 13:33 | 只看该作者
lkc8210 发表于 2024-4-11 10:48
你了解while(step==13)是啥意思吗?
都死循环了,还咋跳出去跑if(S1==0) {step=13;} else {step=0;}?

他说的对,你程序卡死在while里面了,在while里面把条件清零跳出循环
回复

使用道具 举报

9#
ID:1109793 发表于 2024-4-11 20:07 | 只看该作者
在case 13里面再搞个if(step==13),有意思吗?
回复

使用道具 举报

10#
ID:65580 发表于 2024-4-12 08:33 | 只看该作者
本帖最后由 lss9310 于 2024-4-12 11:02 编辑
xiaobendan001 发表于 2024-4-11 20:07
在case 13里面再搞个if(step==13),有意思吗?

本意是松手检测,我的想法是这样的,如没有这句while(step==13)则LIGKZ_cnt++;一直在加。具体这个功能能实现吗,麻烦给一个程序。谢谢
回复

使用道具 举报

11#
ID:1109793 发表于 2024-4-12 19:37 | 只看该作者
lss9310 发表于 2024-4-12 08:33
本意是松手检测,我的想法是这样的,如没有这句while(step==13)则LIGKZ_cnt++;一直在加。具体这个功能能 ...

case:后面加{},我还是不太习惯。
既然你要在松手时动作,那就放case 0:里面才对吧。
你试试看
uchar kt;
然后在case 13:里面kt = 13;
然后在case 0:里面
if(kt==13){}
这样行不行
回复

使用道具 举报

12#
ID:65580 发表于 2024-4-13 13:49 | 只看该作者
xiaobendan001 发表于 2024-4-12 19:37
case:后面加{},我还是不太习惯。
既然你要在松手时动作,那就放case 0:里面才对吧。
你试试看

测试之后,不行。C51单片机利用矩阵键盘上的一个键(同样一个键值),实现同一台设备的第一次按按键启动,第二次按按键停止的控制,能否实现呢
回复

使用道具 举报

13#
ID:1109793 发表于 2024-4-13 15:59 | 只看该作者
lss9310 发表于 2024-4-13 13:49
测试之后,不行。C51单片机利用矩阵键盘上的一个键(同样一个键值),实现同一台设备的第一次按按键启动 ...

当然可以实现啊,那里不行?把改动的代码发上来看看呗
回复

使用道具 举报

14#
ID:65580 发表于 2024-4-14 08:45 | 只看该作者
xiaobendan001 发表于 2024-4-13 15:59
当然可以实现啊,那里不行?把改动的代码发上来看看呗

之前我的程序已经上传,而且要求也描述了,你看看怎么能实现此功能呢,请求帮助提供一个程序,因为之前我试了很多没成功,谢谢 !
回复

使用道具 举报

15#
ID:1109793 发表于 2024-4-14 09:36 | 只看该作者
lss9310 发表于 2024-4-14 08:45
之前我的程序已经上传,而且要求也描述了,你看看怎么能实现此功能呢,请求帮助提供一个程序,因为之前我 ...

之前的不能用,我说的方法你可能没试过。然后我也没有硬件,没办法测试是否能用。只能靠你自己了。
回复

使用道具 举报

16#
ID:161164 发表于 2024-4-15 11:17 | 只看该作者
lss9310 发表于 2024-4-11 09:42
这句S1按钮松开后,step=0,
if(S1==0) {step=13;} else {step=0;}//S1临时测试按钮,测试完成后由矩阵键 ...
  1. void main(void)
  2. {
  3.         uchar PWKZ_cnt=0;//电源控制标志位,按钮次数
  4.         uchar LIGKZ_cnt=0;//照明控制标志位,按钮次数
  5.         PWKZ=0;//24V电源控制
  6.         LIGKZ=0;//照明控制初始化
  7.         P2=0;//所有电机不工作
  8.         LCD_Init();//LCD初始化

  9.         while(1)
  10.         {
  11.                 if(S1==0)
  12.                 {
  13.                         Delay_ms(10);
  14.                         if(S1==0)
  15.                         {
  16.                                 step=13;   //S1临时测试按钮,测试完成后由矩阵键盘输入step值
  17.                                 while(SI==0);
  18.                         }
  19.                 }
  20.                 else
  21.                 {
  22.                         step=0;
  23.                 }

  24.                 switch(step)
  25.                 {
  26.                         case 0:
  27.                         {
  28.                                 M1ZZ=0; //所有电机停止转动
  29.                                 M1FZ=0;
  30.                                 M2ZZ=0;
  31.                                 M2FZ=0;
  32.                                 M3ZZ=0;
  33.                                 M3FZ=0;
  34.                                 M4ZZ=0;
  35.                                 M4FZ=0;
  36.                                 LCD_ShowNum(1,13,step,2);
  37.                                 break;
  38.                         }
  39.                         case 1:
  40.                                 M1ZZ=1;
  41.                                 LCD_ShowNum(1,13,step,2);
  42.                                 break;  //电机M1正转
  43.                         case 2:
  44.                                 M2ZZ=1;
  45.                                 LCD_ShowNum(1,13,step,2);
  46.                                 break;  //电机M2正转
  47.                         case 3:
  48.                                 M3ZZ=1;
  49.                                 M4ZZ=1;
  50.                                 LCD_ShowNum(1,13,step,2);
  51.                                 break;  //电机M3,M4正转
  52.                         case 4:
  53.                                 M3ZZ=1;
  54.                                 M4FZ=1;
  55.                                 LCD_ShowNum(1,13,step,2);
  56.                                 break;   //电机M3正转,M4反转

  57.                         case 5:
  58.                                 M1FZ=1;
  59.                                 LCD_ShowNum(1,13,step,2);
  60.                                 break;  //电机M1反转
  61.                         case 6:
  62.                                 M2FZ=1;
  63.                                 LCD_ShowNum(1,13,step,2);
  64.                                 break;  //电机M2发转
  65.                         case 7:
  66.                                 M3FZ=1;
  67.                                 M4FZ=1;
  68.                                 LCD_ShowNum(1,13,step,2);
  69.                                 break;  //电机M3,M4反转
  70.                         case 8:
  71.                                 M3FZ=1;
  72.                                 M4ZZ=1;
  73.                                 LCD_ShowNum(1,13,step,2);
  74.                                 break;   //电机M3反转,M4正转

  75.                         case 9:
  76.                                 M1ZZ=1;
  77.                                 M2ZZ=1;
  78.                                 LCD_ShowNum(1,13,step,2);
  79.                                 break;  //电机M1与M2正转
  80.                         case 10:
  81.                                 M1FZ=1;
  82.                                 M2FZ=1;
  83.                                 LCD_ShowNum(1,13,step,2);
  84.                                 break;  //电机M1与M2反转
  85.                         case 11:
  86.                                 M1FZ=1;
  87.                                 M2FZ=1;
  88.                                 M3FZ=1;
  89.                                 M4FZ=1;
  90.                                 LCD_ShowNum(1,13,step,2);
  91.                                 break;  //所有电机电机M1,M2,M3,M4反转
  92.                         case 12:
  93.                                 M1ZZ=1;
  94.                                 M2ZZ=1;
  95.                                 M3ZZ=1;
  96.                                 M4ZZ=1;
  97.                                 LCD_ShowNum(1,13,step,2);
  98.                                 break;   //所有电机电机M1,M2,M3,M4正转

  99.                         case 13:    /*照明控制程序*/
  100.                                 //                                LCD_ShowString(1,1,"                ");
  101.                                 LCD_ShowString(1,1,"lighting control");//在第1行照明控制

  102.                                 LIGKZ_cnt++;

  103.                                 if(LIGKZ_cnt==1)
  104.                                 {
  105.                                         LIGKZ=1;        //灯亮
  106.                                         LCD_ShowString(2,1,"Status:  LightOn");//在第2行灯亮
  107.                                 }
  108.                                 if(LIGKZ_cnt==2)
  109.                                 {
  110.                                         LIGKZ=0;//灯灭
  111.                                         LCD_ShowString(2,1,"Status: LightOff");//在第2行灯亮
  112.                                         LIGKZ_cnt=0;
  113.                                 }
  114.                                 step = 0;
  115.                                 break;

  116.                         case 14:
  117.                                 if(step==14)
  118.                                 {
  119.                                         Delay_ms(10);
  120.                                         if(step==14)
  121.                                         {
  122.                                                 //                                LCD_ShowString(1,1,"                ");
  123.                                                 LCD_ShowString(1,1,"At stopped state");//在第1行照明控制-LCD显示

  124.                                                 PWKZ_cnt++;

  125.                                                 if(PWKZ_cnt==1)
  126.                                                 {
  127.                                                         PWKZ=1;
  128.                                                         LCD_ShowString(2,1,"Status:Operation");//在第2行灯亮-LCD显示
  129.                                                 }
  130.                                                 if(PWKZ_cnt==2)
  131.                                                 {
  132.                                                         PWKZ=0;
  133.                                                         LCD_ShowString(2,1," Please unlock  ");//在第2行灯亮-LCD显示
  134.                                                         PWKZ_cnt=0;
  135.                                                 }

  136.                                                 while(step==14)
  137.                                                 {
  138.                                                         Delay_ms(10);
  139.                                                 }

  140.                                         }
  141.                                 }
  142.                                 break;

  143.                         case 15:
  144.                                 break;  //备用
  145.                         case 16:
  146.                                 break;   //备用

  147.                 }
  148.         }
  149. }
复制代码
回复

使用道具 举报

17#
ID:65580 发表于 2024-4-24 09:48 | 只看该作者

谢谢!这样用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;
                                }

请教我怎么能实现此功能呢,麻烦给一个程序,谢谢!
回复

使用道具 举报

18#
ID:161164 发表于 2024-4-24 10:31 | 只看该作者
lss9310 发表于 2024-4-24 09:48
谢谢!这样用S1键模拟,达到同一个键按二次实现了设备的启动与停止。我的程序本意是通过485通信,主机接 ...

你一开始就说是485就不用浪费15天
回复

使用道具 举报

19#
ID:1109793 发表于 2024-4-24 10:59 | 只看该作者
lss9310 发表于 2024-4-24 09:48
谢谢!这样用S1键模拟,达到同一个键按二次实现了设备的启动与停止。我的程序本意是通过485通信,主机接 ...
  1. if(key_val==13){
  2.         key_val = 0;
  3.         s2 = !s2;
  4. }

复制代码
回复

使用道具 举报

20#
ID:344848 发表于 2024-4-24 14:45 | 只看该作者

使用D触发器搭建的一个电路便可以实现!
回复

使用道具 举报

21#
ID:344848 发表于 2024-4-24 14:52 | 只看该作者
单片机外围接一个D触发器,或使用CPLD搭建一个D触发器,接受485信号后,就可以实现上述功能。
回复

使用道具 举报

22#
ID:344848 发表于 2024-4-24 14:58 | 只看该作者
实际工程讲究快速和可靠,以最短的时间完成项目。
回复

使用道具 举报

23#
ID:1109793 发表于 2024-4-24 15:18 | 只看该作者
donglw 发表于 2024-4-24 14:45
使用D触发器搭建的一个电路便可以实现!

人家是要软件解决的
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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