久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4305|回復(fù): 9
打印 上一主題 下一主題
收起左側(cè)

51單片機四個按鍵控制四個功能,求C語言程序編寫思路

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:613250 發(fā)表于 2020-10-5 10:32 來自手機 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
50黑幣
本帖最后由 武。。。。 于 2020-10-5 16:07 編輯

按下按鍵一后(短按),8個led燈全部亮(死循環(huán));按下按鍵二后,8個led燈進行流水(死循環(huán));按下按鍵三后,8個led燈同時做呼吸(2秒亮,4秒暗)(利用pwm占空比);按下按鍵四后,全部關(guān)閉。
原理圖如下:


求大神指導(dǎo)程序,給個思路.
ps:下面是我自己寫的代碼,但是在呼吸燈那里出了點問題,按了呼吸燈就無法按其他按鍵,無法退出循環(huán)。請各路大神指點迷津,幫忙寫出更好的代碼或修改一下代碼。
  1. #include<reg52.h>

  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. uchar code table0[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//LED從低位往高位移
  5. unsigned char ZHOUQI_COUNT;        //記錄進入中斷的次數(shù),滿一個周期清零
  6. unsigned char PWM_VLAUE;        //存儲當(dāng)前高電平對應(yīng)的定時次數(shù)
  7. unsigned int UPDATA_COUNT;        //占空比更新時間

  8. bit direc_flag;                                //占空比更新方向 0增加,1減少


  9. void timer0_init();                        //定時器0初始化
  10. void delayMS(uint x);           //延時函數(shù)
  11. void KeyProcess(uchar Key);         //按鍵處理函數(shù)
  12. void huxi();               //呼吸燈函數(shù)
  13. uchar GetKey();             //檢測按鍵


  14. //延時函數(shù)
  15. void delayMS(uint x)
  16. {
  17.     uchar i;

  18. while (x--)
  19. for(i=0;i<120; i++) ;
  20. }
  21. /***************************************************
  22. *                                定時器0初始化子函數(shù)
  23. *                        工作方式2,每20us中斷一次
  24. ****************************************************/
  25. void timer0_init()
  26. {
  27.         TMOD = 0x02;                //采用定時器0,工作方式2,
  28.         TH0 = 0XED;                         //定時器設(shè)置,每隔20us發(fā)起一次中斷。
  29.         TL0 = 0XED;         
  30.         ET0 = 1;                        //開定時器0中斷
  31.         EA = 1;                                 //開總中斷
  32.         TR0 = 1;                        //打開定時器
  33. }

  34. //檢測按鍵

  35. uchar GetKey()

  36. {

  37. uchar k;
  38. if(P1==0xFF)
  39. return 0;

  40. delayMS(10);

  41. switch (P1)

  42. {

  43. case 0xEF: k=1;break;

  44. case 0xDF: k=2;break;

  45. case 0xBF: k=3;break;

  46. case 0x7F: k=4;break;

  47. default: k=0;

  48. }
  49. while (P1 != 0xFF);//等待釋放按鍵(釋放按鍵時退出循環(huán))


  50. return k;
  51. }
  52. //鍵盤按鍵處理


  53. void KeyProcess(uchar Key)

  54. {
  55. int i;

  56. switch (Key)

  57. {

  58. case 1://led燈全部點亮
  59. while(1)
  60. {
  61. P0=0x00;
  62. if (P1 == 0xDF||P1 == 0xBF||P1 == 0x7F)
  63. break;//等待釋放按鍵(釋放按鍵時退出循環(huán))
  64. }

  65. break;

  66. case 2://以流水燈形式點亮
  67. while(1)
  68. {
  69. for(i=0;i<8;i++)
  70. {
  71. P0=table0[i];
  72. delayMS(100);
  73. }
  74. if (P1 == 0xEF||P1 == 0xBF||P1 == 0x7F)
  75. break;//等待釋放按鍵(釋放按鍵時退出循環(huán))
  76. }

  77. break;
  78. case 3: //led燈進行閃爍
  79. if(Key==3)
  80. while(1)
  81. {
  82. huxi();
  83. if (P1 == 0xEF||P1 == 0xDF||P1 == 0x7F)
  84.       break;//等待釋放按鍵(釋放按鍵時退出循環(huán))
  85. }
  86.   break;
  87. case 4://全部關(guān)閉
  88. while(1)
  89. {
  90. P0=0xff;
  91. if (P1 == 0xEF||P1 == 0xDF||P1 == 0xBF)
  92. break;//等待釋放按鍵(釋放按鍵時退出循環(huán))
  93. }

  94. break;
  95. }

  96. }
  97. //呼吸燈啟動函數(shù)
  98. void huxi()
  99. {
  100.         UPDATA_COUNT = 0;
  101.         ZHOUQI_COUNT = 0;
  102.         PWM_VLAUE = 50;//占空比50%,
  103.         direc_flag = 0;
  104.         P0 = 0xff;                        //默認(rèn)LED熄滅       
  105.         timer0_init();                //定時器0初始化
  106.         while(1);
  107. }
  108. /***************************************************
  109. *                                中斷服務(wù)子函數(shù)
  110. *                         判斷何時該輸出高低電平
  111. ****************************************************/
  112. void time0() interrupt 1
  113. {
  114.         ZHOUQI_COUNT++;       //周期累加
  115.         UPDATA_COUNT++;       //占空比更新時間累加
  116.         if(ZHOUQI_COUNT == PWM_VLAUE)                //判斷是否到了點亮LED的時候
  117.                 P0 = 0x00;                                        //點亮LED
  118.         if(ZHOUQI_COUNT == 100)                                //當(dāng)前周期結(jié)束
  119.         {
  120.                 P0 = 0xff;                                        //熄滅LED
  121.                 ZHOUQI_COUNT = 0;                                //重新計時
  122.         }
  123.         if((UPDATA_COUNT == 5000) && (direc_flag == 0))
  124.         {                                                                   //占空比增加2%
  125.                 UPDATA_COUNT = 0;
  126.                 PWM_VLAUE=PWM_VLAUE+2;
  127.                 if(PWM_VLAUE == 90)                        //占空比更改方向
  128.                         direc_flag = 1;       
  129.         }
  130.         if((UPDATA_COUNT == 5000) && (direc_flag == 1))
  131.         {                                                                //占空比減少1%
  132.                 UPDATA_COUNT = 0;
  133.                 PWM_VLAUE--;
  134.                 if(PWM_VLAUE == 50)                        //占空比更改方向
  135.                         direc_flag = 0;       
  136.         }       
  137. }

  138. //主程序

  139. //--------------------------------------------------------------------

  140. void main()

  141. {

  142. uchar Key;

  143. P0=P1=0xFF;

  144. while(1)

  145. {

  146. Key=GetKey();

  147. if(Key!=0)  KeyProcess(Key);

  148. }

  149. }
復(fù)制代碼



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:275826 發(fā)表于 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;        //記錄進入中斷的次數(shù),滿一個周期清零  void timer0_init();                        //定時器0初始化 void delayMS(uint x);           //延時函數(shù) void KeyProcess(uchar Key);         //按鍵處理函數(shù) bit flag; uchar knum; uint F3cnt,F2cnt,Pwmcnt,T0cnt; uchar temp=0xff,temp1; uchar sh_cnt; //延時函數(shù) void delayMS(uint x) {     uchar i;     while (x--)        for(i=0;i<120; i++) ; } /*************************************************** *                                定時器0初始化子函數(shù) *                        工作方式2,每1000us中斷一次 ****************************************************/ void timer0_init(void) {         TMOD = 0x01;                //采用定時器0,工作方式2,         TH0 = (65536-1000)/256;                         //定時器設(shè)置,每隔20us發(fā)起一次中斷。         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; //全部關(guān)閉                           break;          }  }  /*************************************************** *               中斷服務(wù)子函數(shù) *****************************************************/ void time0(void) interrupt 1 {     TH0 = (65536-1000)/256;                         //定時器設(shè)置,每隔20us發(fā)起一次中斷。     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);                                  } }
回復(fù)

使用道具 舉報

板凳
ID:451718 發(fā)表于 2020-10-6 14:04 | 只看該作者
你的呼吸燈是通過定時器實現(xiàn)的,開啟后,定時器會常態(tài)一直工作,當(dāng)鍵值改變后,你有判斷后去改變 “ET0 = 0; 或者 EA = 0;”操作么?
回復(fù)

使用道具 舉報

地板
ID:451718 發(fā)表于 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同時按下   擴展用


//***********按鍵檢測函數(shù)**************

unsigned char Key_Scan(unsigned char mode)
{
        static unsigned char Key_Up = 1; //按鍵按松開標(biāo)志

        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; //無按鍵按下
       
}

//*************按鍵處理函數(shù)****************

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:
                //關(guān)定時器,熄燈;
           break;
           default:
               
           break;
      }
}

