找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4139|回复: 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,不输出。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
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),试一试
回复

使用道具 举报

5#
ID:259898 发表于 2020-1-3 09:06 | 只看该作者
感觉你delay写的不对
回复

使用道具 举报

6#
ID:276663 发表于 2020-1-3 09:09 | 只看该作者
你的delay函数有误
改为
void delay(unsigned long t)
{

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

使用道具 举报

7#
ID:282850 发表于 2020-1-3 09:09 | 只看该作者
不是程序不跑,而是程序一直在运行delay_1ms(10000),delay_1ms(20000)中,难与执行按键扫描key_SC。
delay_ms要求你按下键的时间10、20S,那样才会执行。
回复

使用道具 举报

8#
ID:680221 发表于 2020-1-3 09:45 | 只看该作者
1.delay函数写的有问题,传入的参数a和全局参数a命名相同,而且全局参数a在其他的地方没有使用,所以这个全局参数的定义毫无意义,参考二楼的解决方案。
2.七楼正解。delay函数的延时不对了。
回复

使用道具 举报

9#
ID:282850 发表于 2020-1-3 10:08 | 只看该作者
回贴时还没看到有人回复,以为大家会发现问题。现终于看到不同声音,是否是delay函数的问题?还是先理下思路吧。
void delay_1ms(a){ ... }如果编译不出错,说明编译器把a当作原定义的U16来处理,现在电脑上没有keil,也不允许装。不好测试。有人说要delay_1ms(long a),没必要,int是最大65535。
还是坚持我上贴的理由,10S、20S延时执行,完后才测一次按键!
回复

使用道具 举报

10#
ID:680400 发表于 2020-1-3 13:34 | 只看该作者
不是程序不跑,而是程序一直在运行delay_1ms(10000),delay_1ms(20000)中
回复

使用道具 举报

11#
ID:412641 发表于 2020-1-3 14:11 | 只看该作者
应该是延时函数有问题,修改一下试试看:
void delay_1ms(int a)
{
  u16 b;
        while(a--)
               { for(b=0;b<600;b++);}
}
回复

使用道具 举报

12#
ID:130230 发表于 2020-1-3 16:45 | 只看该作者
形参总得由个类型吧。。实际上函数的形参需要并且只需要一个类型。。。
回复

使用道具 举报

13#
ID:393245 发表于 2020-1-3 21:47 | 只看该作者
回复大家:
      延时函数没有问题的。
第一的源码里,switch没有延时函数,按键按下,LED有变化。
第二的源码里,switch有延时函数,按键按下,LED无有变化。

问题原因是问:按键处理switch里面有延时函数的用法?
求修改
回复

使用道具 举报

14#
ID:393245 发表于 2020-1-3 21:49 | 只看该作者
csmyldl 发表于 2020-1-3 01:54
延时函数void delay_1ms(a)要改为void delay_1ms(u16 a)

延时函数没有问题的,谢谢
回复

使用道具 举报

15#
ID:393245 发表于 2020-1-3 21:51 | 只看该作者
青龙书生 发表于 2020-1-3 08:51
程序我没有测试,但是switch中加延时一定是好用的,我建议你这样做把延时降低一下delay_1ms(10000),试一试 ...

求测试一下,求解
回复

使用道具 举报

16#
ID:393245 发表于 2020-1-3 21:53 | 只看该作者
IdeaMing 发表于 2020-1-3 09:09
你的delay函数有误
改为
void delay(unsigned long t)

ms级的延时函数,用不着Long吧!
延时函数没有问题的,谢谢
回复

使用道具 举报

17#
ID:393245 发表于 2020-1-3 21:54 | 只看该作者
f556 发表于 2020-1-3 09:09
不是程序不跑,而是程序一直在运行delay_1ms(10000),delay_1ms(20000)中,难与执行按键扫描key_SC。
delay ...

对!应该是这样。
但是,我不了解,你能帮忙修改一下或讲解一下吗
回复

使用道具 举报

18#
ID:213173 发表于 2020-1-4 09:21 | 只看该作者
这个问题大家都被楼主误导,核心问题不在延时函数的参数定义上,虽然楼主定义全局变量u16 a;由于程序中只有延时函数使用变量a,所以不至于导致不可预料后果。但错误就是错误,不能因为能用就正确。
楼主第二程序核心错误在于不单纯是在分支语句增加了延时函数而且画蛇添足增加两条state=0;,所以state只能在0/1间变化,永远不可能执行到分支2和3,造成错觉。
回复

使用道具 举报

19#
ID:160500 发表于 2020-1-4 11:03 | 只看该作者
主要原因是f556说的,延时函数不是不对,是有歧义,形参是有类型的,最好是显式声明,不要用隐式声明
回复

使用道具 举报

20#
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万年了。
回复

使用道具 举报

21#
ID:282850 发表于 2020-1-4 21:27 | 只看该作者
别忘了 在if 里将timeCNT清零。
回复

使用道具 举报

22#
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; 按四下:全部复位。

就是加了延时函数就不变化了。
回复

使用道具 举报

23#
ID:393245 发表于 2020-1-4 23:28 | 只看该作者
f556 发表于 2020-1-4 20:44
unsigned int timeCNT1,timeCNT2;

void main()

你好!你的源码,我试了。
还是一样
只要在switch里面有delay_1ms延时函数都不行
回复

使用道具 举报

24#
ID:681392 发表于 2020-1-5 08:32 | 只看该作者
不是程序不跑,应该是程序一直在运行delay_1ms(10000),delay_1ms(20000)中,难与执行按键扫描key_SC。
改变一下延时时间看看。
回复

使用道具 举报

25#
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. }
复制代码

回复

使用道具 举报

26#
ID:681486 发表于 2020-1-5 12:29 | 只看该作者
你在case语句里加上花括号试试
回复

使用道具 举报

27#
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 单片机教程网

快速回复 返回顶部 返回列表