找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

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

請(qǐng)教一下:C語(yǔ)言switch語(yǔ)句應(yīng)用,為什么加了延時(shí)函數(shù),就不跑了

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:393245 發(fā)表于 2020-1-2 23:55 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
問(wèn)題:switch語(yǔ)句應(yīng)用,為什么加了延時(shí)函數(shù),就不跑了。
程序:(這個(gè)可以跑)
#include <STC90C5xAD.H>  
typedef unsigned char u8;
typedef unsigned int u16;
sbit key_SC=P1^0;  
sbit out_SC=P1^4;  
  
sbit led0=P0^0;
sbit led1=P0^1;
u16 a;
void delay_1ms(a)
{
  u16 b;
        while(--a)
                for(b=0;b<600;b++);
}
u8 state;
void shangceng_main()
{
  if(key_SC==0)
   {
             delay_1ms(20);
                if(key_SC==0)
                 {
                     state++;
      switch(state)
       {
        case 1:
          out_SC=led0=1;led1=0;
         break;
        case 2:
          out_SC=led1=1;led0=0;
         break;
        case 3:
          out_SC=led0=led1=state=0;
         break;
       }
     }
   }
}
void main()
{
        key_SC=1;
        out_SC=0;
        state=0;
  led0=0;
  led1=0;
        while(1)
        {
    shangceng_main();
        }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
程序:(這個(gè)不跑)
#include <STC90C5xAD.H>  
typedef unsigned char u8;
typedef unsigned int u16;
sbit key_SC=P1^0;  
sbit out_SC=P1^4;  
  
sbit led0=P0^0;
sbit led1=P0^1;
u16 a;
void delay_1ms(a)
{
  u16 b;
        while(--a)
                for(b=0;b<600;b++);
}
u8 state;
void shangceng_main()
{
  if(key_SC==0)
   {
             delay_1ms(20);
                if(key_SC==0)
                 {
                     state++;
      switch(state)
       {
        case 1:
          out_SC=led0=1;led1=0;delay_1ms(10000);out_SC=led0=0;led1=0;state=0;
         break;
        case 2:
          out_SC=led1=1;led0=0;delay_1ms(20000);out_SC=led1=0;led0=0;state=0;
         break;
        case 3:
          out_SC=led0=led1=state=0;
         break;
       }
     }
   }
}
void main()
{
        key_SC=1;
        out_SC=0;
        state=0;
  led0=0;
  led1=0;
        while(1)
        {
    shangceng_main();
        }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
程序要求:
           按鍵按一次,out_SC;led0;輸出。等待10000ms,不輸出。
            按鍵按兩次,out_SC;led1;輸出。等待20000ms,不輸出。

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

使用道具 舉報(bào)

沙發(fā)
ID:235200 發(fā)表于 2020-1-3 01:54 | 只看該作者
延時(shí)函數(shù)void delay_1ms(a)要改為void delay_1ms(u16 a)
回復(fù)

使用道具 舉報(bào)

板凳
ID:213173 發(fā)表于 2020-1-3 08:15 | 只看該作者
//u16 a;
void delay_1ms(u16 a)
{
  u16 b;
        while(--a)
                for(b=0;b<600;b++);
}
回復(fù)

使用道具 舉報(bào)

地板
ID:110606 發(fā)表于 2020-1-3 08:51 | 只看該作者
程序我沒(méi)有測(cè)試,但是switch中加延時(shí)一定是好用的,我建議你這樣做把延時(shí)降低一下delay_1ms(10000),試一試
回復(fù)

使用道具 舉報(bào)

5#
ID:259898 發(fā)表于 2020-1-3 09:06 | 只看該作者
感覺(jué)你delay寫(xiě)的不對(duì)
回復(fù)

使用道具 舉報(bào)

6#
ID:276663 發(fā)表于 2020-1-3 09:09 | 只看該作者
你的delay函數(shù)有誤
改為
void delay(unsigned long t)
{

    u16 b;
    while(--t)
      for(b=0;b<600;b++);
}
回復(fù)

使用道具 舉報(bào)

7#
ID:282850 發(fā)表于 2020-1-3 09:09 | 只看該作者
不是程序不跑,而是程序一直在運(yùn)行delay_1ms(10000),delay_1ms(20000)中,難與執(zhí)行按鍵掃描key_SC。
delay_ms要求你按下鍵的時(shí)間10、20S,那樣才會(huì)執(zhí)行。
回復(fù)

使用道具 舉報(bào)

8#
ID:680221 發(fā)表于 2020-1-3 09:45 | 只看該作者
1.delay函數(shù)寫(xiě)的有問(wèn)題,傳入的參數(shù)a和全局參數(shù)a命名相同,而且全局參數(shù)a在其他的地方?jīng)]有使用,所以這個(gè)全局參數(shù)的定義毫無(wú)意義,參考二樓的解決方案。
2.七樓正解。delay函數(shù)的延時(shí)不對(duì)了。
回復(fù)

