欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4221|回復: 16
打印 上一主題 下一主題
收起左側

單片機單鍵切換4模式 子程序跳不出循環問題

[復制鏈接]
跳轉到指定樓層
樓主
ID:128588 發表于 2020-3-4 22:08 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
編了一個單鍵控制一個led四個模式的程序,進入子程序之后,進入while(1)循環無法跳出。。。不怎么如何解決
請朋友們幫我改改(使用的是stc15w104單片機)

單片機源程序如下:
#include<reg52.h>
#define uchar unsigned char
uchar num;
sbit led=P3^1;
sbit S3=P3^0;

void delay(uchar i)
{
        uchar j,k;
        for(j=i;j>0;j--)
        for(k=125;k>0;k--);
}

void ledm1()
{
                                                        
        while(1)
        {
                        led=0;
                 delay(1000);
                 led=1;
                 delay(1000);
        }                    
}

void ledm2()
{
         while(1)
        {
                 led=0;
                 delay(2000);
                 led=1;
                 delay(2000);
         }                                 
}

void ledm3()
{                                                               
           while(1)
           {
                 led=0;
                 delay(3000);
                 led=1;
                 delay(3000);
             }

}

void ledm4()
{                                                                                
                 led=1;              
}

void main()
{
        while(1)
        {
                if(S3==0)
                {
                        delay(20);                 //消抖
                        if(S3==0)
                        {
                                while(!S3);         //等待按鍵松開
                                    if(num<4)
                                    num++;
                                    else
                                    num=1;
                        }
                        switch(num)
                        {
                                case 1: ledm1();num=1; break;
                                case 2: ledm2();num=2; break;
                                case 3: ledm3();num=3; break;
                                case 4: ledm4();num=4; break;
                                default: break;
                        }
                }
        }
}

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

使用道具 舉報

來自 9#
ID:213173 發表于 2020-3-5 10:12 | 只看該作者
樓主在子程序中使用了死循環,程序運行到此時再也出不來,再按按鍵也就無效了。所有程序都得在主循環 while(1)中跑起來,中斷除外。
另外還有兩處錯誤:
1.延時函數的參數數據類型要與實際應用相對應。
2.stc15w104是1T單片機,速度比普通51快許多,延時函數里的變量也要相應增量。
修改如下:
  1. #include<reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. sbit led=P3^1;
  5. sbit S3=P3^0;

  6. uchar num;
  7. uint num1;

  8. //1T單片機ms延時程序
  9. void delay(uint i)
  10. {
  11.         uint j,k;
  12.         for(j=i;j>0;j--)
  13.                 for(k=1150;k>0;k--);
  14. }
  15. /*
  16. //12T單片機ms延時程序
  17. void delay(uint i)
  18. {
  19.         uint j,k;
  20.         for(j=i;j>0;j--)
  21.                 for(k=125;k>0;k--);
  22. }
  23. */
  24. void main()
  25. {
  26.         while(1)
  27.         {
  28.                 if(S3==0)
  29.                 {
  30.                         delay(10);                 //消抖
  31.                         if(S3==0)
  32.                         {
  33.                                 while(!S3);         //等待按鍵松開
  34.                                 num++;
  35.                                 if(num>=4)
  36.                                         num=0;
  37.                         }
  38.                 }
  39.                 if(num==0)
  40.                 {
  41.                         led=1;
  42.                         num1=0;
  43.                 }
  44.                 else
  45.                         num1++;

  46.                 if(num1>num*1000)
  47.                 {
  48.                         num1=0;
  49.                         led=~led;
  50.                 }
  51.                 delay(1);
  52.         }
  53. }

復制代碼
回復

使用道具 舉報

沙發
ID:413383 發表于 2020-3-5 00:19 | 只看該作者
在子程序里不能用while(1)吧
回復

使用道具 舉報

板凳
ID:128588 發表于 2020-3-5 07:35 | 只看該作者
hulilanyua 發表于 2020-3-5 00:19
在子程序里不能用while(1)吧

是的  那我怎么讓子程序循環?
回復

使用道具 舉報

地板
ID:128588 發表于 2020-3-5 08:23 | 只看該作者
hulilanyua 發表于 2020-3-5 00:19
在子程序里不能用while(1)吧

那如何讓子程序循環
回復

使用道具 舉報

5#
ID:697917 發表于 2020-3-5 08:42 | 只看該作者
子函數中是用while(1),程序一旦進入就死在里面了。你把判斷按鍵是否放開放在子函數while中,不要用while(1)
回復

使用道具 舉報

6#
ID:679425 發表于 2020-3-5 08:54 | 只看該作者
break跳出循環操作能用不?
回復

使用道具 舉報

7#
ID:697884 發表于 2020-3-5 09:00 | 只看該作者
void ledm1()
{
                                                        
       // while(1)
        {
                        led=0;
                 delay(1000);
                 led=1;
                 delay(1000);
        }                    
}

void ledm2()
{
       //  while(1)
        {
                 led=0;
                 delay(2000);
                 led=1;
                 delay(2000);
         }                                 
}

void ledm3()
{                                                               
          // while(1)
           {
                 led=0;
                 delay(3000);
                 led=1;
                 delay(3000);
             }

}
把這些函數里面的while(1)都去掉就可以了。
回復

使用道具 舉報

8#
ID:462827 發表于 2020-3-5 09:41 | 只看該作者
幾個ledm跟數字的子函數中不要用循環了
回復

使用道具 舉報

10#
ID:342451 發表于 2020-3-5 10:14 | 只看該作者
要子程序循環,你就用最簡單的if判斷條件就好了,不用搞得那么麻煩
比如
while(1){
   if(按鍵){num++;}
   if(num == xx){執行什么}
   if(num == xx){執行什么}
... ...
}
就這么多,只要你的num不變,在主函數的while里就會一直執行if滿足條件下的語句,不就循環了,而且還不影響你按鍵切換
回復

