官术网_书友最值得收藏!

任務4 第一個程序

第一個C語言程序將告訴AT89S52單片機控制器,讓它在執行程序時發送一條信息給PC(或筆記本電腦)。

創建與編輯你的第一個程序

雙擊Keil uVision IDE的圖標,啟動Keil uVision IDE程序,你會得到如圖1-7所示的Keil uVision2 IDE的主界面。通過用Project菜單中的New Project命令建立項目文件,過程如下。

圖1-7 Keil uVision2 IDE的主界面

(1)單擊Project,會出現如圖1-8所示的菜單畫面,然后選擇“New Project”,將出現如圖1-9所示的對話框。

圖1-8 Project菜單

圖1-9 Create New Project對話框

(2)在文件名中輸入“HelloRoBot”,保存在你想保存的位置(如D:\C51單片機應用與C語言程序設計\程序\Chapter 1),可不用加后綴名,單擊“保存”按鈕,會出現如圖1-10所示的窗口。

圖1-10 單片機型號選擇窗口

(3)這里要求我們選擇芯片的類型,Keil uVision2 IDE幾乎支持所有的51核心單片機,并以列表的形式給出。本書使用的是ATMEL公司的AT89S52,在Keil uVision2 IDE提供的數據庫(Data base)列表中找到此款芯片,然后單擊“確定”按鈕,會出現如圖1-11所示的窗口,詢問你是否加載8051啟動代碼,在這里我們選擇“否”,不加載。(如果選擇“是”,對你的程序沒有任何影響。若你感興趣,可選擇“是”,看看編譯器加載了哪些代碼。)之后會出現如圖1-12所示畫面,此時即得到了項目文件。

圖1-11 是否加載8051啟動代碼提示窗口

圖1-12 目標工程窗口

項目文件創建后,這時只有一個框架,緊接著需要向項目文件中添加程序文件內容。Keil uVision2支持C語言程序。可以是已經建立好的程序文件,也可以是新建的程序文件。如果是建立好的程序文件,則直接用后面的方法添加;如果是新建立的程序文件,則先將程序文件.c存盤后再添加。

單擊按鈕(或通過“File→New”操作),為該項目新建一個C語言程序文件,保存后彈出如圖1-13所示的對話框,將文件保存在項目文件夾中,在文件類型中填寫.c(這里.c為文件擴展名,表示此文件類型為C語言源文件),因為下面將采用C語言編寫第一個程序。

圖1-13 C語言源文件保存對話框

例程:HelloRoBot.c

    #include<uart.h>
    int main(void)
    {
        uart_Init();//串口初始化
        printf("Hello,this is a message from your Robot\n");
        while(1);
    }

將該例程輸入Keil uVision IDE的編輯器,并以文件名HelloRoBot.c保存。下一步就是添加該文件到目標工程項目了,其具體添加過程如下。

(1)單擊圖1-12中的“+”,將出現如圖1-14所示的列表。

圖1-14 添加C語言文件到目標工程

(2)右鍵單擊“Source Group 1”,在出現的菜單下選擇“Add File To Group→Source Group 1”,出現Add Files to Group Source“Group1”對話框。在該對話框中選擇需要添加的程序文件,如剛才建立的HelloRoBot.c,單擊“Add”按鈕,把所選文件添加到項目文件中。一次可添加多個文件。

(3)程序文件添加到項目文件后,這時圖1-14中“Source Group 1”的前面將出現一個“+”號;單擊它將出現剛才添加的源文件名,如圖1-15所示(注意,圖中顯示的文件名是剛才輸入的文件名)。

圖1-15 添加了C語言文件的目標工程

雙擊源文件即可顯示源文件的編輯界面。

下面來生成下載需要的可執行文件。要生成可執行的.hex文件,需要對目標工程“Target 1”進行編譯設置,右鍵單擊“Target 1”,選擇“Option for target‘Target 1’”。單擊“output”,選擇其中的“Create HEX Fi:”,如圖1-16所示,單擊“確定”按鈕關閉設置窗口。單擊Keil uVision IDE快捷工具欄中的按鈕,Keil的C編譯器開始根據要生成的目標文件類型對目標工程項目中的C語言源文件進行編譯。編譯過程中,可以觀察到源文件中有沒有錯誤產生,如果沒有錯誤產生,在IDE主窗口的下面出現如圖1-17所示的提示信息,表明已成功生成了可執行文件,并存儲在C語言源程序存儲的目錄中,文件名就是HelloRoBot.hex。

圖1-16 設置目標工程的編譯輸出文件類型

圖1-17 編譯過程的輸出提示信息

下載可執行文件到單片機

單擊ISP下載軟件圖標,打開ISP下載軟件窗口,如圖1-18所示,并將通信參數設置成圖中所示的參數。

圖1-18 ISP軟件下載窗口

第一個列表框為接口類型選擇列表,該下拉列表中提供了許多接口類型:串口COM1~COM16、并口LPT1~LPT3,以及USB接口等。本書使用并口LPT1。

