找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 757|回复: 17
收起左侧

关于51单片机一个按键分别控制两个LED灯闪烁C程序

[复制链接]
ID:384552 发表于 2023-11-23 20:02 | 显示全部楼层 |阅读模式
求助51单片机一个按键分别控制两个LED灯闪烁C程序,一个按键短按一下LED1灯闪亮,再短按一下LED1灭,长按一下LED2灯闪亮,再短按一下LED2灭,谢谢。
51单片机.PNG
回复

使用道具 举报

ID:195496 发表于 2023-11-24 08:17 | 显示全部楼层
难倒了小白,我是没有时间写,你加上几个标志就可以把完整的程序流程写出来。
回复

使用道具 举报

ID:275826 发表于 2023-11-24 09:06 | 显示全部楼层
uchar bdata flag_key_byte=0xff;
  sbit keyflag=flag_key_byte^0;
  sbit keyflag1=flag_key_byte^1;
  /**********************************************************/
void keyscan(void)
   {
    keyflag1=keyflag;
        keyflag=Key;

        switch(flag_key_byte&0x03)
          {
           case 0:cnt++;break;
           case 2:cnt++;break;
           case 1:if(cnt>30)kv=2;
                     else if(cnt>5)kv=1;
                  else kv=0;
                  cnt=0;
                  flag_key_byte=0xff; break;
          }
          
         }
  /**********************************************************/
回复

使用道具 举报

ID:161164 发表于 2023-11-24 09:17 | 显示全部楼层
如果LED1,2都亮的情况下再短按会如何?
回复

使用道具 举报

ID:123289 发表于 2023-11-24 09:59 | 显示全部楼层
先做出:弹动、长按、短按 的识别方法!
要点:做一个计数器CJ来判定弹动、长按与短按,CJ的规则如下:
1、CJ计数只发生于定时器的中断服务程序中,每次中断+1,计满不再计,即不回0。
2、CJ计数只发生于键按下的时候,未按下不计。
3、做一个键状态判定触发标记:B_OK,如果键未按下,但CJ<>0【弹起】,则置B_OK=1,表示是判断键状态的时候了。【弹起起效】
4、当B_OK=1,判断键状态的界定法则是:CJ<某个值为弹动;CJ<某个值为短按;CJ>某个值为长按,某个值是多少由你决定。建议事先将长短两个界定值放置在某个寄存器中,这样可以随意变更界定值。
5、状态界定完成后将:B_OK清0、CJ清0以备下次再界定。
回复

使用道具 举报

ID:584814 发表于 2023-11-24 10:18 | 显示全部楼层
tyrl800 发表于 2023-11-24 09:06
uchar bdata flag_key_byte=0xff;
  sbit keyflag=flag_key_byte^0;
  sbit keyflag1=flag_key_byte^1;
...

怎么看switch(flag_key_byte&0x03)只会出一个结果呢
回复

使用道具 举报

ID:123289 发表于 2023-11-24 10:33 | 显示全部楼层
做出以下三个变量:
1、闪动变量FL:在定时器中断服务程序中,每0.4秒FL求反一次。
2、长按变量CA:界定出长按时,让CA =1。
3、短按变量DA:界定出短按时,让DA = !DA。
输出这样写就可以达成目的了:
LED1 = DA * FL
LED2 = CA * FL * DA
回复

使用道具 举报

ID:275826 发表于 2023-11-24 11:08 | 显示全部楼层
man1234567 发表于 2023-11-24 10:18
怎么看switch(flag_key_byte&0x03)只会出一个结果呢

3种结果,0,1,2;1短,2长,0 无
回复

使用道具 举报

ID:384552 发表于 2023-11-24 12:47 | 显示全部楼层
tyrl800 发表于 2023-11-24 09:06
uchar bdata flag_key_byte=0xff;
  sbit keyflag=flag_key_byte^0;
  sbit keyflag1=flag_key_byte^1;
...

我是个小白,这个程序不完整,麻烦补充一下子呗,谢谢
回复

使用道具 举报

ID:332444 发表于 2023-11-24 14:27 | 显示全部楼层
今天回复了一个类似短按和长按的荔枝
[按键控制数码管加减显示
编写程序,在数码管上显示000-255范围内的任意整数。具体要求是:K1按下后加1计数,K2按下后减1计数,K3按下后清零,而且,在不松开按键时,数字会按一定时间间隔持续递增或递减。(1)画出电路图;(2)写出源程序代码并进行仿真。求帮]