main()
{
      Key_Deal();
      switch(KeyFlag)
      {
           case 1:
                 //關(guān)定時器
                 //全亮操作
           break;
           case 2:
                 //關(guān)定時器
                 //跑馬燈操作
           break;
           case 3:
                 //呼吸燈,開定時器;
           break;
      }
}
回復(fù)

使用道具 舉報

5#
ID:613250 發(fā)表于 2020-10-7 00:46 來自手機 | 只看該作者
tyrl800 發(fā)表于 2020-10-6 10:10
#include #define uchar unsigned char #define uint unsigned int #define Kport  P3 #define Ledport  P1 ...

你好,請問您的呼吸燈部分是亮兩秒暗四秒嗎?
回復(fù)

使用道具 舉報

6#
ID:275826 發(fā)表于 2020-10-7 08:54 | 只看該作者
武。。。。 發(fā)表于 2020-10-7 00:46
你好,請問您的呼吸燈部分是亮兩秒暗四秒嗎?

上面例程是各一秒左右,修改下參數(shù)很容易實現(xiàn)的
回復(fù)

使用道具 舉報

7#
ID:827215 發(fā)表于 2020-10-9 18:48 | 只看該作者
這種情況下我就不想用定時器了,當(dāng)然,用定時器延時ok的。既然是51,直接讀取按鍵對應(yīng)口,根據(jù)讀取到的值執(zhí)行不同的程序。所以寫四個現(xiàn)象的函數(shù),然后根據(jù)IO口讀取條件調(diào)用
回復(fù)