使用道具 舉報

11#
ID:128588 發表于 2020-3-5 15:09 | 只看該作者
之一知足 發表于 2020-3-5 10:14
要子程序循環,你就用最簡單的if判斷條件就好了,不用搞得那么麻煩
比如
while(1){

這樣做的話  我試了  按鍵檢測就成了問題  比如說我子程序的執行的周期是2秒  按下按鍵的時候 得子程序周期結束才能識別key==0,怎么再增加按鍵識別頻率
回復

使用道具 舉報

12#
ID:128588 發表于 2020-3-5 15:11 | 只看該作者
黎明初至 發表于 2020-3-5 08:42
子函數中是用while(1),程序一旦進入就死在里面了。你把判斷按鍵是否放開放在子函數while中,不要用while(1 ...

那怎么讓子程序中的led一直循環閃爍?
回復

使用道具 舉報

13#
ID:128588 發表于 2020-3-5 15:19 | 只看該作者
本帖最后由 523503527 于 2020-3-5 15:49 編輯
wulin 發表于 2020-3-5 10:12
樓主在子程序中使用了死循環,程序運行到此時再也出不來,再按按鍵也就無效了。所有程序都得在主循環 while ...

謝謝,學到了。您編的我差不多看懂了,但是延時的這段,可以移植性不太強,譬如我想改延時 亮500ms,滅1000ms,或者其他沒有規律的,num1無法*1000的。能不能教我如何寫子程序?
回復

使用道具 舉報

14#
ID:128588 發表于 2020-3-5 19:13 | 只看該作者
wulin 發表于 2020-3-5 10:12
樓主在子程序中使用了死循環,程序運行到此時再也出不來,再按按鍵也就無效了。所有程序都得在主循環 while ...

謝謝大神。認真理解了你的編程。還想額外請教你一個問題,如果用子程序,思路該如何?比如子程序1是led1亮500,滅700,循環閃爍,這種無規律,沒辦法使用num1>num*1000判的
if(num==0)
                {
                        led=1;
                        num1=0;
                }
                else
                        num1++;

                if(num1>num*1000)
                {
                        num1=0;
                        led=~led;
                }
                delay(1);
        }
}

回復

使用道具 舉報

15#
ID:703117 發表于 2020-3-5 19:59 | 只看該作者
if(num==0)
                {
                        led=1;
                        num1=0;
                }
                else
                        num1++;

                if(num1>num*1000)
                {
                        num1=0;
                        led=~led;
                }
                delay(1);
        }
}
回復

使用道具 舉報

16#
ID:213173 發表于 2020-3-5 22:25 | 只看該作者
523503527 發表于 2020-3-5 19:13
謝謝大神。認真理解了你的編程。還想額外請教你一個問題,如果用子程序,思路該如何?比如子程序1是led1 ...

給你再改一下,按鍵不影響程序正常運行,循環閃爍用子程序任意設置周期和亮滅比。
  1. #include<reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. sbit led=P3^1;
  5. sbit S3=P3^0;

  6. uchar num;
  7. uchar count=0;        //計數延時
  8. bit   sign=0;        //按鍵自鎖標志

  9. //1T單片機ms延時程序
  10. void delay(uint i)
  11. {
  12.         uint j,k;
  13.         for(j=i;j>0;j--)
  14.                 for(k=1150;k>0;k--);
  15. }
  16. /*
  17. //12T單片機ms延時程序
  18. void delay(uint i)
  19. {
  20.         uint j,k;
  21.         for(j=i;j>0;j--)
  22.                 for(k=125;k>0;k--);
  23. }
  24. */
  25. void ledm1()
  26. {
  27.         static uint i=0;
  28.         i++;
  29.         if(i<=200)
  30.                 led=0;
  31.         if(i>200)
  32.                 led=1;
  33.         if(i>400)
  34.                 i=0;
  35. }
  36. void ledm2()
  37. {
  38.         static uint i=0;
  39.         i++;
  40.         if(i<=100)
  41.                 led=0;
  42.         if(i>100)
  43.                 led=1;
  44.         if(i>300)
  45.                 i=0;
  46. }
  47. void ledm3()
  48. {
  49.         static uint i=0;
  50.         i++;
  51.         if(i<=400)
  52.                 led=0;
  53.         if(i>400)
  54.                 led=1;
  55.         if(i>600)
  56.                 i=0;
  57. }

  58. void main()
  59. {
  60.         while(1)
  61.         {
  62.                 if(!S3)//鍵按下
  63.                 {
  64.                         if(++count>=10 && sign==0)//消抖與自鎖
  65.                         {
  66.                                 sign=1;
  67.                                 num++;
  68.                                 if(num>=4)
  69.                                         num=0;
  70.                         }
  71.                 }
  72.                 else //鍵松手
  73.                 {
  74.                         count=0;
  75.                         sign=0;       
  76.                 }
  77.                 switch(num)
  78.                 {
  79.                         case 0:  led=1;   break;
  80.                         case 1:  ledm1(); break;
  81.                         case 2:  ledm2(); break;
  82.                         case 3:  ledm3(); break;
  83.                 }
  84.                 delay(1);//控制主循環周期約1ms,如用定時器可以更精確
  85.         }
  86. }

復制代碼
回復

使用道具 舉報

17#
ID:128588 發表于 2020-3-6 08:41 | 只看該作者
wulin 發表于 2020-3-5 22:25
給你再改一下,按鍵不影響程序正常運行,循環閃爍用子程序任意設置周期和亮滅比。

謝謝   單片機初學   沒有這種編程思路,不知道要過多久才能像你一樣
回復

使用道具 舉報

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

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表