1.gif
回复

使用道具 举报

ID:275826 发表于 2023-11-24 15:47 | 显示全部楼层
QDMLIT 发表于 2023-11-24 12:47
我是个小白,这个程序不完整,麻烦补充一下子呗,谢谢

#include <reg51.h>
  #include <intrins.h>
  #define uchar unsigned char
  #define uint  unsigned int
  sbit Key =P3^7;
  uchar cnt,kv;
  sbit led1=P1^0;
  sbit led2=P1^1;
  bit bit_10ms=0;
  uchar bdata flag_key_byte=0xff;
  sbit keyflag=flag_key_byte^0;
  sbit keyflag1=flag_key_byte^1;
  /**********************************************************/
void keyscan(void)
   {
    keyflag1=keyflag;
        keyflag=Key;

        switch(flag_key_byte&0x03)
          {
           case 0:cnt++;break;
           case 2:cnt++;break;
           case 1:if(cnt>30)kv=2;
                     else if(cnt>5)kv=1;
                  else kv=0;
                  cnt=0;
                  flag_key_byte=0xff; break;
          }
       
         }
  /**********************************************************/
void main()
   {
         
         TH0=(65536-20000)/256;
     TL0=(65536-20000)%256;
         TMOD=0X01;
         ET0=EA=TR0=1;
          while(1)
            {
                 if(bit_10ms)
                   {keyscan();
                    bit_10ms=0;
                   }
                 if(kv==1) {led1=!led1;kv=0;}
                 if(kv==2) {led2=!led2;kv=0;}
                }
         }
  /**********************************************************/

   void DelayInt() interrupt 1
   {TH0=(65536-20000)/256;
    TL0=(65536-20000)%256;
        bit_10ms=1;
   }
  /**********************************************************/
回复

使用道具 举报

ID:384552 发表于 2023-11-24 19:16 | 显示全部楼层
tyrl800 发表于 2023-11-24 15:47
#include
  #include
  #define uchar unsigned char

您好,您的程序我仿真后是按键短按下LED1点亮,再短按LED1灭,LED1并没有闪烁,我这个实验是按键分别控制两个LED灯闪烁C程序,一个按键短按一下LED1灯闪亮,再短按一下LED1灭,长按一下LED2灯闪亮,再短按一下LED2灭,谢谢。
回复

使用道具 举报

ID:275826 发表于 2023-11-24 20:58 | 显示全部楼层
QDMLIT 发表于 2023-11-24 19:16
您好,您的程序我仿真后是按键短按下LED1点亮,再短按LED1灭,LED1并没有闪烁,我这个实验是按键分别控制 ...

#include <reg51.h>
  #include <intrins.h>
  #define uchar unsigned char
  #define uint  unsigned int
  sbit Key =P3^7;
  uchar cnt,flashcnt;
  sbit led1=P1^0;
  sbit led2=P1^1;
  bit bit_10ms=0,flag1,flag2;
  uchar bdata flag_key_byte=0xff;
  sbit keyflag=flag_key_byte^0;
  sbit keyflag1=flag_key_byte^1;
  /**********************************************************/
uchar keyscan(void)
   {uchar kv=0;
    keyflag1=keyflag;
        keyflag=Key;

        switch(flag_key_byte&0x03)
          {
           case 0:cnt++;break;
           case 2:cnt++;break;
           case 1:if(cnt>30)kv=2;
                     else if(cnt>5)kv=1;
                  else kv=0;
                  cnt=0;
                  flag_key_byte=0xff; break;
          }
          return kv;
         }
  /**********************************************************/
void main()
   {
         uchar kv=0;
         TH0=(65536-20000)/256;
     TL0=(65536-20000)%256;
         TMOD=0X01;
         ET0=EA=TR0=1;
          while(1)
            {
                 if(bit_10ms)
                   {kv=keyscan();
                    bit_10ms=0;
                    if(kv==1) {flag1=!flag1;}
                    if(kv==2) {flag2=!flag2;}
                        if(!flag1)  led1=1;
                    if(!flag2)  led2=1;
                        flashcnt++;
                        if(flashcnt==10)
                          {
                           flashcnt=0;
                           if(flag1) led1=!led1;
                       if(flag2) led2=!led2;
                          }
                   }

                }
         }
  /**********************************************************/

   void DelayInt() interrupt 1
   {TH0=(65536-20000)/256;
    TL0=(65536-20000)%256;
        bit_10ms=1;
   }
  /**********************************************************/