使用道具 舉報

8#
ID:827243 發(fā)表于 2020-10-9 19:15 | 只看該作者
呼吸死在 140行            while(1);
修改如下:
1. 去掉 140行
2.  110行 case 3 如下
case 3: //led燈進行閃爍
huxi();
break;
回復(fù)

使用道具 舉報

9#
ID:798631 發(fā)表于 2020-10-9 21:51 | 只看該作者
呼吸比較好實現(xiàn)  定時器中斷里面做10毫秒時基,計數(shù)延時  ,燈也加上閃爍秒計數(shù)2之前亮 到6滅燈清0  就好了   
回復(fù)

使用道具 舉報

10#
ID:613250 發(fā)表于 2020-10-13 15:09 | 只看該作者
daemondong 發(fā)表于 2020-10-9 19:15
呼吸死在 140行            while(1);
修改如下:
1. 去掉 140行

我試著那樣去仿真,發(fā)現(xiàn)按了呼吸燈的按鍵后就無法按其他按鍵了,會一直停留在呼吸燈那里。
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产一区2区| 国产精品久久久久久久免费观看 | 日韩欧美理论片 | 一区二区不卡高清 | 精品区 | 久久51| 亚洲网在线 | 奇米影视在线 | 久久久久国产精品一区 | 精品国产免费人成在线观看 | 欧美亚洲国产一区 | 亚洲精品一区二区三区在线观看 | 亚洲一区二区av | 国产精品高潮呻吟久久久久 | 久久av一区二区三区 | 天天在线操 | 天天色图| 成人性视频免费网站 | 给我免费的视频在线观看 | 精品久久久精品 | 国产精品极品美女在线观看免费 | 国产乱肥老妇国产一区二 | 成人精品国产 | 日本一区二区三区四区 | 亚洲精品视频免费 | 免费黄色的网站 | 亚洲韩国精品 | 国产不卡一区 | 日本久久网 | 国产精品久久亚洲 | 色吊丝2 | 成人亚洲精品久久久久软件 | 高清视频一区二区三区 | 亚洲国产精品久久 | a级免费视频 | 午夜视频在线 | 国产免费一级一级 | 91伊人| 国产羞羞视频在线观看 | www一级片 | 狠狠色综合欧美激情 |