第二個列表框為下載速度選擇列表,該列表內容與接口類型緊密相連。接口不同,該列表就提供不同內容的下載速度。若選擇LPT1,則提供了5種下載速度:TURBO模式、FAST模式、NORMAL模式、SLOW模式和TURBO SLOW模式。在這5種模式下,程序下載速度依次減小。本書中的例程使用的是第一個模式:TURBO模式,下載速度最快。

第三個列表框為單片機型號選擇列表。

如何快速地認識新的軟件?

面對一款新的軟件,你可能有一種無從下手的感覺:這個是干什么的?那個又是干什么的?其實,軟件本身就提供了問題的答案。

每一款軟件都提供了幫助文檔。如SL ISP軟件界面的右上角有個“問號”按鈕,單擊它就彈出一系列的選項,這些選項就對該款軟件做出了大致的解釋,有助你快速掌握軟件的使用。

單擊“Flash”按鈕,選擇要下載的可執行hex文件——HelloRoBot.hex,選擇后單擊編程開始下載。如果下載成功,則在窗口下面顯示“完成次數:x次”,否則顯示“失敗次數:x次”。

如果芯片是第二次下載程序,先選中“擦除”復選框。

舉一反三

如果你學習過《基礎機器人制作與編程》這本書,并已經掌握了采用BASIC Stamp系列單片機模塊的PBASIC語言開發技能,請你與剛才介紹的C語言編程過程進行比較,看看有何不同。并思考一下,這些不同對于初學者而言各有何優缺點。是不是復雜很多?

用串口調試軟件查看單片機輸出信息

打開串口調試終端,選擇串口“COM1”后單擊“打開串口”按鈕,在“接收區”內你看到了什么?什么也沒有!為什么呢?因為從把執行文件成功下載到單片機的那個時刻開始,程序就開始運行了:單片機已經向PC發送了信息。你錯過了接收。怎么辦呢?

在機器人教學板上提供了“Reset”按鈕,它可以讓下載到單片機內的程序重新運行一次。按下“Reset”按鈕,是不是出現如圖1-19所示的畫面呢?

圖1-19 串口調試終端

HelloRoBot.c是如何工作的

要講清楚C語言的第一個程序是如何工作的,要比BASIC語言復雜很多。因為C語言是一個非常龐大的系統,是為開發大型程序而準備的。即使是最小的一個程序,其框架結構也很復雜。

例程中第一行代碼是HelloRoBot.c所包含的頭文件。該頭文件在編譯過程中用來將下面程序中需要用到的標準數據類型和由C語言編譯器提供的一些標準輸入/輸出函數、中斷服務函數等包括進來,生成可執行代碼。頭文件中可以嵌套頭文件,同時也可以直接定義一些常用的功能函數。本例程中的頭文件uart.h在本書的后續任務中都要用到,它其中就包含了本例程中,以及后面的例程中都要用到的uart_Init()函數的定義和實現。

下面先介紹函數的概念。一個較大的C語言程序一般分成若干個模塊,每個模塊實現一定的功能,我們稱之為函數。任何一個C語言程序本身就是一個函數,該函數必須以main函數作為程序的起點,通常稱之為主函數。主函數可以調用任何子函數,子函數之間也可以相互調用(但是不可以調用主函數)。函數定義的一般格式為:

函數返回值的類型 函數名(形式參數1,形式參數2,……)

第二行就是程序的入口main函數。main前面的int是指定main的函數返回值類型為整數類型,括號中void或無內容表示沒有形式參數。每個函數的主體都要用“{}”括起來(反思一下同PBASIC語言編程的區別)。

函數的具體應用將在第3講介紹。

main函數主體中有兩行語句:第一行是串口初始化函數uart_Init(),用來規定單片機串口是如何與PC通信的。有興趣的讀者可以打開uart.h頭文件,看看該函數是如何實現的。如果其中有很多內容不懂,不要緊,記住這個函數的功能就行,以后慢慢學習和理解。這行語句中“//”后的是注釋。注釋是一行會被編譯器忽視的文字,不被編譯,僅僅為了讓人閱讀程序方便。函數體中的第二行語句printf命令是單片機通過串口向PC發送一條信息。

printf函數

printf函數稱為格式輸出函數,其功能是按用戶指定的格式,把指定的數據顯示輸出。該函數是C語言提供的標準輸出函數,定義在C語言的標準函數庫中,要使用它,必須包括定義標準函數庫的頭文件stdio.h。由于在uart.h頭文件中包括了stdio.h,因此本例程無須另外包括該頭文件。printf函數的一般形式為:

    printf(“格式控制字符串”,輸出列表);

格式控制字符串可由格式字符串和非格式字符串組成。

格式字符串是以%開頭的字符串;輸出列表在格式輸出時才用到,它給出了各個輸出項,要求與格式字符串在數量和類型上一一對應。

非格式字符串在輸出時原樣輸出,在顯示中起提示作用。例程中用到的就是非格式字符串。

“\n”是一個向調試終端發送回車命令的控制符。也就是說,當單擊“Reset”按鈕再次運行程序時,將在下一行顯示“Hello,this is a message from your Robot”;如果沒有“\n”,則會在上一語句中的結尾,即“Robot”后面接著顯示。

