我正在使用 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);”更有帮助
做。
它递减延迟值,然后检查该值是否仍然大于零。如果是,循环体再次执行。
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 硬件调试头。没有它,这个目标的在线调试是不可能的。
--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 位整数。在这种情况下,无符号表示数字始终为正数,没有负号。
让我们换一种方式,我希望这会有所帮助。
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);
}
测试
(--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;
}
}
}