关于这行代码的C题。"while (--delay > 0);"

问题描述 投票:0回答:5

我正在使用 PIC 通过 ULN2003 驱动板控制 28BYJ-48 步进电机。我找到了一个完美运行的代码,但试图理解一行代码在做什么。

经过搜索,我过去没有遇到过这种情况。我是 C 编程的新手,正在学习其他人的代码。我在一段代码中遇到了这个问题,它的工作方式与我预期的一样。

if(Wait > 0) /* Wait is set in the void main void which calls this in the function*/
{
    delay = Wait;  /*delay takes the value of wait*/
    do {
       while(INTCONbits.T0IF == 0) {} 
       INTCONbits.T0IF = 0;
    } while (--delay > 0);
}

while (--delay > 0);
.

让我感到难过,因为延迟是从已知值中获取并传递给函数调用的,所以

--
与它有什么关系。

我知道有些语言在读取变量后用于递减变量,但据我所知,该值没有被降低。

任何帮助或指示将不胜感激。

编辑以显示更多代码。

void StepMotor(int16_t Count, uint8_t Wait)
{
    static uint8_t state = 0;
    /*  values for half step             0001, 0011, 0010, 0110, 0100, 1100, 1000, 1001*/
    static const uint8_t HalfSteps[8] = {0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09};
    uint8_t delay;

    do
    {
        if (Count > 0)
        {
            PORTC = HalfSteps[state];   /* drive stepper to select state */
            state++;                    /* step one state clockwise */
            state &= 0x07;              /* keep state within HalfStep table */
            Count--;                    /* update step count */
        }
        else if (Count < 0)
        {
            PORTC = HalfSteps[state];  /* drive stepper to select state */ 
            state--;                   /* step one state counterclockwise */ 
            state &= 0x07;             /* keep state within HalfStep table */ 
            Count++;                   /* update step count */ 
        }
        /* Wait between steps */
        if(Wait > 0) /* Wait is set in the void main void which calls this in the function*/
        {
            delay = Wait;  /*delay takes the value of wait*/
            do {
               while(INTCONbits.T0IF == 0) {} 
               INTCONbits.T0IF = 0;
            } while (--delay > 0);
        }
    } while (Count != 0);
}

void main(void) 
{
    /*
     * Application initialization
     */
    Init_PIC();
    /*
     * Application process loop
     */
    while(1)
    {
        StepMotor(4076, 4);     /* step about 1/2 a revolution clockwise at 4.096 milliseconds per step (about 8 seconds) */
        __delay_ms(1000);
        StepMotor(-2038, 2);    /* step about 1/2 a revolution counterclockwise at 2.048 milliseconds per step (about 4 seconds) */
        __delay_ms(1000);
        StepMotor(-2038, 2);    /* step about 1/2 a revolution counterclockwise at 2.048 milliseconds per step (about 4 seconds) */
        __delay_ms(1000);
    }
}

也许这对于回答我的问题什么是“while (--delay > 0);”更有帮助

做。

c pic
5个回答
2
投票

它递减延迟值,然后检查该值是否仍然大于零。如果是,循环体再次执行。


1
投票

John的问题起源于Microchip论坛上的这个topic

John 似乎在努力学习 C 编程语言的一些基本语法和概念。为了帮助 John,我创建了一个 MPLABX project 来演示我将如何格式化 C 语言文件并实现一个过程循环来执行所描述的动画序列。

John 需要考虑一些概念以完全理解代码和使用特定语法的选择。在 C 中一般有三种循环方式:

  • for(sss;ccc;iii);
    声明
  • while(ccc){}
    声明
  • do {} while(ccc);
    声明

请查阅任何 C 语言参考资料以了解有关这些差异的更多详细信息。

长期使用 Microchip C 编译器后,我发现它们生成了更好的代码,可以使用

do {} while(ccc);
语句将无符号值递减到零。

