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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4703|回復: 26
收起左側

請教一下:C語言switch語句應用,為什么加了延時函數,就不跑了

  [復制鏈接]
ID:393245 發表于 2020-1-2 23:55 | 顯示全部樓層 |閱讀模式
問題:switch語句應用,為什么加了延時函數,就不跑了。
程序:(這個可以跑)
#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();
        }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
程序:(這個不跑)
#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,不輸出。

回復

使用道具 舉報

ID:235200 發表于 2020-1-3 01:54 | 顯示全部樓層
延時函數void delay_1ms(a)要改為void delay_1ms(u16 a)
回復

使用道具 舉報

ID:213173 發表于 2020-1-3 08:15 | 顯示全部樓層
//u16 a;
void delay_1ms(u16 a)
{
  u16 b;
        while(--a)
                for(b=0;b<600;b++);
}
回復

使用道具 舉報

ID:110606 發表于 2020-1-3 08:51 | 顯示全部樓層
程序我沒有測試,但是switch中加延時一定是好用的,我建議你這樣做把延時降低一下delay_1ms(10000),試一試
回復

使用道具 舉報

ID:259898 發表于 2020-1-3 09:06 | 顯示全部樓層
感覺你delay寫的不對
回復

使用道具 舉報

ID:276663 發表于 2020-1-3 09:09 | 顯示全部樓層
你的delay函數有誤
改為
void delay(unsigned long t)
{

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

使用道具 舉報

ID:282850 發表于 2020-1-3 09:09 | 顯示全部樓層
不是程序不跑,而是程序一直在運行delay_1ms(10000),delay_1ms(20000)中,難與執行按鍵掃描key_SC。
delay_ms要求你按下鍵的時間10、20S,那樣才會執行。
回復

使用道具 舉報

ID:680221 發表于 2020-1-3 09:45 | 顯示全部樓層
1.delay函數寫的有問題,傳入的參數a和全局參數a命名相同,而且全局參數a在其他的地方沒有使用,所以這個全局參數的定義毫無意義,參考二樓的解決方案。
2.七樓正解。delay函數的延時不對了。
回復

使用道具 舉報

ID:282850 發表于 2020-1-3 10:08 | 顯示全部樓層
回貼時還沒看到有人回復,以為大家會發現問題。現終于看到不同聲音,是否是delay函數的問題?還是先理下思路吧。
void delay_1ms(a){ ... }如果編譯不出錯,說明編譯器把a當作原定義的U16來處理,現在電腦上沒有keil,也不允許裝。不好測試。有人說要delay_1ms(long a),沒必要,int是最大65535。
還是堅持我上貼的理由,10S、20S延時執行,完后才測一次按鍵!
回復

使用道具 舉報

ID:680400 發表于 2020-1-3 13:34 | 顯示全部樓層
不是程序不跑,而是程序一直在運行delay_1ms(10000),delay_1ms(20000)中
回復

使用道具 舉報

ID:412641 發表于 2020-1-3 14:11 | 顯示全部樓層
應該是延時函數有問題,修改一下試試看:
void delay_1ms(int a)
{
  u16 b;
        while(a--)
               { for(b=0;b<600;b++);}
}
回復

使用道具 舉報

ID:130230 發表于 2020-1-3 16:45 | 顯示全部樓層
形參總得由個類型吧。。實際上函數的形參需要并且只需要一個類型。。。
回復

使用道具 舉報

ID:393245 發表于 2020-1-3 21:47 | 顯示全部樓層
回復大家:
      延時函數沒有問題的。
第一的源碼里,switch沒有延時函數,按鍵按下,LED有變化。
第二的源碼里,switch有延時函數,按鍵按下,LED無有變化。

問題原因是問:按鍵處理switch里面有延時函數的用法?
求修改
回復

使用道具 舉報

ID:393245 發表于 2020-1-3 21:49 | 顯示全部樓層
csmyldl 發表于 2020-1-3 01:54
延時函數void delay_1ms(a)要改為void delay_1ms(u16 a)

延時函數沒有問題的,謝謝
回復

使用道具 舉報

ID:393245 發表于 2020-1-3 21:51 | 顯示全部樓層
青龍書生 發表于 2020-1-3 08:51
程序我沒有測試,但是switch中加延時一定是好用的,我建議你這樣做把延時降低一下delay_1ms(10000),試一試 ...

求測試一下,求解
回復

使用道具 舉報

ID:393245 發表于 2020-1-3 21:53 | 顯示全部樓層
IdeaMing 發表于 2020-1-3 09:09
你的delay函數有誤
改為
void delay(unsigned long t)

ms級的延時函數,用不著Long吧!
延時函數沒有問題的,謝謝
回復

使用道具 舉報

ID:393245 發表于 2020-1-3 21:54 | 顯示全部樓層
f556 發表于 2020-1-3 09:09
不是程序不跑,而是程序一直在運行delay_1ms(10000),delay_1ms(20000)中,難與執行按鍵掃描key_SC。
delay ...

對!應該是這樣。
但是,我不了解,你能幫忙修改一下或講解一下嗎
回復

使用道具 舉報

ID:213173 發表于 2020-1-4 09:21 | 顯示全部樓層
這個問題大家都被樓主誤導,核心問題不在延時函數的參數定義上,雖然樓主定義全局變量u16 a;由于程序中只有延時函數使用變量a,所以不至于導致不可預料后果。但錯誤就是錯誤,不能因為能用就正確。
樓主第二程序核心錯誤在于不單純是在分支語句增加了延時函數而且畫蛇添足增加兩條state=0;,所以state只能在0/1間變化,永遠不可能執行到分支2和3,造成錯覺。
回復

使用道具 舉報

ID:160500 發表于 2020-1-4 11:03 | 顯示全部樓層
主要原因是f556說的,延時函數不是不對,是有歧義,形參是有類型的,最好是顯式聲明,不要用隱式聲明
回復

使用道具 舉報

ID:282850 發表于 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;}
      
}
思路是這樣,不會造成很長時間的延時(無用功)。
用無窮思維,如果一個延時是delay(1萬年),這樣很明顯是垃圾寫法,當然除了中斷可以破這個1萬年,不然就是死機1萬年了。
回復

