搜索
bottom↓
回复: 73

switch case 叠加while 循环问题求教

[复制链接]

出0入0汤圆

发表于 2016-2-13 00:10:54 | 显示全部楼层 |阅读模式
各位大神 求教问题。   我用if也试了,用goto也试了,就是不能顺利跳转

我的问题是我有三个case 我要怎么定义 i  才能在这个三个case中进行循环  就是第一次执行case1的while循环  第二次执行 case2的while循环 第三次执行case3的while循环  第四次执行case1的while循环 --- 如此一个大循环。  用i++试了也不行~ 不知道是不是我加的位置不对,还是我一开始定义的 i=1 的问题,这样始终执行的是case 1 的while.  实在是搞不懂了~

主程序如下:
void main(void)
{
          P3M0=0x08;
        TMOD=0x11;
        IE=0x88;
        PWM=0;
        OUT=0;
        i=1
        switch(i)
        {
         case 1:                        
         { while(i==1)
         {
                  measure();
                if(time>1600)PWM=1;
                else PWM=0;
     }
      i++; break;
         }
         case 2:
         { while(i==2)
         {
                 measure();
                if(time>1600)OUT=1;
                else OUT=0;
     }
     i++; break;
         }
         case 3:
         { while(i==3)
         {
                 measure();
                if(time>1600)PWM=1,OUT=1;
                else PWM=0,OUT=0;
     }
     i=1; break;
         }
         default:break;
     }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2016-2-13 01:06:28 | 显示全部楼层
你的 switch 外侧没有循环,只执行了一次,当然只进了 case 1
话说类似这样的问题即使没看出来,加个断电调试或用 printf 输出点信息到串口也能查出来吧

出0入31汤圆

发表于 2016-2-13 07:39:45 | 显示全部楼层
本帖最后由 zchong 于 2016-2-13 08:43 编辑

2楼说的对,程序执行完已经exit了

后补:
忏悔,没认真看代码

应该是在case 1的while里就出不来了

出0入0汤圆

 楼主| 发表于 2016-2-13 07:59:45 | 显示全部楼层
wudicgi 发表于 2016-2-13 01:06
你的 switch 外侧没有循环,只执行了一次,当然只进了 case 1
话说类似这样的问题即使没看出来,加个断电调 ...

你好,switch外侧不是没有循环 我外侧是有判断time是否有输入的 所以当检测到第一次time大于1600的时候执行case1  我要的是检测到第二次time大于1600的时候执行case2  第三次大于1600执行case3  (每次time小于1600则中断出while 准备下次检测后进入下一条case)
所以我觉得外侧不用循环吧?

出0入0汤圆

发表于 2016-2-13 08:11:09 来自手机 | 显示全部楼层
是我水平低么?不是在1里死循环了么

出0入0汤圆

 楼主| 发表于 2016-2-13 08:17:09 | 显示全部楼层
panjun10 发表于 2016-2-13 08:11
是我水平低么?不是在1里死循环了么

就是请教应该怎么出来   

出50入0汤圆

发表于 2016-2-13 08:20:57 来自手机 | 显示全部楼层
可以在定时器中断里改变i的值即可

出0入0汤圆

发表于 2016-2-13 08:21:07 来自手机 | 显示全部楼层
程序不是那么设计的,你里面为什么要循环?你想跑几次?你想实现什么功能?都没说?

出0入0汤圆

发表于 2016-2-13 08:42:53 来自手机 | 显示全部楼层
babylu200661 发表于 2016-2-13 07:59
你好,switch外侧不是没有循环 我外侧是有判断time是否有输入的 所以当检测到第一次time大于1600的时候执 ...

switch外面就是main,难道是main在被别的循环调用?

出0入0汤圆

发表于 2016-2-13 09:02:44 | 显示全部楼层
babylu200661 发表于 2016-2-13 08:17
就是请教应该怎么出来

想要出来,i++要在while的循环里面。

出0入0汤圆

发表于 2016-2-13 09:50:17 | 显示全部楼层
这样的程序,写的人辛苦,看的人更辛苦,改的人死了的心都有了!

出0入0汤圆

发表于 2016-2-13 10:04:36 | 显示全部楼层
本帖最后由 JeffreySun 于 2016-2-13 10:07 编辑

2楼已经指出,需加上while死循环。

编辑:
还有其他错误。

出0入0汤圆

发表于 2016-2-13 10:15:03 | 显示全部楼层
以下是修改好的代码

  1. void main(void)
  2. {
  3.         P3M0=0x08;
  4.         TMOD=0x11;
  5.         IE=0x88;
  6.         PWM=0;
  7.         OUT=0;
  8.         i=1
  9.         while(1)
  10.         {
  11.         switch(i)
  12.         {
  13.          case 1:                        
  14.          {
  15.                                          while(i==1)
  16.                                         {
  17.                  measure();
  18.                 if(time>1600)
  19.                                                                 {
  20.                                                                         PWM=1;
  21.                                                                         i=2;
  22.                                                                 }
  23.                 else PWM=0;
  24.                                         }
  25.                                         break;
  26.          }
  27.          case 2:
  28.          {
  29.                                         while(i==2)
  30.                                         {
  31.                  measure();
  32.                 if(time>1600)
  33.                                                                 {
  34.                                                                 OUT=1;
  35.                                                                 i=3;
  36.                                                                 }
  37.                 else OUT=0;
  38.                                         }
  39.                                         break;
  40.          }
  41.          case 3:
  42.          {
  43.                                          while(i==3)
  44.                                         {
  45.                  measure();
  46.                 if(time>1600)
  47.                                                                 {
  48.                                                                 PWM=1;
  49.                                                                 OUT=1;
  50.                                                                 i=1;
  51.                                                                 }
  52.                 else
  53.                                                                 {
  54.                                                                 PWM=0;
  55.                                                                 OUT=0;
  56.                                                                 }
  57.                                         }
  58.                                         break;
  59.          }
  60.          default:break;
  61.      }
  62.          }
  63. }
复制代码

出0入0汤圆

发表于 2016-2-13 11:01:44 | 显示全部楼层
while(i==1)怎么跳出来?贴出来的代码里没有看到可以满足跳出条件的语句。

出0入0汤圆

发表于 2016-2-13 11:56:55 来自手机 | 显示全部楼层
像这样的流水功能,并非需要switch,直接利用PC指针的顺序,简单说就一条接一条写就行

出0入0汤圆

发表于 2016-2-13 12:51:05 | 显示全部楼层
要想跳出while循环在最后一条语句把i的值清掉、至于i=0还是几、看你程序需求;

出0入0汤圆

发表于 2016-2-13 12:58:28 | 显示全部楼层
单纯说I的问题,把每个CASE里面的I++;去掉。在SWITCH之前那个I = 1;改成IF(I<3)I++;ELSE I = 1;当然,里面那些WHILE也是问题

出0入0汤圆

发表于 2016-2-13 13:14:18 | 显示全部楼层
看起来楼主的意图,13楼的方法是正确的。
实际上在TIME++的地方设置I的值,我觉得更好

出0入0汤圆

发表于 2016-2-13 13:27:47 | 显示全部楼层
JeffreySun 发表于 2016-2-13 10:15
以下是修改好的代码

看看我这个思路对不对


void main(void)
{
           P3M0=0x08;
         TMOD=0x11;
         IE=0x88;
         PWM=0;
         OUT=0;
         i=1;
    while(1)
{
         switch(i)
         {
          case 1:                        
          {
              while(i==1){
                   measure();
                 if(time>1600){
                    PWM=1;
                  }
          i = 2;
           }
     }
                 else{
                     PWM=0;
                     }
        break;
         
          case 2:
          {
         while(i==2){
                  measure();
                 if(time>1600){
                    OUT=1;
                    }
         i = 3;
          }
   }
                 else{
                   OUT=0;
                   }
       break;
         
          case 3:
          {
          while(i==3){
                  measure();
                 if(time>1600){
                    PWM=1,???OUT=1;
                   }
             i = 1;
          }
   }
                 else {
                  PWM=0,????OUT=0;
                  }
   
     break;
       }   
          default:break;
      }

出0入0汤圆

发表于 2016-2-13 13:37:36 | 显示全部楼层
1826772880 发表于 2016-2-13 13:27
看看我这个思路对不对

这样看有点累啊
好像不对
你每次WHILE里面就一次直接退出了,好像和楼主的意图不太符合

不知道楼主的TIME的部分程序是啥样的

出0入0汤圆

发表于 2016-2-13 13:40:48 | 显示全部楼层
xiaobendan 发表于 2016-2-13 13:37
这样看有点累啊
好像不对
你每次WHILE里面就一次直接退出了,好像和楼主的意图不太符合

哈哈、、程序菜鸟一枚、两种清i 的方式、看楼主是哪种方式

出0入0汤圆

 楼主| 发表于 2016-2-13 20:48:42 | 显示全部楼层
xiaobendan 发表于 2016-2-13 13:37
这样看有点累啊
好像不对
你每次WHILE里面就一次直接退出了,好像和楼主的意图不太符合

time部分没什么程序,time是measure函数测得的值, 单片机输入脚有个脉冲输入,然后就是检测脉冲输入,
当脉冲time第一次 大于1600的时候输出PWM=1 小于1600则所有输出都关闭,
脉冲time第二次大于1600输出OUT=1 小于1600则所有输出都关闭,
脉冲time第三次大于1600输出PWM, OUT=1 小于1600 则同样所有的输出都关闭。  

第四次的时候再重复第一个PWM输出1  ------ 如此往复循环。

不知道各位明白没有。

PWM缩写为P  OUT 缩写为P
正确的循环输出顺序应该如下:
time>1600 输出P=1 O=0  
time<1600 输出P=0 O=0
time>1600 输出P=0 O=1  
time<1600 输出P=0 O=0
time>1600 输出P=1 O=1  
time<1600 输出P=0 O=0

另外各位说的外侧加一个大的while(1)死循环  程序是对了,没什么问题,但是输出不对~
测试了
time>1600 输出P=1 O=1  
time<1600 输出P=1 O=0
time>1600 输出P=1 O=1  
time<1600 输出P=0 O=1
time>1600 输出P=1 O=1  
time<1600 输出P=1 O=0
time>1600 输出P=1 O=1  
time<1600 输出P=0 O=0
time>1600 输出P=1 O=1
time<1600 输出P=0 O=0
time>1600 输出P=1 O=1
time<1600 输出P=0 O=0
time>1600 输出P=1 O=1
time<1600 输出P=0 O=1
time>1600 输出P=1 O=1
time<1600 输出P=0 O=0
time>1600 输出P=1 O=1
time<1600 输出P=0 O=0
time>1600 输出P=1 O=1
time<1600 输出P=0 O=0
time>1600 输出P=1 O=1
time>1600 输出P=1 O=1
time<1600 输出P=0 O=0
time>1600 输出P=1 O=1
time<1600 输出P=0 O=0
time>1600 输出P=0 O=1
time<1600 输出P=0 O=0
time>1600 输出P=1 O=1
time<1600 输出P=1 O=0

感觉完全就乱了~
time<1600 输出P=0 O=0
      

出0入0汤圆

 楼主| 发表于 2016-2-13 20:50:16 | 显示全部楼层
1826772880 发表于 2016-2-13 13:40
哈哈、、程序菜鸟一枚、两种清i 的方式、看楼主是哪种方式

你的清i的方式也是得到同样的结果,都是乱的~  输出没顺序~ 根本不对,跟我在里面写i++一样。

出0入0汤圆

 楼主| 发表于 2016-2-13 20:56:23 | 显示全部楼层
brentcao 发表于 2016-2-13 08:21
程序不是那么设计的,你里面为什么要循环?你想跑几次?你想实现什么功能?都没说? ...

time部分没什么程序,time是measure函数对单片机外侧输出测得的值, 单片机输入脚有个脉冲输入,然后就是检测脉冲输入,然后两个输出口做出对应的开关
当脉冲time第一次 大于1600的时候输出口PWM=1 小于1600则所有输出都关闭,
脉冲time第二次大于1600输出口OUT=1 小于1600则所有输出都关闭,
脉冲time第三次大于1600输出口PWM, OUT=1 小于1600 则同样所有的输出都关闭。  

第四次的时候再重复第一个PWM输出1  ------ 如此往复循环。

不知道各位明白没有。

PWM缩写为P  OUT 缩写为P
正确的无限循环输出顺序应该如下:
time>1600 输出P=1 O=0  
time<1600 输出P=0 O=0
time>1600 输出P=0 O=1  
time<1600 输出P=0 O=0
time>1600 输出P=1 O=1  
time<1600 输出P=0 O=0

出0入0汤圆

发表于 2016-2-13 21:27:07 | 显示全部楼层
贴出你的measure()函数看看

出0入0汤圆

 楼主| 发表于 2016-2-13 21:52:43 | 显示全部楼层
JeffreySun 发表于 2016-2-13 21:27
贴出你的measure()函数看看

#include<reg52.h>
#include "intrins.h"
#define u8 unsigned char
#define u16 unsigned int

sfr P3M1=0xb1;
sfr P3M0=0xb2;
sfr IAP_DATA=0xc2;//EEPROM寄存器
sfr IAP_ADDRH=0xc3;
sfr IAP_ADDRL=0xc4;
sfr IAP_CMD=0xc5;
sfr IAP_TRIG=0xc6;
sfr IAP_CONTR=0xc7;

sbit PWM=P3^3;
sbit IN=P3^4;
sbit OUT=P3^2;
int  i;

u16 time;//,proportion,MAX,MIN,k,tt ;

void measure()//脉宽测量
{
        time=0;
        TL0=0,TH0=0;
        while(!IN);
        TR0=1;
        while(IN);
        TR0=0;
        time+=TH0;
        time<<=8;
        time+=TL0;               
}

/*=====接主函数=====
void main(void)
{

出0入34汤圆

发表于 2016-2-13 21:55:52 | 显示全部楼层
楼主真是好运,找了一伙人帮您 Debug。

出0入0汤圆

 楼主| 发表于 2016-2-13 21:59:14 | 显示全部楼层
xyz543 发表于 2016-2-13 21:55
楼主真是好运,找了一伙人帮您 Debug。

哈哈,是啊  论坛热心的人多~  谁给我搞定了,加我微信或QQ,我发红包给他

出0入0汤圆

发表于 2016-2-13 22:18:36 | 显示全部楼层
这其实是一个状态机。
每一个状态都要刷一遍全部2个输出。

  1. void main(void)
  2. {
  3.         P3M0=0x08;
  4.         TMOD=0x11;
  5.         IE=0x88;
  6.         PWM=0;
  7.         OUT=0;
  8.         i=1
  9. while(1)
  10.         {
  11.         switch(i)
  12.                 {
  13.                 case 1:                        
  14.                         {
  15.                         while(i==1)
  16.                                 {
  17.                                 measure();
  18.                                 if(time>1600)
  19.                                         {
  20.                                         PWM=1;
  21.                                         OUT=0;
  22.                                         i=2;
  23.                                         }
  24.                                 else
  25.                                         {
  26.                                         PWM=0;
  27.                                         OUT=0;
  28.                                         }
  29.                                 }
  30.                         break;
  31.                         }
  32.                 case 2:
  33.                         {
  34.                         while(i==2)
  35.                                 {
  36.                                 measure();
  37.                                 if(time>1600)
  38.                                         {
  39.                                         PWM=0
  40.                                         OUT=1;
  41.                                         i=3;
  42.                                         }
  43.                                 else
  44.                                         {
  45.                                         PWM=0;
  46.                                         OUT=0;
  47.                                         }
  48.                                 }
  49.                         break;
  50.                         }
  51.                 case 3:
  52.                         {
  53.                         while(i==3)
  54.                                 {
  55.                                 measure();
  56.                                 if(time>1600)
  57.                                         {
  58.                                         PWM=1;
  59.                                         OUT=1;
  60.                                         i=1;
  61.                                         }
  62.                                 else
  63.                                         {
  64.                                         PWM=0;
  65.                                         OUT=0;
  66.                                         }
  67.                                 }
  68.                         break;
  69.                         }
  70.                 default:break;
  71.                 }
  72.         }
  73. }
复制代码

出0入0汤圆

发表于 2016-2-13 22:20:36 | 显示全部楼层
另外,像这种测量脉冲的问题,需要放到中断里执行,否则速度快了肯定会有些脉冲测不到。

出0入0汤圆

发表于 2016-2-13 22:24:34 | 显示全部楼层
xyz543 发表于 2016-2-13 21:55
楼主真是好运,找了一伙人帮您 Debug。

看到楼主,仿佛看到了自己之前debug的无助。

不过楼主这么简单的几行代码,bug这么多,楼主实际上应该自己来搞。

我这么做其实是害了他,但是实在是很想解决这个问题。。。。

出0入34汤圆

发表于 2016-2-13 22:28:38 | 显示全部楼层
那好吧!在 While Loop 内若跳不出来就加一个 break; 就行啦!~
开玩笑的,给楼主您一个方向,您可能要去理解那个叫 O/S 啥的,可能对您会有些帮助吧?!

出0入0汤圆

 楼主| 发表于 2016-2-13 22:28:39 | 显示全部楼层
JeffreySun 发表于 2016-2-13 22:24
看到楼主,仿佛看到了自己之前debug的无助。

不过楼主这么简单的几行代码,bug这么多,楼主实际上应该自 ...

我已经搞了一个多星期了~ 实在是新手,改了又改,边看书边改,能到这样已经实属不易啊~  多谢兄台帮我。  已经一个头两个大了  

出0入0汤圆

发表于 2016-2-13 22:34:08 | 显示全部楼层
这个其实就是个statemachine,用for循环语句+if条件判断实现很简单。
while(1)
{
      for(i=1;i<4;i++)
       {
              if(i==1)
                  {  
                       measure();
                if(time>1600)PWM=1;
                else PWM=0;
                      }
             else if (i==2)
                  {       
                     measure();
                 if(time>1600){
                    OUT=1;       
                           }
            elseif(i==3)
                  {
                       measure();
                if(time>1600)PWM=1,OUT=1;
                else PWM=0,OUT=0;
                      }
          }
}

出0入0汤圆

发表于 2016-2-13 22:42:01 | 显示全部楼层
proteldxp 发表于 2016-2-13 22:34
这个其实就是个statemachine,用for循环语句+if条件判断实现很简单。
while(1)
{

这么写肯定不行。
你这样即便没有符合要求的脉冲,依然会切换state。

出0入0汤圆

发表于 2016-2-13 22:46:48 | 显示全部楼层
你感觉执行完第三个while ==3后再回去执行第一个 OUT会不会是零?
        switch(i)
          {
           case 1:                        
           {
               while(i==1){
                    measure();
                  if(time>1600){
                     PWM=1;
                    OUT = 0;
                   }
           i = 2;
            }
      }
                  else{
                      PWM=0;
                      OUT = 0;
                      }
         break;
         
           case 2:
           {
          while(i==2){
                   measure();
                  if(time>1600){
                     PWM = 0;
                     OUT=1;
                     }
          i = 3;
           }
    }
                  else{
                    OUT=0;
                   PWM = 0;
                    }
        break;
         
           case 3:
           {
           while(i==3){
                   measure();
                  if(time>1600){
                     PWM=1;
                     OUT=1;
                    }
              i = 1;
           }
    }
                  else {
                   PWM=0;
                   OUT=0;
                   }
     
      break;

出0入0汤圆

发表于 2016-2-13 22:50:41 | 显示全部楼层
1826772880 发表于 2016-2-13 22:46
你感觉执行完第三个while ==3后再回去执行第一个 OUT会不会是零?
        switch(i)
          {

OUT一定会被清零。

出0入0汤圆

发表于 2016-2-13 22:51:12 | 显示全部楼层
proteldxp 发表于 2016-2-13 22:34
这个其实就是个statemachine,用for循环语句+if条件判断实现很简单。
while(1)
{

最简单不需要判断、程序只管往下跑就好了、他这里没有指定i等于几再去执行哪个函数

出0入0汤圆

发表于 2016-2-13 22:52:21 | 显示全部楼层
JeffreySun 发表于 2016-2-13 22:50
OUT一定会被清零。

你在哪里看到lz原程序上有清OUT的语句?

出0入0汤圆

发表于 2016-2-13 22:56:37 | 显示全部楼层
1826772880 发表于 2016-2-13 22:52
你在哪里看到lz原程序上有清OUT的语句?

因为没有,所以才不对啊。
lz每次切换state的时候(不只是第三个while)都要清零2两个输出。

看楼主:

PWM缩写为P  OUT 缩写为P
正确的循环输出顺序应该如下:
time>1600 输出P=1 O=0  
time<1600 输出P=0 O=0
time>1600 输出P=0 O=1  
time<1600 输出P=0 O=0
time>1600 输出P=1 O=1  
time<1600 输出P=0 O=0

出0入0汤圆

 楼主| 发表于 2016-2-13 22:57:19 | 显示全部楼层
1826772880 发表于 2016-2-13 22:51
最简单不需要判断、程序只管往下跑就好了、他这里没有指定i等于几再去执行哪个函数 ...

只管往下跑肯定不行啊, CASE1 CASE2 CASE3是并行的, 就是外面没有脉冲输入的时候是不执行程序的,如果按你说的,那一检测到一个脉冲 三个CASE都跑遍了是不对的。  我要的是每次检测到脉冲有 然后无 这个过程中只跑其中一个CASE, 下次再有脉冲的时候才跑其他的。

出0入0汤圆

 楼主| 发表于 2016-2-13 23:00:39 | 显示全部楼层
本帖最后由 babylu200661 于 2016-2-14 01:25 编辑
1826772880 发表于 2016-2-13 22:52
你在哪里看到lz原程序上有清OUT的语句?


其实OUT一开始赋值的时候就是0啊,前面两个CASE 都没有变为1 为什么要清0呢? 只有到第三个CASE中 OUT才变为1 所以当脉冲小于1600的时候我才要清0    不知道我说的明白了吗?




一样是条数限制

实际上我的程序不会自动往下跑啊,当我 I值固定的时候就是在固定的那个CASE中不会往下,还有我第三个CASE最后是有OUT=0给它清了啊,我说其他几个CASE不用加吧? 我理解的对吗?

方便的话如果愿意加我WEI信:       jame-weixin     名NAME字 :JAMES

谢谢各位的热心

出0入0汤圆

发表于 2016-2-13 23:02:03 | 显示全部楼层
问一下楼主,一旦出现脉冲大于1600,你是想持续输出某个信号(1:0,0:1或者1:1),还是仅仅发出一个短脉冲信号(1:0,0:1或者1:1)?

出0入0汤圆

 楼主| 发表于 2016-2-13 23:04:23 | 显示全部楼层
JeffreySun 发表于 2016-2-13 22:56
因为没有,所以才不对啊。
lz每次切换state的时候(不只是第三个while)都要清零2两个输出。

对我想您应该已经明白我的要求了。 您写的程序里面 i 一定不能写在上面的,如果写在上面就不对了(要写也写在else 后面,不在if 下面),我刚才测试了,写在上面的时候就会出现当脉冲小于1600的时候 还有灯亮着。

出0入0汤圆

 楼主| 发表于 2016-2-13 23:06:48 | 显示全部楼层
本帖最后由 babylu200661 于 2016-2-14 01:26 编辑
JeffreySun 发表于 2016-2-13 23:02
问一下楼主,一旦出现脉冲大于1600,你是想持续输出某个信号(1:0,0:1或者1:1),还是仅仅发出一个短脉 ...


我要持续连续输出信号,(只有当<1600时才改变输出都为0)所以我才用while, 不用while做死循环,这样就会往下走了,  我用的对吗?  



我的权限每个小时限制5条 您的这段程序输出的结果是当脉冲大于1600时     PWM 和 OUT都不停的输出0,1,0,1  接灯的话就是两个输出口不停闪烁。 当小于1600的时候是都关闭,正确的。  好像是没有关死在某个CASE中。  
我这个是用来控制灯的,不是舵机。 另外你说的第三个CASE执行完,那只有TIME小于1600才会出去啊,不然不是锁死在那个while中的么? 而我在第三个case的else中也加了 out=0 给它清掉了啊。所以其它的CASE应该没有影响吧?




果然跟我上面想的一样,楼主的表达式有问题的。 有什么问题? 我单独赋值I 等于1 或者2 或者3的时候每个CASE 都能正常运作啊,就是不跳转而已固定在其中一个CASE里,没有任何异常。  而且我理解的应该是那个MEASURE单片机是一直在进行测量的。 所以不存在说几次测得吧?只要是大于1600就是 固定输出一种  而不会是闪烁。。     难道我理解错了?  

出0入0汤圆

发表于 2016-2-13 23:07:24 | 显示全部楼层
babylu200661 发表于 2016-2-13 23:00
其实OUT一开始赋值的时候就是0啊,前面两个CASE 都没有变为1 为什么要清0呢? 只有到第三个CASE中 OUT才变 ...

因为第三个case执行完了之后,OUT就变成1了, 如果前两个case不清掉的话会一直保持1直到再回到第三个case。

出0入0汤圆

发表于 2016-2-13 23:08:12 | 显示全部楼层
babylu200661 发表于 2016-2-13 22:57
只管往下跑肯定不行啊, CASE1 CASE2 CASE3是并行的, 就是外面没有脉冲输入的时候是不执行程序的,如果 ...

没有脉冲不跑的话那你这个程序也不对啊、你执行完第一个后就给 i 赋值了、他就会接着执行下一个while 那你只能在每个while的最后一条加上while(IN);让他停在这里、有脉冲再跑

出0入0汤圆

发表于 2016-2-13 23:09:52 | 显示全部楼层
lz是用来控制舵机么?

出0入0汤圆

发表于 2016-2-13 23:13:32 | 显示全部楼层
babylu200661 发表于 2016-2-13 23:00
其实OUT一开始赋值的时候就是0啊,前面两个CASE 都没有变为1 为什么要清0呢? 只有到第三个CASE中 OUT才变 ...

因为你首次执行前两个while   OUT是零、在执行完第三个后他变为1了、接着回去第一个时候、不管你是怎么样的结果、OUT还是1。好好想想需不需要清零

出0入0汤圆

发表于 2016-2-13 23:27:19 | 显示全部楼层
我想了一下lz的情况可能是这样的:

单片机收到的脉冲很有可能是连续的,相邻两个脉冲幅度是差不多的。比如一段时间连续收到了 1700 1750 1800 1700 1600 1500 这种数值,应该被判做楼主所谓的“收到一次大于1600的脉冲”,而不是4次大于1600的脉冲


出0入0汤圆

发表于 2016-2-13 23:29:24 | 显示全部楼层
本帖最后由 JeffreySun 于 2016-2-13 23:31 编辑


我的权限每个小时限制5条 您的这段程序输出的结果是当脉冲大于1600时     PWM 和 OUT都不停的输出0,1,0,1  接灯的话就是两个输出口不停闪烁。 当小于1600的时候是都关闭,正确的。  好像是没有关死在某个CASE中。  
我这个是用来控制灯的,不是舵机。 另外你说的第三个CASE执行完,那只有TIME小于1600才会出去啊,不然不是锁死在那个while中的么? 而我在第三个case的else中也加了 out=0 给它清掉了啊。所以其它的CASE应该没有影响吧?



果然跟我上面想的一样,楼主的表达是有问题的。


编辑:错别字

出0入0汤圆

发表于 2016-2-13 23:46:40 | 显示全部楼层
babylu200661 发表于 2016-2-13 23:06
我要持续连续输出信号,(只有当

你第三个是清零了、那是小于1600才清零、你大于1600就跑出去了、怎么执行清零?另外我不明白你整个while(==i)是想干什么?是想等这个脉冲过去再来一个脉冲跑下一个while还是?

出0入0汤圆

 楼主| 发表于 2016-2-14 00:06:02 | 显示全部楼层
1826772880 发表于 2016-2-13 23:46
你第三个是清零了、那是小于1600才清零、你大于1600就跑出去了、怎么执行清零?另外我不明白你整个while ...

大于1600怎么会出去啊,大于1600的时候是锁死在那个CASE的while中啊输出PWM=1 或者OUT=1,怎么回跑出去啊?    当小于1600时才会BREAK出去  而且跑出去了,我MAIN里面有写OUT=0啊??   我都搞晕了~

出0入0汤圆

发表于 2016-2-14 00:08:33 | 显示全部楼层
switch(i)外侧要加while(1)才行,这样外侧才会遁环
所有 if(time>1600)内最后要加break;,这样内遁环才跳得出来。

出0入0汤圆

发表于 2016-2-14 00:14:41 | 显示全部楼层
babylu200661 发表于 2016-2-14 00:06
大于1600怎么会出去啊,大于1600的时候是锁死在那个CASE的while中啊输出PWM=1 或者OUT=1,怎么回跑出去啊 ...

  我明白你的意思了
switch(i)
           {
            case 1:                        
            {
                while(i==1){
                     measure();
                   if(time>1600){
                      PWM=1;
                     OUT = 0;
                    }  //if
                else{
                       PWM=0;
                       OUT = 0;
                       i = 2;
                       }  //else
                   }  //while
              } //case
          break;
           
            case 2:
            {
           while(i==2){
                    measure();
                   if(time>1600){
                      PWM = 0;
                      OUT=1;
                      }
            else{
                       OUT=0;
                    PWM = 0;
                          i = 3;
                  }
              }
          }
         break;
           
            case 3:
            {
            while(i==3){
                    measure();
                   if(time>1600){
                      PWM=1;
                      OUT=1;
                     }
          else {
                    PWM=0;
                    OUT=0;
                       i = 1;
                }
          }
      }
                 }
      
       break;

出0入0汤圆

发表于 2016-2-14 00:25:34 | 显示全部楼层
本帖最后由 JeffreySun 于 2016-2-14 00:50 编辑

  1. void main(void)
  2. {
  3.         P3M0=0x08;
  4.         TMOD=0x11;
  5.         IE=0x88;
  6.         PWM=0;
  7.         OUT=0;
  8.         i=1
  9.        

  10. while(1)
  11.         {
  12.         switch(i)
  13.                 {
  14.                 case 1:     //状态1   等待第一个大于1600脉冲到来           
  15.                         {
  16.                         while(i==1)
  17.                                 {
  18.                                 measure();
  19.                                 if(time>1600)  //收到脉冲
  20.                                         {
  21.                                         PWM=1;
  22.                                         OUT=0;
  23.                                         i=2;  //进入状态2
  24.                                         }
  25.                                 else
  26.                                         {                //没有收到脉冲
  27.                                         PWM=0;
  28.                                         OUT=0;
  29.                                         i=1;  //留在状态1
  30.                                         }
  31.                                 }
  32.                         break;
  33.                         }
  34.                 case 2: //状态2   持续接收大于1600的脉冲 直到小于1600   输出1,0     
  35.                         {
  36.                         while(i==2)
  37.                                 {
  38.                                 measure();
  39.                                 if(time>1600)
  40.                                         {
  41.                                         PWM=1;
  42.                                         OUT=0;
  43.                                         i=2;
  44.                                         }
  45.                                 else
  46.                                         {
  47.                                         PWM=0;
  48.                                         OUT=0;
  49.                                         i=3;
  50.                                         }
  51.                                 }
  52.                         break;
  53.                         }
  54.                 case 3://状态3   等待第二次接收大于1600脉冲
  55.                         {
  56.                         while(i==3)
  57.                                 {
  58.                                 measure();
  59.                                 if(time>1600)
  60.                                         {
  61.                                         PWM=0;
  62.                                         OUT=1;
  63.                                         i=4;
  64.                                         }
  65.                                 else
  66.                                         {
  67.                                         PWM=0;
  68.                                         OUT=0;
  69.                                         i=3;
  70.                                         }
  71.                                 }
  72.                         break;
  73.                         }
  74.                 case 4: //状态4   持续接收大于1600的脉冲 直到小于1600      输出0,1
  75.                         {
  76.                         while(i==4)
  77.                                 {
  78.                                 measure();
  79.                                 if(time>1600)
  80.                                         {
  81.                                         PWM=0;
  82.                                         OUT=1;
  83.                                         i=4;
  84.                                         }
  85.                                 else
  86.                                         {
  87.                                         PWM=0;
  88.                                         OUT=0;
  89.                                         i=5;
  90.                                         }
  91.                                 }
  92.                         break;
  93.                         }
  94.                 case 5://状态5   等待第三次接收大于1600脉冲
  95.                         {
  96.                         while(i==5)
  97.                                 {
  98.                                 measure();
  99.                                 if(time>1600)
  100.                                         {
  101.                                         PWM=1;
  102.                                         OUT=1;
  103.                                         i=6;
  104.                                         }
  105.                                 else
  106.                                         {
  107.                                         PWM=0;
  108.                                         OUT=0;
  109.                                         i=5;
  110.                                         }
  111.                                 }
  112.                         break;
  113.                         }                                                                                               



  114.                 case 6://状态6   持续接收大于1600的脉冲 直到小于1600   输出1,1
  115.                         {
  116.                         while(i==6)
  117.                                 {
  118.                                 measure();
  119.                                 if(time>1600)
  120.                                         {
  121.                                         PWM=1;
  122.                                         OUT=1;
  123.                                         i=6;
  124.                                         }
  125.                                 else
  126.                                         {
  127.                                         PWM=0;
  128.                                         OUT=0;
  129.                                         i=1;
  130.                                         }
  131.                                 }
  132.                         break;
  133.                         }
  134.                 default:break;
  135.                 }
  136.         }
  137. }
复制代码



编辑:替换乱码注释

出0入0汤圆

 楼主| 发表于 2016-2-14 00:28:58 | 显示全部楼层
1826772880 发表于 2016-2-14 00:14
我明白你的意思了
switch(i)
           {

非常感谢这么晚还在给我弄, 我这么改过了,不对的,您这样的话初始复制是多少,那就固定在对应的CASE里面,跳不出去的  而且您写的break要在case大括号之前,不然不对的。

出0入0汤圆

发表于 2016-2-14 00:49:36 | 显示全部楼层
本帖最后由 1826772880 于 2016-2-14 00:53 编辑

我编程本来就很渣、只有这招了、、别嫌弃、、、
while(1){
                      measure();
                 if(i==1 & time > 1600){
                       PWM=1;
                      OUT = 0;
                        i = 2;
                     }  
                 if(i == 2 & time <1600){
                        PWM=0;
                        OUT = 0;
                        i = 3;
                        }  

                 if(i==3 & time > 1600){
                       PWM=1;
                      OUT = 0;
                           i = 4;
                     }  
                 if(i == 4 & time <1600){
                        PWM=0;
                        OUT = 0;
                        i = 5;
                        }  

                 if(i==5 & time > 1600){
                       PWM=1;
                      OUT = 0;
                          i =6;
                     }  
                 if(i == 6 & time <1600){
                        PWM=0;
                        OUT = 0;
                        i = 1;
                        }  

出0入0汤圆

发表于 2016-2-14 01:06:26 | 显示全部楼层
1826772880 发表于 2016-2-14 00:49
我编程本来就很渣、只有这招了、、别嫌弃、、、
while(1){
                      measure();

你写的比我的switch效率高多了。

出0入0汤圆

 楼主| 发表于 2016-2-14 01:08:24 | 显示全部楼层
本帖最后由 babylu200661 于 2016-2-14 01:26 编辑
JeffreySun 发表于 2016-2-14 00:25
编辑:替换乱码注释


多谢兄台相助!  这个程序完全符合我的要求!

出0入0汤圆

 楼主| 发表于 2016-2-14 01:15:12 | 显示全部楼层
本帖最后由 babylu200661 于 2016-2-14 01:24 编辑
1826772880 发表于 2016-2-14 00:49
我编程本来就很渣、只有这招了、、别嫌弃、、、
while(1){
                      measure();


非常感谢深夜还在给我改, 不过我试了下您的程序 只有PWM=1 和0两种状态输出,没有其他状态输出,今天太晚了,明天再研究您写的。 刚刚上面那位的程序是对的,就是我想要的。谢谢谢谢两位的相助~

出0入0汤圆

发表于 2016-2-14 01:15:54 来自手机 | 显示全部楼层
JeffreySun 发表于 2016-2-14 01:06
你写的比我的switch效率高多了。

简单粗暴,哈哈

出0入0汤圆

 楼主| 发表于 2016-2-14 01:18:54 | 显示全部楼层

多谢啊  方便加我下WEI信

出0入0汤圆

发表于 2016-2-14 01:21:54 来自手机 | 显示全部楼层
babylu200661 发表于 2016-2-14 01:15
非常感谢深夜还在给我改, 不过我试了下您的程序 只有PWM=1 和0两种状态输出,没有其他状态输出,今天太 ...

顺便把你字体都改小,论坛是不允许大字体的,至于那个&还是&&,我至今还没研究过细节,一直都是蒙的

出0入0汤圆

 楼主| 发表于 2016-2-14 01:27:27 | 显示全部楼层
1826772880 发表于 2016-2-14 01:21
顺便把你字体都改小,论坛是不允许大字体的,至于那个&还是&&,我至今还没研究过细节,一直都是蒙的 ...

唯有谢谢二次~

出0入0汤圆

发表于 2016-2-14 11:06:09 来自手机 | 显示全部楼层
babylu200661 发表于 2016-2-14 01:15
非常感谢深夜还在给我改, 不过我试了下您的程序 只有PWM=1 和0两种状态输出,没有其他状态输出,今天太 ...

突然想起我是复制粘贴来着,所以每个if内容都一样,你改下pwm就好了

出0入0汤圆

 楼主| 发表于 2016-2-14 11:08:56 | 显示全部楼层
1826772880 发表于 2016-2-14 11:06
突然想起我是复制粘贴来着,所以每个if内容都一样,你改下pwm就好了

好的,多谢啊~

出0入0汤圆

发表于 2016-2-14 15:05:48 | 显示全部楼层
while(i==1)
while(i==2)
while(i==3)
只要进去其中一个,在其内部没有跳出语句,当然就死在里面出不了啊
楼主不懂状态机概念是啥东西吧?

出0入0汤圆

 楼主| 发表于 2016-2-14 16:20:49 | 显示全部楼层
haowei029 发表于 2016-2-14 15:05
while(i==1)
while(i==2)
while(i==3)

多谢回复,是不懂,但是我下面有I++和BREAK 出来是能出来的,就是出来了进去的时候控制不好顺序,上面的 JeffreySun  已经完美帮我解决了~

出0入0汤圆

 楼主| 发表于 2016-2-15 00:31:40 | 显示全部楼层
1826772880 发表于 2016-2-14 11:06
突然想起我是复制粘贴来着,所以每个if内容都一样,你改下pwm就好了

你的程序也是对的! 那个& 要用两个 &&   简洁明了   谢啦~

出0入0汤圆

发表于 2016-2-15 13:18:51 | 显示全部楼层
while(i==1){  ******** ;if( i !=1)break;}     

出0入0汤圆

发表于 2016-2-16 23:18:44 | 显示全部楼层
我在你的需求里没有找到计数器清零的地方?

出0入0汤圆

发表于 2016-2-17 00:55:22 | 显示全部楼层
babylu200661 发表于 2016-2-14 16:20
多谢回复,是不懂,但是我下面有I++和BREAK 出来是能出来的,就是出来了进去的时候控制不好顺序,上面的  ...

人家帮你改的是程序算法,或许只是能用。但是程序的语句不是最优,很罗嗦!
你自己好好分析一下每个语句,看看是不是有重复的地方?我就不一一指出来了。
可能是新手吧?要多写写程序,多锻炼自己!慢慢来,程序这种东西是要自己练出来的!

出0入0汤圆

 楼主| 发表于 2016-2-17 13:46:36 | 显示全部楼层
haowei029 发表于 2016-2-17 00:55
人家帮你改的是程序算法,或许只是能用。但是程序的语句不是最优,很罗嗦!
你自己好好分析一下每个语句 ...

好的,问题解决了,慢慢在琢磨加深学习~
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-13 06:32

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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