使用道具 舉報(bào)

9#
ID:282850 發(fā)表于 2020-1-3 10:08 | 只看該作者
回貼時(shí)還沒(méi)看到有人回復(fù),以為大家會(huì)發(fā)現(xiàn)問(wèn)題,F(xiàn)終于看到不同聲音,是否是delay函數(shù)的問(wèn)題?還是先理下思路吧。
void delay_1ms(a){ ... }如果編譯不出錯(cuò),說(shuō)明編譯器把a(bǔ)當(dāng)作原定義的U16來(lái)處理,現(xiàn)在電腦上沒(méi)有keil,也不允許裝。不好測(cè)試。有人說(shuō)要delay_1ms(long a),沒(méi)必要,int是最大65535。
還是堅(jiān)持我上貼的理由,10S、20S延時(shí)執(zhí)行,完后才測(cè)一次按鍵!
回復(fù)

使用道具 舉報(bào)

10#
ID:680400 發(fā)表于 2020-1-3 13:34 | 只看該作者
不是程序不跑,而是程序一直在運(yùn)行delay_1ms(10000),delay_1ms(20000)中
回復(fù)

使用道具 舉報(bào)

11#
ID:412641 發(fā)表于 2020-1-3 14:11 | 只看該作者
應(yīng)該是延時(shí)函數(shù)有問(wèn)題,修改一下試試看:
void delay_1ms(int a)
{
  u16 b;
        while(a--)
               { for(b=0;b<600;b++);}
}
回復(fù)

使用道具 舉報(bào)

12#
ID:130230 發(fā)表于 2020-1-3 16:45 | 只看該作者
形參總得由個(gè)類型吧。。實(shí)際上函數(shù)的形參需要并且只需要一個(gè)類型。。。
回復(fù)

使用道具 舉報(bào)

13#
ID:393245 發(fā)表于 2020-1-3 21:47 | 只看該作者
回復(fù)大家:
      延時(shí)函數(shù)沒(méi)有問(wèn)題的。
第一的源碼里,switch沒(méi)有延時(shí)函數(shù),按鍵按下,LED有變化。
第二的源碼里,switch有延時(shí)函數(shù),按鍵按下,LED無(wú)有變化。

問(wèn)題原因是問(wèn):按鍵處理switch里面有延時(shí)函數(shù)的用法?
求修改
回復(fù)

使用道具 舉報(bào)

14#
ID:393245 發(fā)表于 2020-1-3 21:49 | 只看該作者
csmyldl 發(fā)表于 2020-1-3 01:54
延時(shí)函數(shù)void delay_1ms(a)要改為void delay_1ms(u16 a)

延時(shí)函數(shù)沒(méi)有問(wèn)題的,謝謝
回復(fù)

使用道具 舉報(bào)

15#
ID:393245 發(fā)表于 2020-1-3 21:51 | 只看該作者
青龍書(shū)生 發(fā)表于 2020-1-3 08:51
程序我沒(méi)有測(cè)試,但是switch中加延時(shí)一定是好用的,我建議你這樣做把延時(shí)降低一下delay_1ms(10000),試一試 ...

求測(cè)試一下,求解
回復(fù)

使用道具 舉報(bào)

16#
ID:393245 發(fā)表于 2020-1-3 21:53 | 只看該作者
IdeaMing 發(fā)表于 2020-1-3 09:09
你的delay函數(shù)有誤
改為
void delay(unsigned long t)

ms級(jí)的延時(shí)函數(shù),用不著Long吧!
延時(shí)函數(shù)沒(méi)有問(wèn)題的,謝謝
回復(fù)

使用道具 舉報(bào)

17#
ID:393245 發(fā)表于 2020-1-3 21:54 | 只看該作者
f556 發(fā)表于 2020-1-3 09:09
不是程序不跑,而是程序一直在運(yùn)行delay_1ms(10000),delay_1ms(20000)中,難與執(zhí)行按鍵掃描key_SC。
delay ...

對(duì)!應(yīng)該是這樣。
但是,我不了解,你能幫忙修改一下或講解一下嗎
回復(fù)

使用道具 舉報(bào)

