任务3 计数并控制循环次数
任务2中已经通过对C51编程实现对机器人伺服电机的控制,为了让微控制器不断发出控制指令,你用到了以while(1)开头的死循环(即永不结束的循环)。不过在实际的机器人控制过程中,你会经常要求机器人运动一段给定的距离或者一段固定的时间,这时就需要能控制代码执行的次数。
for语句
最方便的控制一段代码执行次数的方法是利用for循环,语法如下:
for(表达式1;表达式2;表达式3)语句
它的执行过程如下:
(1)求解表达式1。
(2)求解表达式2,若其值为真(非0),则执行for语句中指定的内嵌语句,然后执行下面第(3)步;若其值为假(0),则结束循环,转到第(5)步。
(3)求解表达式3。
(4)转回第(2)步继续执行。
(5)循环结束,执行for语句下面的一个语句。
for语句最简单的应用形式,也就是最易理解的形式如下:
for(循环变量赋初值;循环条件;循环变量增/减值)语句
例如,下面是一个用整型变量myCounter来计数的for循环程序片段。每执行一次循环,它会显示myCounter的值。
for(myCounter=1;myCounter<=10;myCounter++) { printf("%d",myCounter); delay_nms(500); }
在这里,向你介绍新的算术运算符。
自增和自减
C语言有两个很有用的运算符——自增和自减,即“++”和“--”。
运算符“++”是操作数加1,而“--”是操作数减1。换句话说:“x=x+1”同“x++”;“x=x-1”同“x--”。
myCounter ++的作用就相当于myCounter=myCounter+1,只不过这样用起来更简洁。这也是C语言的特点,灵活简洁。
该你了——不同的初始值和终值及计数步长
你可以修改表达式3来使myCounter以不同步长计数,而不是按9,10,11,…来计,你可以让它每次增加2(9,11,13,…)或增加5(10,15,20,…)或任何你想要的步进,递增或递减都可以。下面的例子是每次减3。
for(myCounter=21;myCounter>=9;myCounter=myCounter-3) { printf("%d\n",myCounter); delay_nms(500); }
for循环控制电机的运行时间
到目前为止,你已经理解了脉冲宽度控制连续旋转电机速度和方向的原理。控制电机速度和方向的方法是非常简单的。控制电机运行的时间也非常简单,那就是用for循环。
下面是for循环的例子,它会使电机运行几秒钟。
for(Counter=1;Counter<=100;i++) { P1_1=1; delay_nus(1700); P1_1=0; delay_nms(20); }
让我们来计算一下这个代码能使电机转动的确切的时间长度。每通过循环一次,delay_nus(1700)持续1.7 ms,delay_nms(20)持续20ms,其他语句的执行时间很少,可忽略。那么for循环整体执行一次的时间是:1.7 ms+20 ms=21.7ms,本循环执行100次,即就是21.7ms乘以100,时间=21.7ms×100=0.0217s×100=2.17s。
假如要让电机运行4.34s,for循环必须执行上面两倍的时间。
for(Counter=1;Counter<=200;i++) { P1_1=1; delay_nus(1700); P1_1=0; delay_nms(20); }
例程:ControlServoRunTimes.c
● 输入、保存并运行程序ControlServoRunTimes.c;
● 验证是否与P1_1连接的电机逆时针旋转2.17s,然后与P1_0连接的电机旋转4.34s。
#include<BoeBot.h> #include<uart.h> int main(void) { int Counter; uart_Init(); printf("Program Running!\n"); for(Counter=1;Counter<=100;Counter++) { P1_1=1; delay_nus(1700); P1_1=0; delay_nms(20); } for(Counter=1;Counter<=200;Counter++) { P1_0=1; delay_nus(1700); P1_0=0; delay_nms(20); } while(1); }
假如想让两个电机同时运行,给与P1_1连接的电机发出1.7ms的脉宽,给与P1_0连接的电机发出1.3ms的脉宽,现在每通过循环一次要用的时间是:
1.7ms——与P1_1连接的电机
1.3ms——与P1_0连接的电机
20 ms——中断持续时间
----------------------------------------
一共是23 ms
如果想使机器人运行一段确定的时间,可以计算如下:
脉冲数量=时间/0.023s=时间/0.023
假如想让电机运行3s,计算如下:
脉冲数量=3/0.023= 130现在,可以将for循环中作如下修改,程序如下:
for(counter=1;counter<=130;i++) { P1_1=1; delay_nus(1700); P1_1=0; P1_0=1; delay_nus(1300); P1_0=0; delay_nms(20); }
例程:BothServosThreeSeconds.c
下面是一个使电机向一个方向旋转3s,然后反向旋转的例子。
● 输入、保存并运行程序BothServosThreeSeconds.c;
#include<BoeBot.h> #include<uart.h> int main(void) { int counter; uart_Init(); printf("Program Running!\n"); for(counter=1;counter<=130;counter++) { P1_1=1; delay_nus(1700); P1_1=0; P1_0=1; delay_nus(1300); P1_0=0; delay_nms(20); } for(counter=1;counter<=130;counter++) { P1_1=1; delay_nus(1300); P1_1=0; P1_0=1; delay_nus(1700); P1_0=0; delay_nms(20); } while(1); }
验证每个机器人是否沿一个方向运行3s,然后反方向运行3s。你是否注意到当电机同时反向的时候,它们总是保持同步运行?这将有什么作用呢?