while(1);的作用

while是C語言里的循環控制語句,它的具體語法將在第2講里介紹,這里講解為何要加上這個循環。

hex文件是加載在單片機Flash存儲器上的,并且是從頭開始往下加載。當你把hex文件加載上去時,填滿了整個Flash空間嗎?當然沒有!那么,當程序執行完printf函數之后,它還將向下執行,但后面的空間并沒有存放程序代碼,這時程序會亂運行,也就是發生了跑飛現象。

加上while(1);語句,讓程序一直停止在這里,就是為了防止程序跑飛。

該你了——例程:HelloRoBotYourTurn.c

    #include<uart.h>
    int main(void)
    {
        int i;
        uart_Init();
        i=7*11;
        printf("What's 7 X 11?\n");
        printf("The answer is:%d\n",i);
        while(1);
    }

按照上述方法建立新的項目,輸入程序HelloRoBotYourTurn.c并運行,查看輸出結果,是否與圖1-20一樣?

圖1-20 例程HelloRoBotYourTurn.c輸出結果

HelloRoBotYourTurn.c是如何工作的

在介紹main函數內容之前,先講解一下C語言的一些基本知識。

C語言數據類型

C語言有5種基本數據類型:字符、整型、單精度實型、雙精度實型和空類型。這些數據類型的長度和范圍會因處理器的類型和C語言編譯程序的實現而有所不同,對于Keil51產生的目標文件,表1-1給出了兩種書中常用的數據長度和范圍。

表1-1 常用數據類型的長度和范圍

標志符

在C語言中,標志符是對變量、函數名和其他各種用戶定義對象的命名。標志符的長度可以是一個或多個字符。絕大多數情況下,標志符的第一個字符必須是字母或下畫線,隨后的字符必須是字母、數字或下畫線(某些C語言編譯器可能不允許下畫線作為標志符的起始字符)。表1-2是一些正確或錯誤標志符命名的實例。

表1-2 正確或錯誤標志符命名實例

常量

C語言中的常量是不接受程序修改的固定值,常量可以為任意數據類型,如下例所示。

    char 'a'、'9'
    int 21、-234

變量

在程序中可以改變的量稱為變量。一個變量應該有一個名字(標志符),在內存中占據一定的存儲單元,在該存儲單元中存放變量的值。請注意區分變量名和變量值這兩個不同的概念。所有C語言變量必須在使用之前定義。定義變量的一般形式是:

    type variable_list;

這里的type必須是有效的C數據類型,variable_list(變量表)可以由一個或多個由逗號分隔的多個標志符名構成。下面給出一些定義的范例:

    int i,j,k;
    char'x','y','z';

注意:C語言中變量名與其類型無關。

運算符

C語言有3大運算符:算術、關系與邏輯、位操作。另外,C語言還有一些特殊的運算符,用于完成一些特殊的任務。

算術運算符

表1-3給出了C語言允許的算術運算符。在C語言中,運算符“+”、“-”、“*”和“/”的用法與大多數計算機語言的相同,幾乎可以用于C語言內定義的任何數據類型。

表1-3 算術運算符

表達式

表達式由運算符、常量及變量構成。C語言的表達式遵循一般代數規則。

C語言規定,任何表達式在其末尾加上分號就構成為語句。

賦值運算符

賦值運算符記為“=”。由“=”連接的式子稱為賦值表達式,其后加分號構成賦值語句,其一般形式為:

變量=表達式;

現在,來看看main函數是如何工作的。

    int i;

定義了一個整型變量i。i即是變量的標志符,分號表示結束。

    uart_Init();

與上一個例程一樣,規定單片機串口如何與PC通信。

    i=7*11;

將表達式“7*11”的值賦給變量i,也就是說變量i的值為77。

    printf("What's 7*11?\n");

輸出“What’s 7*11?”,這里printf的用法與上一個例程一樣。

    printf("The answer is:%d\n",i);

這里用到了printf函數的格式字符串輸出。%d是指定輸出數據的類型為十進制整數。printf函數首先輸出“The answer is:”;然后它遇到了“%d”,表示將后面輸出列表中的變量以十進制的形式輸出,即將變量i以“77”的形式輸出;最后的輸出結果即為:The answer is:77

最后一條語句while(1);也起到與在上例中同樣的作用:防止程序跑飛。

主站蜘蛛池模板: SHOW| 锡林浩特市| 万宁市| 潜山县| 陈巴尔虎旗| 垫江县| 美姑县| 富民县| 肇庆市| 师宗县| 荣昌县| 油尖旺区| 洛南县| 长宁县| 太康县| 丹寨县| 隆回县| 昭平县| 通州区| 微山县| 通许县| 蓬安县| 资中县| 武汉市| 梓潼县| 隆化县| 蓬莱市| 土默特左旗| 靖安县| 海城市| 青冈县| 塔城市| 镇原县| 牡丹江市| 蒲城县| 大埔县| 昌乐县| 垫江县| 渝中区| 新密市| 长治市|