- C51單片機應用與C語言程序設計
- 秦志強編著
- 821字
- 2019-01-01 05:55:32
任務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。你是否注意到當電機同時反向的時候,它們總是保持同步運行?這將有什么作用呢?