回复

使用道具 举报

ID:213173 发表于 2023-11-24 21:07 | 显示全部楼层
QDMLIT 发表于 2023-11-24 19:16
您好,您的程序我仿真后是按键短按下LED1点亮,再短按LED1灭,LED1并没有闪烁,我这个实验是按键分别控制 ...
  1. #include <REG51.H>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. #define key_S 3                                        //宏定义短按(约15ms)
  5. #define key_L key_S*40                        //宏定义长按(约600ms)

  6. sbit key =P3^5;
  7. sbit LED1=P1^0;
  8. sbit LED2=P1^1;

  9. uchar KeySec;//键值
  10. bit flashing=0;//闪烁标志

  11. //定时器初始化程序
  12. void Timer0Init(void)//5毫秒@12.000MHz
  13. {
  14.         TMOD |= 0x01;        //设置定时器模式
  15.         TL0 = 0x78;                //设置定时初始值
  16.         TH0 = 0xEC;                //设置定时初始值
  17.         TF0 = 0;                //清除TF0标志
  18.         TR0 = 1;                //定时器0开始计时
  19. }

  20. void keyscan()
  21. {
  22.         static unsigned int time=0;//计数变量
  23.         if(!key)//按键按下
  24.         {
  25.                 time++;
  26.                 if(time>=key_L && KeySec==0)//长按
  27.                 {
  28.                         KeySec=2;
  29.                 }
  30.         }
  31.         else                                //松手
  32.         {
  33.                 if(time>key_S && time<key_L)//短按
  34.                 {
  35.                         if(KeySec==0)KeySec=1;
  36.                         else if(KeySec==1)KeySec=0;
  37.                         else if(KeySec==2)KeySec=0;
  38.                 }
  39.                 time=0;
  40.         }
  41. }

  42. void display()//显示函数
  43. {
  44.         static uchar i=0;

  45.         if(++i>=50)
  46.         {
  47.                 i=0;
  48.                 flashing=~flashing;
  49.         }
  50.         if(KeySec==0)
  51.         {
  52.                 LED1=1;
  53.                 LED2=1;
  54.         }
  55.         if(KeySec==1)
  56.         {
  57.                 LED1=flashing;
  58.                 LED2=1;
  59.         }
  60.         if(KeySec==2)
  61.         {
  62.                 LED1=1;
  63.                 LED2=flashing;
  64.         }
  65. }

  66. void main()//主函数
  67. {
  68.         Timer0Init();//初始化定时器
  69.         while(1)
  70.         {
  71.                 if(TF0)//查询定时器中断请求位
  72.                 {
  73.                         TF0=0;
  74.                         TL0 = 0x78;                //设置定时初始值
  75.                         TH0 = 0xEC;                //设置定时初始值
  76.                         keyscan();                //按键扫描函数
  77.                         display();                //显示函数
  78.                 }
  79.         }
  80. }
复制代码
回复

使用道具 举报

ID:384552 发表于 2023-11-25 19:00 | 显示全部楼层
tyrl800 发表于 2023-11-24 20:58
#include
  #include
  #define uchar unsigned char

谢谢您辛苦付出
回复

使用道具 举报

ID:384552 发表于 2023-11-25 22:09 | 显示全部楼层

朋友谢谢您的辛苦付出
回复

使用道具 举报

ID:384552 发表于 2023-11-26 20:23 | 显示全部楼层

您好,在这个程序上改变LED闪烁时间怎么修改程序,如点亮2S,灭2秒,谢谢
回复

使用道具 举报

ID:213173 发表于 2023-11-27 05:51 | 显示全部楼层
QDMLIT 发表于 2023-11-26 20:23
您好,在这个程序上改变LED闪烁时间怎么修改程序,如点亮2S,灭2秒,谢谢

void display()//显示函数
{
        static uint i=0;

       if(++i>=400)
        {
                i=0;
                flashing=~flashing;
        }
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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