找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

51单片机四个按键控制四个功能,求C语言程序编写思路

查看数: 4480 | 评论数: 9 | 收藏 1
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2020-10-5 10:32

正文摘要:

本帖最后由 武。。。。 于 2020-10-5 16:07 编辑 按下按键一后(短按),8个led灯全部亮(死循环);按下按键二后,8个led灯进行流水(死循环);按下按键三后,8个led灯同时做呼吸(2秒亮,4秒暗)(利用pwm占空 ...

回复

ID:613250 发表于 2020-10-13 15:09
daemondong 发表于 2020-10-9 19:15
呼吸死在 140行            while(1);
修改如下:
1. 去掉 140行

我试着那样去仿真,发现按了呼吸灯的按键后就无法按其他按键了,会一直停留在呼吸灯那里。
ID:798631 发表于 2020-10-9 21:51
呼吸比较好实现  定时器中断里面做10毫秒时基,计数延时  ,灯也加上闪烁秒计数2之前亮 到6灭灯清0  就好了   
ID:827243 发表于 2020-10-9 19:15
呼吸死在 140行            while(1);
修改如下:
1. 去掉 140行
2.  110行 case 3 如下
case 3: //led灯进行闪烁
huxi();
break;
ID:827215 发表于 2020-10-9 18:48
这种情况下我就不想用定时器了,当然,用定时器延时ok的。既然是51,直接读取按键对应口,根据读取到的值执行不同的程序。所以写四个现象的函数,然后根据IO口读取条件调用
ID:275826 发表于 2020-10-7 08:54
武。。。。 发表于 2020-10-7 00:46
你好,请问您的呼吸灯部分是亮两秒暗四秒吗?

上面例程是各一秒左右,修改下参数很容易实现的
ID:613250 发表于 2020-10-7 00:46
tyrl800 发表于 2020-10-6 10:10
#include #define uchar unsigned char #define uint unsigned int #define Kport  P3 #define Ledport  P1 ...

你好,请问您的呼吸灯部分是亮两秒暗四秒吗?
ID:451718 发表于 2020-10-6 14:28
//***********硬件底层定义**************
#define K1                    P14
#define K2                    P15
#define K3                    P16
#define K4                    P17

//***********软件层定义*************
#define KEY1_PRES                        1        //KEY1按下
#define KEY2_PRES                        2        //KEY2按下
#define KEY3_PRES                        3        //KEY3按下
#define KEY4_PRES                        4        //KEY4按下
#define KEY5_PRES                        5        //KEY3和KEY4同时按下   扩展用


//***********按键检测函数**************

unsigned char Key_Scan(unsigned char mode)
{
        static unsigned char Key_Up = 1; //按键按松开标志

        if(mode)        //支持连按
        {
                Key_Up = 1;       
        }
        if(Key_Up && (K1==0 || K2==0 || K3==0 || K4==0))
        {
               
                Key_Up = 0;
               
                if(K1 == 0)
                        return KEY1_PRES;
                else if(K2 == 0)
                        return KEY2_PRES;
                else if(K3 == 0 && K4 == 0)
                        return KEY5_PRES;
                else if(K3 == 0)
                        return KEY3_PRES;
                else if(K4 == 0)
                        return KEY4_PRES;

        }
        else if(K1 == 1 && K2 == 1 && K3 == 1 && K4 == 1)
        {
                Key_Up = 1;
        }
               
        return 0; //无按键按下
       
}

//*************按键处理函数****************

Key_Deal()
{
      
      key = Key_Scan(1);           //key外部变量,  1:支持连按, 0:不支持连按,

      switch(key)
      {
           case 1:
                 KeyFlag = 1;      //KeyFlag 外部变量
           break;
           case 2:
                 KeyFlag = 2;
           break;
           case 3:
                 KeyFlag = 3;
           break;
           case 4:
                //关定时器,熄灯;
           break;
           default:
               
           break;
      }
}

main()
{
      Key_Deal();
      switch(KeyFlag)
      {
           case 1:
                 //关定时器
                 //全亮操作
           break;
           case 2:
                 //关定时器
                 //跑马灯操作
           break;
           case 3:
                 //呼吸灯,开定时器;
           break;
      }
}
ID:451718 发表于 2020-10-6 14:04
你的呼吸灯是通过定时器实现的,开启后,定时器会常态一直工作,当键值改变后,你有判断后去改变 “ET0 = 0; 或者 EA = 0;”操作么?
ID:275826 发表于 2020-10-6 10:10
#include<reg52.h> #define uchar unsigned char #define uint unsigned int #define Kport  P3 #define Ledport  P1 uchar code table0[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//LED从低位往高位移 unsigned char kscancnt;        //记录进入中断的次数,满一个周期清零  void timer0_init();                        //定时器0初始化 void delayMS(uint x);           //延时函数 void KeyProcess(uchar Key);         //按键处理函数 bit flag; uchar knum; uint F3cnt,F2cnt,Pwmcnt,T0cnt; uchar temp=0xff,temp1; uchar sh_cnt; //延时函数 void delayMS(uint x) {     uchar i;     while (x--)        for(i=0;i<120; i++) ; } /*************************************************** *                                定时器0初始化子函数 *                        工作方式2,每1000us中断一次 ****************************************************/ void timer0_init(void) {         TMOD = 0x01;                //采用定时器0,工作方式2,         TH0 = (65536-1000)/256;                         //定时器设置,每隔20us发起一次中断。         TL0 = (65536-1000)%256;                   ET0 = 1;                        //开定时器0中断         EA = 1;                                 //开总中断         TR0 = 1;                        //打开定时器 }  //检测按键  uchar GetKey(uchar kscancnt)  {      uchar ktmp;     if(kscancnt==0)          {           temp=(Kport&0xf0)>>4;           ktmp=~temp &(temp1);           if(ktmp)knum=ktmp;           temp1=temp;          }    return knum;  }  //键盘按键处理  void KeyProcess(uchar Key)   {        switch (Key)          {            case 1:Ledport=0x00;                                                 break;                             case 2:if(F2cnt==200){sh_cnt=++sh_cnt%8;F2cnt=0;}                           Ledport=table0[sh_cnt];                       break;            case 4:if(T0cnt==300)                     {F3cnt=F3cnt+10;T0cnt=0;}                           if(F3cnt==130){F3cnt=0;flag=!flag;}                   Pwmcnt=++Pwmcnt%100;                            if(flag)                             {if(Pwmcnt>F3cnt)Ledport=0x00;else Ledport=0xff;}                           else                             {if(Pwmcnt>F3cnt)Ledport=0xff;else Ledport=0x00;}                   break;             case 8:Ledport=0xff; //全部关闭                           break;          }  }  /*************************************************** *               中断服务子函数 *****************************************************/ void time0(void) interrupt 1 {     TH0 = (65536-1000)/256;                         //定时器设置,每隔20us发起一次中断。     TL0 = (65536-1000)%256;           kscancnt=++ kscancnt%10;         if(knum==2)         {F2cnt++; }     if(knum==4)         {T0cnt++; } }   //--------------------------------------------------------------------  void main(void)  {           uchar Key;         P0=P1=0xFF;         timer0_init();         while(1)                    {                  Key=GetKey(kscancnt);                  KeyProcess(Key);                                  } }

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

Powered by 单片机教程网

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