使用道具 舉報

ID:282850 發表于 2020-1-4 21:27 | 顯示全部樓層
別忘了 在if 里將timeCNT清零。
回復

使用道具 舉報

ID:393245 發表于 2020-1-4 22:42 | 顯示全部樓層
這樣寫會好理解一些:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#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();
                      }
       }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
這個正常的。按鍵按一下:zout   &&  led0  =  1;  按兩下:zout   &&  led1  =  1; 按三下:zout   &&  led2  =  1; 按四下:全部復位。

就是加了延時函數就不變化了。
回復

使用道具 舉報

ID:393245 發表于 2020-1-4 23:28 | 顯示全部樓層
f556 發表于 2020-1-4 20:44
unsigned int timeCNT1,timeCNT2;

void main()

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

使用道具 舉報

ID:681392 發表于 2020-1-5 08:32 | 顯示全部樓層
不是程序不跑,應該是程序一直在運行delay_1ms(10000),delay_1ms(20000)中,難與執行按鍵掃描key_SC。
改變一下延時時間看看。
回復

使用道具 舉報

ID:213173 發表于 2020-1-5 10:00 | 顯示全部樓層
373630833 發表于 2020-1-4 23:28
你好!你的源碼,我試了。
還是一樣
只要在switch里面有delay_1ms延時函數都不行

樓主不要胡猜,已給你把程序2理清并加注釋,仿真無誤。樓主應該能看得懂,樓上朋友多數被你誤導。
要學會用Keil 走單步,問題一覽無余。
程序的缺陷是使用阻滯式延時會使按鍵在此期間無效。不能及時切換工作狀態。
  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;延時函數的形式參數在此聲明就成全局變量,有潛在風險。
  10. void delay_1ms(u16 a)//以12MHz時鐘計算此函數延時約=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;此處錯誤,否則不可能有執行case 2:的機會
  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. //以下贅句,因為按鍵第三次是重復case 2:的最終結果
  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. }
復制代碼

回復

使用道具 舉報

ID:681486 發表于 2020-1-5 12:29 | 顯示全部樓層
你在case語句里加上花括號試試
回復

使用道具 舉報

ID:282850 發表于 2020-1-6 09:55 | 顯示全部樓層
比較經典的錯誤,程序及問題我復制保存了,哪天要是當師傅,可以當個反面教材。
再次理了一個你程序流程,還有一個問題,if(key){ state++; switch{} ;}switch包含在if(key)中是另一個導致出錯的問題。沒有key,則State++,switch、timeCNT都不會被執行!!!
嵌套邏輯雖然有時也正常,且有些時候還必須這樣嵌套,但不好控制。
但我一般喜歡順序控制邏輯,較清晰。
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)  {改變狀態 }
你試試。另外switch中可以不要delay,delay可加在switch前,時間還有執行整個while(1)內語句、函數調用的時間,所以不用累加到10000、20000.
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91久久精品一区二区二区 | 在线免费看毛片 | 亚洲不卡av在线 | 欧美一区二区三区 | 欧美综合国产精品久久丁香 | 国产一级片免费在线观看 | 羞羞的视频在线观看 | 国产一区二区久久 | 国产精品99999999 | 免费成人高清 | 色狠狠一区 | 日韩精品成人 | 欧美性吧| 不用播放器看的av | 四季久久免费一区二区三区四区 | 日韩一区二区在线视频 | 国产亚洲第一页 | 国产一区二区三区四区三区四 | 国产乱码精品一区二区三区中文 | 亚洲视频欧美视频 | 国产1区 | 亚洲精品视频在线播放 | 91国自视频| 作爱视频免费看 | 日韩av电影在线观看 | 99国产视频 | 亚洲高清视频在线 | 九九爱这里只有精品 | 国产99精品 | 免费99视频 | 欧美日韩成人影院 | 亚洲欧美久久 | 日韩中文一区二区三区 | 欧美日韩亚洲一区 | 日韩精品成人一区二区三区视频 | www.久久久久久久久 | 亚洲精品乱码久久久久久按摩观 | 色综合99| 国产一区不卡 | 久久久精品视 | 天天夜干 |