18#
ID:213173 發(fā)表于 2020-1-4 09:21 | 只看該作者
這個(gè)問(wèn)題大家都被樓主誤導(dǎo),核心問(wèn)題不在延時(shí)函數(shù)的參數(shù)定義上,雖然樓主定義全局變量u16 a;由于程序中只有延時(shí)函數(shù)使用變量a,所以不至于導(dǎo)致不可預(yù)料后果。但錯(cuò)誤就是錯(cuò)誤,不能因?yàn)槟苡镁驼_。
樓主第二程序核心錯(cuò)誤在于不單純是在分支語(yǔ)句增加了延時(shí)函數(shù)而且畫(huà)蛇添足增加兩條state=0;,所以state只能在0/1間變化,永遠(yuǎn)不可能執(zhí)行到分支2和3,造成錯(cuò)覺(jué)。
回復(fù)

使用道具 舉報(bào)

19#
ID:160500 發(fā)表于 2020-1-4 11:03 | 只看該作者
主要原因是f556說(shuō)的,延時(shí)函數(shù)不是不對(duì),是有歧義,形參是有類型的,最好是顯式聲明,不要用隱式聲明
回復(fù)

使用道具 舉報(bào)

20#
ID:282850 發(fā)表于 2020-1-4 20:44 | 只看該作者
unsigned int timeCNT1,timeCNT2;

