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

標題: 單片機不使用外部中斷,如何LED顯示程序? [打印本頁]

作者: EHJUDSZ    時間: 2024-8-9 16:25
標題: 單片機不使用外部中斷,如何LED顯示程序?
我要實現的是按鍵按一下LED長亮,第二下顯示SOS信號,第三下LED熄滅,但是現在有時按第三下LED并不熄滅,我想是因為我的SOS顯示代碼沒有執行完,所以按鍵掃描不到,請問這個問題如何解決呢。下面是我的代碼# include <STC8.h>
# include <intrins.h>
sbit KEY = P3^5;
sbit LED = P3^4;
unsigned int num=0;
unsigned int LED_flag=0;
void Delay10ms()                //@24.000MHz
{
        unsigned char data i, j, k;

        i = 2;
        j = 56;
        k = 172;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}
void Delay200ms(void)        //@24.000MHz
{
        unsigned char data i, j, k;

        _nop_();
        _nop_();
        i = 25;
        j = 90;
        k = 176;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

void Delay500ms(void)        //@24.000MHz
{
        unsigned char data i, j, k;

        _nop_();
        _nop_();
        i = 61;
        j = 225;
        k = 62;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}
void Delay2000ms(void)        //@24.000MHz
{
        unsigned char data i, j, k;

        i = 244;
        j = 130;
        k = 4;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

void Init_IO()               
{
    P0M1 = 0x00;   P0M0 = 0x00;   
    P1M1 = 0x00;   P1M0 = 0x00;   
    P2M1 = 0x00;   P2M0 = 0x00;   
    P3M1 = 0x00;   P3M0 = 0x00;   
    P4M1 = 0x00;   P4M0 = 0x00;   
    P5M1 = 0x00;   P5M0 = 0x00;   
    P6M1 = 0x00;   P6M0 = 0x00;   
    P7M1 = 0x00;   P7M0 = 0x00;   
}
void display_sos()
{
        LED = 1;            
        Delay200ms();
        LED = 0;            
        Delay200ms();
        LED = 1;            
        Delay200ms();
        LED = 0;            
        Delay200ms();
        LED = 1;            
        Delay200ms();
        LED = 0;            
        Delay200ms();

        LED = 1;            
  Delay500ms();
        LED = 0;            
  Delay500ms();
        LED = 1;            
  Delay500ms();
        LED = 0;           
  Delay500ms();
        LED = 1;            
  Delay500ms();
        LED = 0;            
  Delay500ms();

        LED = 1;            
        Delay200ms();
        LED = 0;            
        Delay200ms();
        LED = 1;           
        Delay200ms();
        LED = 0;            
        Delay200ms();
        LED = 1;            
        Delay200ms();
        LED = 0;            
        Delay200ms();
        
        Delay2000ms();
}
void display()
{
        if(LED_flag==0)
        {
                LED=0;
        }
        else if(LED_flag==1)
        {
                LED=1;
        }
        else if(LED_flag==2)
        {
                while(LED_flag==2)
                {
                        display_sos();
                }        
        }
        else if(LED_flag==3)
        {
                LED=0;
        }
}        
void KeyScan()
{
        if(KEY == 0)
        {
                Delay10ms();                        
                if(KEY == 0)
                {
                        LED_flag++;
                        display();
                        if(LED_flag==3)
                        {
                                LED_flag=0;
                        }                        
                }
                while(!KEY);                                
        }
}
void main()
{
  LED = 0;
        Init_IO();
        while(1)
        {
                KeyScan();               
        }
}



作者: cedtek    時間: 2024-8-9 21:41
以下回答來自GPT-4o



作者: 1754232    時間: 2024-8-9 22:05
延時過多,這種造成單片機內部資源消耗一直延時你的SOS信號,這種沒什么太好的解決辦法,建議你學一下中斷函數吧
作者: ppcbug    時間: 2024-8-9 23:00
建議使用狀態機。
按鍵切換 狀態機的 狀態, 然后 用狀態去驅動 三個不同顯示函數。
這樣程序很清晰 , 模塊化 很強 .
作者: hy47566398    時間: 2024-8-9 23:11
死循環了:
        else if(LED_flag==2)
         {
                 while(LED_flag==2)              <----如何跳出這個循環的???
                 {
                         display_sos();
                 }        
         }
         else if(LED_flag==3)
作者: 想進步要學習    時間: 2024-8-10 08:58
/*
什么狀不狀態不態,太遠了。在你基礎上改了下,思路是沒問題的,代碼還沒測試過,你看看有沒有有沒有參考價值吧。
*/
sbit KEY = P3 ^ 5;
sbit LED = P3 ^ 4;
unsigned int num = 0;
unsigned int LED_flag = 0;
void Delay10ms()                //@24.000MHz
{
    unsigned char data i, j, k;

    i = 2;
    j = 56;
    k = 172;
    do
    {
        do
        {
            while (--k);
        }
        while (--j);
    }
    while (--i);
}

void Init_IO()
{
    P0M1 = 0x00;
    P0M0 = 0x00;
    P1M1 = 0x00;
    P1M0 = 0x00;
    P2M1 = 0x00;
    P2M0 = 0x00;
    P3M1 = 0x00;
    P3M0 = 0x00;
    P4M1 = 0x00;
    P4M0 = 0x00;
    P5M1 = 0x00;
    P5M0 = 0x00;
    P6M1 = 0x00;
    P6M0 = 0x00;
    P7M1 = 0x00;
    P7M0 = 0x00;
}
void display_sos(unsigned char state)
{
    static unsigned int cnt = 0;
    if (state == 0)
    {
        cnt = 0;
    }
/*
下面其實可以寫的漂亮點,用結構體數組for循環處理
*/
    if (cnt < 540)
    {
        cnt++;
    }  
    if (cnt < 20)
    {
        LED = 1;
    }
    else if (cnt < 40)
    {
        LED = 0;
    }
    else if (cnt < 60)
    {
        LED = 1;
    }
    else if (cnt < 80)
    {
        LED = 0;
    }
    else if (cnt < 100)
    {
        LED = 1;
    }
    else if (cnt < 120)
    {
        LED = 0;
    }
   
    else if (cnt < 170)
    {
        LED = 1;
    }
    else if (cnt < 220)
    {
        LED = 0;
    }
    else if (cnt < 270)
    {
        LED = 1;
    }
    else if (cnt < 320)
    {
        LED = 0;
    }
    else if (cnt < 370)
    {
        LED = 1;
    }
    else if (cnt < 420)
    {
        LED = 0;
    }

    else if (cnt < 440)
    {
        LED = 1;
    }
    else if (cnt < 460)
    {
        LED = 0;
    }
    else if (cnt < 480)
    {
        LED = 1;
    }
    else if (cnt < 500)
    {
        LED = 0;
    }
    else if (cnt < 520)
    {
        LED = 1;
    }
    else if (cnt < 540)
    {
        LED = 0;
    }
}
void display()
{
    static unsigned char state = 0;
    if (LED_flag == 0)
    {
        LED = 0;
        state = 0;
    }
    else if (LED_flag == 1)
    {
        LED = 1;
        state = 0;
    }
    else if (LED_flag == 2)
    {
        display_sos(state);
        state = 1;
    }
    else if (LED_flag == 3)
    {
        LED = 0;
        state = 0;
    }
}

void KeyScan()
{
    static unsigned char last_key_state = 1;
    static unsigned char cnt = 0;   

    if (KEY != last_key_state)
    {
        if (++cnt >= 3)
        {
            if (last_key_state == 1)
            {
                if (++LED_flag >= 3)
                {
                    LED_flag = 0;
                }              
            }                        
            cnt = 0;
            last_key_state = KEY;
        }
    }
    else
    {
        cnt = 0;
    }
}
void main()
{
    LED = 0;
    Init_IO();
    while (1)
    {
        KeyScan();
        display();   
        Delay10ms();            
    }
}
作者: EHJUDSZ    時間: 2024-8-10 09:00
cedtek 發表于 2024-8-9 21:41
以下回答來自GPT-4o

您好,我下載您的程序之后發現SOS信號并不能實現(LED完全不亮),請問這是什么原因呀
作者: EHJUDSZ    時間: 2024-8-10 09:02
1754232 發表于 2024-8-9 22:05
延時過多,這種造成單片機內部資源消耗一直延時你的SOS信號,這種沒什么太好的解決辦法,建議你學一下中斷 ...

嗯嗯,感謝
作者: EHJUDSZ    時間: 2024-8-10 09:03
ppcbug 發表于 2024-8-9 23:00
建議使用狀態機。
按鍵切換 狀態機的 狀態, 然后 用狀態去驅動 三個不同顯示函數。
這樣程序很清晰 ,  ...

好的,感謝
作者: EHJUDSZ    時間: 2024-8-10 16:05
想進步要學習 發表于 2024-8-10 08:58
/*
什么狀不狀態不態,太遠了。在你基礎上改了下,思路是沒問題的,代碼還沒測試過,你看看有沒有有沒有參 ...

非常感謝您,參考您的代碼解決了我的問題
作者: lkc8210    時間: 2024-8-10 18:15
請善用主循環
  1. #include <STC8H.H>
  2. # include <intrins.h>
  3. sbit KEY = P3^5;
  4. sbit LED = P3^4;
  5. unsigned int num=0;
  6. unsigned int LED_flag=0;
  7. void Delay10ms()                //@24.000MHz
  8. {
  9.         unsigned char data i, j, k;

  10.         i = 2;
  11.         j = 56;
  12.         k = 172;
  13.         do
  14.         {
  15.                 do
  16.                 {
  17.                         while (--k);
  18.                 }
  19.                 while (--j);
  20.         }
  21.         while (--i);
  22. }

  23. void Init_IO()
  24. {
  25.         P3M1 = 0x00;
  26.         P3M0 = 0x00;
  27. }
  28. void display_sos()
  29. {
  30.         static unsigned char Step=0, delay=0,repeat = 0;
  31.         if(Step==0)
  32.         {
  33.                 LED = 1;
  34.                 repeat = 6;               
  35.                 Step= 1;
  36.         }
  37.         if(Step==1)
  38.         {
  39.                 if(++delay>=20)
  40.                 {
  41.                         delay=0;
  42.                         repeat--;
  43.                         if(repeat==0)
  44.                         {
  45.                                 Step=2;
  46.                                 repeat = 6;
  47.                         }else{
  48.                                 if(LED)
  49.                                         LED=0;
  50.                                 else
  51.                                         LED=1;                               
  52.                         }
  53.                        
  54.                 }
  55.         }
  56.         if(Step==2)
  57.         {
  58.                 if(++delay>=50)
  59.                 {
  60.                         delay=0;
  61.                         repeat--;
  62.                         if(repeat==0)
  63.                         {
  64.                                 Step=3;
  65.                                 LED=0;
  66.                         }else{
  67.                                 if(LED)
  68.                                         LED=0;
  69.                                 else
  70.                                         LED=1;                               
  71.                         }
  72.                 }
  73.         }
  74.         if(Step==3)
  75.         {
  76.                 if(++delay>=200)
  77.                 {
  78.                         Step=0;
  79.                         delay=0;
  80.                 }
  81.         }
  82.         Delay10ms();
  83. }
  84. void display()
  85. {
  86.         if(LED_flag==0)
  87.         {
  88.                 LED=0;
  89.         }
  90.         else if(LED_flag==1)
  91.         {
  92.                 LED=1;
  93.         }
  94.         else if(LED_flag==2)
  95.         {
  96.                 display_sos();
  97.         }
  98. }
  99. void KeyScan()
  100. {
  101.         if(KEY == 0)
  102.         {
  103.                 Delay10ms();
  104.                 if(KEY == 0)
  105.                 {
  106.                         LED_flag++;
  107.                         if(LED_flag==3)
  108.                         {
  109.                                 LED_flag=0;
  110.                         }
  111.                 }
  112.                 while(!KEY);
  113.         }
  114. }
  115. void main()
  116. {
  117.         LED = 0;
  118.         Init_IO();
  119.         while(1)
  120.         {
  121.                 display();
  122.                 KeyScan();
  123.         }
  124. }
復制代碼




作者: wjfw    時間: 2024-8-10 23:30
太復雜了。
計算按鍵次數保存在R0,然后判斷R0=1,2,3去執行相應的動作即可
作者: wjfw    時間: 2024-8-11 20:29
;==================================
;----不用中斷,按一次LED亮,按兩次SOS,按三次LED滅,按四次全滅
;==================================
;====淄博金峰電子科技==============
     ORG   0000H
;====初始化========================
     MOV   R0,  #00H
     MOV   P1,  #0FFH
     MOV   P3,  #0FFH
     K1    EQU  P3.0  ;定義P3.0為K1
     LED   EQU  P1.0  ;定義P1.0為LED
     SOS   EQU  P1.3  ;定義P1.3為SOS
;====主程序=========================
MAIN:
     JNB   K1,  JIA
     LCALL OUT
     JMP   MAIN
;====記錄按鍵次數程序=============
JIA:
     LCALL DELAY
     JNB   K1,$
     LCALL DELAY
     INC   R0
     LJMP  MAIN
;====輸出子程序===================   
OUT:
     MOV  A,R0
OUT1:   
     CJNE A,#01,OUT2
     CLR  LED
     RET
OUT2:
     CJNE A,#02,OUT3
     CLR  SOS
     RET
OUT3:
     CJNE A,#03,OUT4
     SETB LED
     RET
OUT4:
     CJNE A,#04,OUT5
OUT5:     
     SETB SOS
     MOV  R0,#00H
     RET   
;====延時子程序=====================
DELAY:
     MOV  R6,#255
L1: MOV  R7,#248
     DJNZ R7,$
     DJNZ R6,L1
     RET   
END 按3次.rar (3.81 KB, 下載次數: 1)
作者: wjfw    時間: 2024-8-11 20:52
使用匯編形成的代碼很小的

作者: xrba    時間: 2024-8-11 23:16
你的DELAY延時太長了,有200ms,甚至500ms,在延時過程中是不能處理按鍵的。
作者: xrba    時間: 2024-8-11 23:21
你的DELAY延時時間太長了,200ms已經很長了,還有500ms的。
有兩種解決方案:
一、放棄延時,用定時器中斷計數,比如1ms觸發一次,主循環中識別按鍵,識別計數值,計數達到設定時間后,顯示下一個內容。此方案的優點是定時精度高,缺點是你需要管理多個狀態變量,我的程序都是用的這種方式;
二、將延時切割小,用循環控制延時時間,在循環中調用按鍵識別程序。此方案程序修改量小,但是定時的精度會有影響。

作者: xianfajushi    時間: 2024-8-12 20:09
典型的阻塞延時造成的案例,解決方案有放棄阻塞延時,改用詢問延時,改用中斷延時。




歡迎光臨 (http://m.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 在线亚洲精品 | 国产精品成人一区二区三区 | 日韩精品久久久久久久酒店 | 精品日韩av| 97精品国产露脸对白 | 免费观看a级片 | 91av在线免费观看 | 狠狠干婷婷 | 亚洲h网站 | 免费的黄色网址 | 日韩精品一区二区三区免费视频 | 天天干夜夜 | 午夜激情视频在线观看 | 亚洲精品一区二区三区蜜桃久 | 国产成人av网站 | 综合一区二区三区 | 大桥未久在线视频 | 国产性生活| 亚洲国产网站 | 在线观看91 | 日韩在线观看一区 | 欧美在线一区二区 | 精品一区二区在线播放 | 日韩不卡在线观看 | 欧美激情在线播放 | 国产精品免费一区二区三区 | 日本中文字幕网站 | 黄色片视频 | 免费一级a毛片 | 免费在线观看毛片 | 特级特黄aaaa免费看 | 久久久久久久国产 | 一区二区三区四区视频在线观看 | 天天天天躁天天爱天天碰2018 | 国产成人影视 | 亚洲精品乱码久久久久 | 欧美激情xxx | 色哥网 | 91欧美日韩 | 国产超碰人人模人人爽人人添 | 久久免费精品 |