语法不太清晰

} while (--delay > 0);
的原因是XC8 C编译器将生成稍微更高效的机器代码。老实说,我经常写这种循环结构,现在它只是一种反射。我很抱歉使用了一种让你学习曲线上升得太快的语法。

您的问题得到如此好的回答真是太好了。一些心胸狭隘的偏执狂对你的问题投了反对票,这似乎是一种耻辱。对我来说,它似乎比这里出现的许多问题写得更好。

解决评论中提出的调试问题。 Microchip 不再销售用于 PIC16F676 的 AC162052 硬件调试头。没有它,这个目标的在线调试是不可能的。


1
投票

--i
接近
i --
,或
i = i - 1
.

虽然,还是有区别的!例如:(在这种情况下)

while(i-- > 0) something();
接近于:
      while(i > 0) { i --; something(); }
,但是
while(--i > 0) something();
接近于:
i --; while(i > 0) { something(); i --; }
.

我敢肯定它们之间还有其他一些奇怪的区别,你可以看看

pre-increment
post-increment
,正如萨克斯风已经建议的那样。

while(--i > 0);
只是递减
i
的值,直到它达到
0
.
do; while(--i > 0);
做所有事情,then递减
i
,所以它循环直到
i
达到
0
,但是
i
在循环之后只有
0
,循环内的最小
i
1 
.

int i = 4; // uint8_t and int are SIMILAR
do {
  printf("%d, ", i);
} while(--i > 0);
printf("after: %d", i);

输出:

4, 3, 2, 1, after: 0
.

uint8_t
是无符号 8 位整数。在这种情况下,无符号表示数字始终为正数,没有负号。


1
投票

让我们换一种方式,我希望这会有所帮助。

if(Wait > 0) /* Wait is set in the void main void which calls this in the function*/
{
    delay = Wait;  /*delay takes the value of wait*/
    do {
        while(INTCONbits.T0IF == 0) {} 
        INTCONbits.T0IF = 0;
        delay = delay - 1;
    } while (delay > 0);

}


1
投票

测试

(--delay > 0)
首先递减
delay
并将结果与
0
进行比较。
do
/
while
循环精确地迭代
delay
次,如果它输入的是
delay
的值,即
> 0
,因此初始测试
if (Wait > 0) {

这些

do
/
while
循环令人困惑且容易出错。

问题中的第一个片段更具可读性:

    for (delay = 0; delay < Wait; delay++) {
        while (INTCONbits.T0IF == 0)
            continue;
        INTCONbits.T0IF = 0;
    }

或者可能:

    for (delay = Wait; delay > 0; delay--) {
        while (INTCONbits.T0IF == 0)
            continue;
        INTCONbits.T0IF = 0;
    }

同样,由于

do
/
while
循环,在
StepMotor
中,即使
Count
的初始值为
0
,函数也会等待,这似乎是不必要的,因为步进电机不会移动所有。

这是一个替代方案:

void StepMotor(int16_t Count, uint8_t Wait) {
    static uint8_t state = 0;
    /*  values for half step             0001, 0011, 0010, 0110, 0100, 1100, 1000, 1001*/
    static const uint8_t HalfSteps[8] = {0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09};
    uint8_t delay;

    while (Count != 0) {
        if (Count > 0) {
            Count--;                   /* update step count */
            PORTC = HalfSteps[state];  /* drive stepper to select state */
            state++;                   /* step one state clockwise */
            state &= 0x07;             /* keep state within HalfStep table */
        } else {
            Count++;                   /* update step count */ 
            PORTC = HalfSteps[state];  /* drive stepper to select state */ 
            state--;                   /* step one state counterclockwise */ 
            state &= 0x07;             /* keep state within HalfStep table */ 
        }
        /* Wait between steps */
        for (delay = Wait; delay > 0; delay--) {
            while (INTCONbits.T0IF == 0)
                continue;
            INTCONbits.T0IF = 0;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.