- C51單片機應用與C語言程序設計
- 秦志強編著
- 1888字
- 2019-01-01 05:55:31
任務1 單燈閃爍控制
為了驗證P1口的輸出電平是不是由你編寫的程序輸出的電平,可以采用一個非常簡單有效的辦法,就是在想驗證的端口位接一個發(fā)光二極管。當輸出高電平時,發(fā)光二極管滅;輸出低電平時,發(fā)光二極管亮。
在本任務中,使用P1端口的第一腳(記為P1_0)來控制發(fā)光二極管以1Hz的頻率不斷閃爍。
LED電路元件
(1)紅色發(fā)光二極管2個;
(2)470Ω電阻2個。
LED電路搭建
按照圖2-2上部分所示電路,在智能機器人教學板的面包板上搭建起實際電路。實際搭建好的電路參考圖2-2下部分的照片。實際搭建電路時應注意:

圖2-2 發(fā)光二極管與I/O腳P1_0的連接
● 確認發(fā)光二極管的短針腳(陰極)插入通過電阻與P1_0相連;
● 確認發(fā)光二極管的長針腳(陽極)插入“VCC”插口。
例程:HighLowLed.c
● 接通面包板上的電源;
● 輸入、保存、下載并運行程序HighLowLed.c(整個過程請參考第1講);
● 觀察與P1_0連接的LED是否每隔一秒發(fā)光、關閉一次。
#include<BoeBot.h> #include<uart.h> int main(void) { uart_Init(); //初始化串口 printf("The LED connected to P1_0 is blinking!\n"); while(1) { P1_0=1; //P1_0輸出高電平 delay_nms(500); //延時500ms P1_0=0; //P1_0輸出低電平 delay_nms(500); //延時500ms } }
HighLowLed.c是如何工作的
與第1講程序相比,本例程多使用了一個頭文件BoeBot.h,在該頭文件中定義了兩個延時函數:void delay_nms(unsigned int i)與void delay_nus(unsigned int i)。
無符號整型數據unsigned int
與第1講講到的整型數據int相比,無符號整型數據unsigned int只有一個不同:數據的取值范圍從-32768~+32767變?yōu)?~65535,也就是說它只能取非負整數。
delay_nms( )是毫秒級的延時,而delay_nus( )是微秒級的延時。如果想延時1s,可以使用語句delay_nms(1000);1ms的延時則用delay_nus(1000)來完成。
注意:上述的延時函數是在外部晶振為12MHz的情況下設計的,如果外部晶振頻率不是12MHz,調用這兩個函數所產生的真正延時就會發(fā)生變化。
晶振的作用
單片機要能工作,就必須有一個標準時鐘信號,而晶振就為單片機提供標準時鐘信號。
uart_Init();串口初始化函數,在頭文件uart.h中實現,具體內容將在后面講節(jié)介紹。
調用printf是為了在程序執(zhí)行前給調試終端發(fā)送一條提示信息,告訴你現在程序開始執(zhí)行了,并告訴你程序隨后將開始干什么。這在以后的編程開發(fā)過程中形成一個良好的習慣,有助于提高程序的調試效率。代碼段為:
while(1) { P1_0=1; //P1_0輸出高電平 delay_nms(500); //延時500ms P1_0=0; //P1_0輸出低電平 delay_nms(500); //延時500ms }
上述程序是本例程的功能主體。首先看兩個大括號中的代碼:先給P1_0腳輸出高電平,由賦值語句P1_0=1完成,然后調用延時函數delay_nms(500),讓單片機微控制等待500ms,再給P1_0腳輸出低電平,即P1_0=0,然后再次調用延時函數delay_nms(500)。這樣就完成了一次閃爍。在程序中,你沒有看到P1_0的定義,它已經在由C語言為C51開發(fā)的標準庫中定義好,由頭文件uart.h包括進來。后續(xù)講節(jié)中將要用到的其他引腳名稱和定義都是如此。
注意:在所有計算機系統中,都用1表示高電平,0表示低電平,所以,P1_0=1就表示要向該端口輸出高電平,而P1_0=0就表示給該端口輸出低電平。
例程中兩次調用延時函數,讓單片機微控制器在給P1_0引腳端口輸出高電平和低電平之間都延時500ms,即輸出的高電平和低電平都保持500ms。
微控制器的最大優(yōu)點之一就是它們從來不會抱怨不停地重復做同樣的事情。為了讓單片機不斷閃爍,你需要把讓LED閃爍一次的幾個語句放在while(1){…}循環(huán)里。這里用到了C語言實現循環(huán)結構的一種形式——while語句。
while語句
while語句的一般形式如下:
while(表達式)循環(huán)體語句
當表達式為非0值時,執(zhí)行while語句中的內嵌語句,其特點是先判斷表達式,后執(zhí)行語句。例程中直接用1代替了表達式,因此總是非0值,所以循環(huán)永不結束,也就可以一直讓LED燈閃爍。
注意:循環(huán)體語句如果包含一個以上的語句,就必須用大括號(“{ }”)括起來,以復合語句的形式出現。如果不加大括號,則while語句的范圍只到while后面的第一個分號處。例如,本例中while語句中如果沒有大括號,則while語句的范圍只到“P1_0=1;”。
也可以不要循環(huán)體語句,如第1講例程中就直接用while(1),程序將一直停在此處。
在PBASIC編程語言中,需要循環(huán)的語句放在了DO?LOOP之間。
時序圖簡介
時序圖反應的是高、低電壓信號與時間的關系圖。在圖2-3中,時間從左到右增長,高、低電壓信號隨著時間在0~5V間變化。這個時序圖顯示的是剛才實驗中的1000ms的高、低電壓信號片段。右邊的省略號表示這些信號是重復出現的。

圖2-3 程序HighLowLed.c的時序圖
該你了——讓另一個LED閃爍
讓另一個連接到P1_1管腳的LED閃爍是一件很容易的事情,把P1_0改為P1_1,重新運行程序即可。
參考下面的代碼段修改程序:
uart_Init(); printf("The LED connected to P1_1 is blinking!"); while(1) { P1_1=1; //P1_1輸出高電平 delay_nms(500); //延時500ms P1_1=0; //P1_1輸出低電平 delay_nms(500); //延時500ms }
運行修改后的程序,確定能讓LED閃爍。
你也可以讓兩個LED同時閃爍。參考下面代碼段修改程序:
uart_Init(); printf("The LEDs connected to P1_0 and P1_1 are blinking!\n"); while(1) { P1_0=1; //P1_0輸出高電平 P1_1=1; //P1_1輸出高電平 delay_nms(500); //延時500ms P1_0=0; //P1_0輸出低電平 P1_1=0; //P1_0輸出低電平 delay_nms(500); //延時500ms }
運行修改后的程序,確定能讓兩個LED幾乎同時閃爍。
當然,你可以再次修改程序,讓兩個發(fā)光二極管交替亮或滅,也可以通過改變延時函數參數n的值,來改變LED的閃爍頻率。
嘗試一下!
- 用Proteus可視化設計玩轉Arduino
- 輕松學會單片機
- FPGA嵌入式項目開發(fā)三位一體實戰(zhàn)精講
- VxWorks設備驅動開發(fā)詳解
- TinyML:基于TensorFlow Lite在Arduino和超低功耗微控制器上部署機器學習
- 嵌入式Linux接口開發(fā)技術
- 51單片機逆向學習實戰(zhàn)教程(電子設計與嵌入式開發(fā)實踐叢書)
- 單片機應用技術
- 零起點學Proteus單片機仿真技術
- ANSYS Workbench 17.0有限元分析從入門到精通
- 基于STM32的嵌入式系統設計與實踐
- 51單片機工程師是怎樣煉成的:基于C語言+Proteus仿真
- 嵌入式系統與Qt程序開發(fā)
- STC 32位 8051單片機原理與應用
- C51單片機項目設計實踐教程(第2版)