void main()
{
    ...
      while(1)
      {
            
            key-------自己加
                  ....
            
            switch(state)
            {
              case 1:
                  out_SC=led0=1;led1=0; delay_1ms(1); timeCNT1++;
                  break;
              case 2:
                 out_SC=led1=1;led0=0;delay_1ms(2); timeCNT2++;
                  break;
              case 3:
                  out_SC=led0=led1=state=0;
                  break;
            }
      
      .....
      
            if(timeCNT1 >1000){out_SC=led0=0;led1=0;state=0;}
            if(timeCNT2 >1000){out_SC=led1=0;led0=0;state=0;}
      
}
思路是這樣,不會(huì)造成很長(zhǎng)時(shí)間的延時(shí)(無(wú)用功)。
用無(wú)窮思維,如果一個(gè)延時(shí)是delay(1萬(wàn)年),這樣很明顯是垃圾寫(xiě)法,當(dāng)然除了中斷可以破這個(gè)1萬(wàn)年,不然就是死機(jī)1萬(wàn)年了。
回復(fù)

使用道具 舉報(bào)

21#
ID:282850 發(fā)表于 2020-1-4 21:27 | 只看該作者
別忘了 在if 里將timeCNT清零。
回復(fù)

使用道具 舉報(bào)

22#
ID:393245 發(fā)表于 2020-1-4 22:42 | 只看該作者
這樣寫(xiě)會(huì)好理解一些:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <STC90C5xAD.H>

typedef unsigned char u8;
typedef unsigned int u16;

sbit key=P0^0;  
sbit zout=P0^1;  
sbit led0=P0^2;
sbit led1=P0^3;
sbit led2=P0^4;

void delay_1ms(u16 a)
      {
            u16 b;
            while(--a)
            for(b=0;b<600;b++);
      }

void key_main()
     {
           u8 state;
           if(key==0)
                 {
                         delay_1ms(10);
                         if(key==0)
                                {
                                       state++;
                                       if(state==1)
                                             {
                                                     zout=led0=1;
                                                     led1=led2=0;        
                                             }
                                      if(state==2)
                                             {
                                                     zout=led1=1;
                                                     led0=led2=0;
                                             }
                                     if(state==3)
                                             {
                                                     zout=led2=1;
                                                     led0=led1=0;
                                             }
                                     if(state>=4)
                                            {
                                                     state=zout=led0=led1=led2=0;
                                            }
                                    while(!key);
                            }
                  }
       }

void main()
      {
              key=1;
              zout=led0=led1=led2=0;
              while(1)
                      {
                              key_main();
                      }
       }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
這個(gè)正常的。按鍵按一下:zout   &&  led0  =  1;  按兩下:zout   &&  led1  =  1; 按三下:zout   &&  led2  =  1; 按四下:全部復(fù)位。

就是加了延時(shí)函數(shù)就不變化了。
回復(fù)

使用道具 舉報(bào)

23#
ID:393245 發(fā)表于 2020-1-4 23:28 | 只看該作者
f556 發(fā)表于 2020-1-4 20:44
unsigned int timeCNT1,timeCNT2;

void main()

你好!你的源碼,我試了。
還是一樣
只要在switch里面有delay_1ms延時(shí)函數(shù)都不行
回復(fù)

使用道具 舉報(bào)

24#
ID:681392 發(fā)表于 2020-1-5 08:32 | 只看該作者
不是程序不跑,應(yīng)該是程序一直在運(yùn)行delay_1ms(10000),delay_1ms(20000)中,難與執(zhí)行按鍵掃描key_SC。
改變一下延時(shí)時(shí)間看看。
回復(fù)

使用道具 舉報(bào)

25#
ID:213173 發(fā)表于 2020-1-5 10:00 | 只看該作者
373630833 發(fā)表于 2020-1-4 23:28
你好!你的源碼,我試了。
還是一樣
只要在switch里面有delay_1ms延時(shí)函數(shù)都不行

樓主不要胡猜,已給你把程序2理清并加注釋,仿真無(wú)誤。樓主應(yīng)該能看得懂,樓上朋友多數(shù)被你誤導(dǎo)。
要學(xué)會(huì)用Keil 走單步,問(wèn)題一覽無(wú)余。
程序的缺陷是使用阻滯式延時(shí)會(huì)使按鍵在此期間無(wú)效。不能及時(shí)切換工作狀態(tài)。
  1. #include <STC90C5xAD.H>  
  2. typedef unsigned char u8;
  3. typedef unsigned int u16;
  4. sbit key_SC=P1^0;  
  5. sbit out_SC=P1^4;  
  6.   
  7. sbit led0=P0^0;
  8. sbit led1=P0^1;
  9. //u16 a;延時(shí)函數(shù)的形式參數(shù)在此聲明就成全局變量,有潛在風(fēng)險(xiǎn)。
  10. void delay_1ms(u16 a)//以12MHz時(shí)鐘計(jì)算此函數(shù)延時(shí)約=a*7ms
  11. {
  12.         u16 b;
  13.         while(--a)
  14.         for(b=0;b<600;b++);
  15. }
  16. u8 state;
  17. void shangceng_main()
  18. {
  19.         if(key_SC==1)
  20.         {
  21.                 delay_1ms(20);//138ms
  22.                 if(key_SC==0)
  23.                 {
  24.                         state++;
  25.                         switch(state)
  26.                         {
  27.                                 case 1:
  28.                                 out_SC=led0=1;
  29.                                 led1=0;
  30.                                 delay_1ms(10000);//72s
  31.                                 out_SC=led0=0;
  32.                                 led1=0;
  33.                                 //state=0;此處錯(cuò)誤,否則不可能有執(zhí)行case 2:的機(jī)會(huì)
  34.                                 break;

  35.                                 case 2:
  36.                                 out_SC=led1=1;
  37.                                 led0=0;
  38.                                 delay_1ms(20000);//144s
  39.                                 out_SC=led1=0;
  40.                                 led0=0;
  41.                                 state=0;
  42.                                 break;
  43. //以下贅句,因?yàn)榘存I第三次是重復(fù)case 2:的最終結(jié)果
  44. //                                case 3:
  45. //                                out_SC=led0=led1=state=0;
  46. //                                break;
  47.                         }
  48.                 }
  49.         }
  50. }
  51. void main()
  52. {
  53.         key_SC=1;
  54.         out_SC=0;
  55.         state=0;
  56.         led0=0;
  57.         led1=0;
  58.         while(1)
  59.         {
  60.                 shangceng_main();
  61.         }
  62. }
復(fù)制代碼

回復(fù)

使用道具 舉報(bào)

26#
ID:681486 發(fā)表于 2020-1-5 12:29 | 只看該作者
你在case語(yǔ)句里加上花括號(hào)試試
回復(fù)

使用道具 舉報(bào)

27#
ID:282850 發(fā)表于 2020-1-6 09:55 | 只看該作者
比較經(jīng)典的錯(cuò)誤,程序及問(wèn)題我復(fù)制保存了,哪天要是當(dāng)師傅,可以當(dāng)個(gè)反面教材。
再次理了一個(gè)你程序流程,還有一個(gè)問(wèn)題,if(key){ state++; switch{} ;}switch包含在if(key)中是另一個(gè)導(dǎo)致出錯(cuò)的問(wèn)題。沒(méi)有key,則State++,switch、timeCNT都不會(huì)被執(zhí)行。!
嵌套邏輯雖然有時(shí)也正常,且有些時(shí)候還必須這樣嵌套,但不好控制。
但我一般喜歡順序控制邏輯,較清晰。
if(a>5){
   if(a>8){
             if(a>10){};
            };
           }
另一種我喜歡的:
if(a>5){};
if(a>8){};
if(a>10){};
建議:
if(key) ){....;  state++; }
delay_ms(1);
switch () {  timeCNT++; }
if(timeCNT >4000)  {改變狀態(tài) }
你試試。另外switch中可以不要delay,delay可加在switch前,時(shí)間還有執(zhí)行整個(gè)while(1)內(nèi)語(yǔ)句、函數(shù)調(diào)用的時(shí)間,所以不用累加到10000、20000.
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表