新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > PIC 單片機 C 語言編程簡介(3)

        PIC 單片機 C 語言編程簡介(3)

        作者: 時間:2016-11-22 來源:網絡 收藏
        例 11-5 C 語言中斷函數舉例

        本文引用地址:http://www.104case.com/article/201611/319597.htm

        PICC 會自動加入代碼實現中斷現場的保護,并在中斷結束時自動恢復現場,所以編程

        員無需象編寫匯編程序那樣加入中斷現場保護和恢復的額外指令語句。但如果在中斷服務程

        序中需要修改某些全局變量時,是否需要保護這些變量的初值將由編程員自己決定和實施。

        用 C 語言編寫中斷服務程序必須遵循高效的原則:

        &O1540; 代碼盡量簡短,中斷服務強調的是一個“快”字。

        &O1540; 避免在中斷內使用函數調用。雖然 PICC 允許在中斷里調用其它函數,但為了解決

        遞歸調用的問題,此函數必須為中斷服務獨家專用。既如此,不妨把原本要寫在其

        它函數內的代碼直接寫在中斷服務程序中。

        &O1540; 避免在中斷內進行數學運算。數學運算將很有可能用到庫函數和許多中間變量,就

        算不出現遞歸調用的問題,光在中斷入口和出口處為了保護和恢復這些中間臨時變

        量就需要大量的開銷,嚴重影響中斷服務的效率。

        中檔系列 PIC 單片機的中斷入口只有一個,因此整個程序中只能有一個中斷服務函數。

        11.6.5 標準庫函數

        PICC 提供了較完整的 C 標準庫函數支持,其中包括數學運算函數和字符串操作函數。

        在程序中使用這些現成的庫函數時需要注意的是入口參數必須在 bank0 中。

        如果需要用到數學函數,則應在程序前 “#include ” 包含頭文件;如果要使

        用字符串操作函數,就需要包含“#include ”頭文件。在這些頭文件中提供了函數

        類型的聲明。通過直接查看這些頭文件就可以知道 PICC 提供了哪些標準庫函數。

        C 語言中常用的格式化打印函數“printf/sprintf”用在單片機的程序中時要特別謹慎。

        printf/sprintf 是一個非常大的函數,一旦使用,你的程序代碼長度就會增加很多。除非是在

        編寫試驗性質的代碼,可以考慮使用格式化打印函數以簡化測試程序;一般的最終產品設計

        都是自己編寫最精簡的代碼實現特定格式的數據顯示和輸出。本來,在單片機應用中輸出的

        數據格式都相對簡單而且固定,實現起來應該很容易。

        對于標準 C 語言的控制臺輸入(scanf)/輸出(printf)函數,PICC 需要用戶自己編寫

        其底層函數 getch()和 putch()。在單片機系統中實現 scanf/printf 本來就沒什么太多意義,如

        果一定要實現,只要編寫好特定的 getch()和 putch()函數,你就可以通過任何接口輸入或輸

        出格式化的數據。


        11.7

        PICC 定義特殊區域值

        PICC 提供了相關的預處理指令以實現在原程序中定義單片機的配置字和標記單元。

        11.7.1 定義工作配置字

        在原程序中定義 PIC 單片機工作配置字的重要性在前面章節中已經闡述。在用 PICC 寫


        程序時同樣可以在 C 原程序中定義,具體方式如下:

        __CONFIG (HS & UNPROTECT & PWRTEN & BORDIS & WDTEN);

        上面的關鍵詞“__CONFIG”(注意前面有兩個下劃線符)專門用于是芯片配置字的設

        定,后面括號中的各項配置位符號在特定型號單片機的頭文件中已經定義(注意不是 pic.h

        頭文件),相互之間用邏輯“與”操作符組合在一起。這樣定義的配置字信息最后將和程序

        代碼一起放入同一個 HEX 文件。

        在這里列出了適用于 16F7x 系列單片機配置位符號預定義,其它型號或系列的單片機

        配置字定義方式類似,使用前查閱一下對應的頭文件即可。


        #define RC

        #define HS


        0x3FFF // RC 振蕩

        0x3FFE // HS 模式

        #define XT

        #define LP


        0x3FFD // XT 模式

        0x3FFC // LP 模式


        #define WDTEN 0x3FFF // 看門狗打開


        #define WDTDIS

        #define PWRTEN


        0x3FFB // 看門狗關閉

        0x3FF7 // 上電延時定時器打開


        #define PWRTDIS 0x3FFF // 上電延時定時器關閉

        #define BOREN 0x3FFF // 低電壓復位允許


        #define BORDIS


        0x3FBF // 低電壓復位禁止


        #define UNPROTECT 0x3FFF // 沒有代碼保護

        #define PROTECT 0x3FEF // 程序代碼保護

        例 11-6 頭文件預定義的配置信息符號

        11.7.2 定義芯片標記單元

        PIC 單片機中的標記單元定義可以用下面的__IDLOC(注意前面有兩個下劃線符)預處

        理指令實現,方法如下:

        __IDLOC (1234);

        其特殊之處是括號內的值全部為 16 進制數,不需要用“0x”引導。這樣上面的定義就設定

        了標記單元內容為 01020304。

        11.8


        MPLAB-IDE 中實現 PICC 的編譯選項設置

        在 11.3 節中已經介紹了如何實現 PICC 和 MPLAB-IDE 開發平臺的掛接。一旦項目建立


        成功、程序編寫完成后即可以通過 MPLAB 環境下的項目管理工具實現程序的編譯、連接和

        調試。它們的含義分別

        是:


        -項目維護(Make):MPLAB 檢查項目中的原程序文件,只編譯那些在上次編

        譯后又被修改過的原程序,最后進行連接;

        -項目重建(Build All):項目中的所有原程序文件,不管是否有修改,都將被

        重新編譯一次,最后進行連接。

        也可以通過 Project 菜單選擇“Make”或“Build All”實現項目編譯。不管采用何種方

        式,在啟動編譯過程前一般都要設定一些編譯選項。

        11.8.1 選擇單片機型號

        在選擇 PICC 作為語言工具并建立了項目后,同樣通過菜單項 Configure&O1616;Select Device

        在 MPLAB 環境中選擇具體單片機型號。請回顧一下例 11-1 的代碼,我們在原程序一開始

        使用了“#include ”實現了相關單片機的一些預定義符號的直接引用,但沒有具體指

        明是哪一個型號。實際上,“pic.h”頭文件只是一個簡單的管理工具(條件判別),它會按照

        MPLAB 所選擇的特定型號的單片機,把真正對應的頭文件包含進來。有興趣者可以直接用

        文本編輯工具打開 pic.h 文件查看其是如何根據不同的單片機型號包含對應的頭文件。

        這樣對編程員而言,程序中只需加上一句“#include ”即可。

        11.8.2 PICC 普通編譯選項(General)設定

        參考第三章 3.2.7 節的內容和圖 3-20 的指示說明,啟動編譯選項設定對話框。在使用

        PICC 語言工具時對話框的內容和用 MPAMS 匯編工具相比完全不同。圖 11-3 為 PICC 編譯

        環境下普通選項設定的界面。

        在此界面中用戶唯一能改變的是編譯器查找頭文件時的指定路徑(Include Path),實際

        上如果編譯器安裝沒有問題,在此界面中這些普通選項的設定無需任何改動,編譯器會自動

        到缺省認定的路徑中(編譯器安裝后的相關路徑)查找編譯所需的各類文件。

        %C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/9.jpg" src="file:///F:/data/%C3%83%C2%8F%C3%83%C2%82%C3%83%C2%94%C3%83%C2%98/PIC%C3%82%C2%B5%C3%82%C2%A5%C3%83%C2%86%C3%82%C2%AC%C3%82%C2%BB%C3%83%C2%BAC%C3%83%C2%93%C3%83%C2%AF%C3%83%C2%91%C3%83%C2%94%C3%82%C2%B1%C3%83%C2%A0%3Cwbr%3E%C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/9.jpg" /> %C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/10.jpg" src="file:///F:/data/%C3%83%C2%8F%C3%83%C2%82%C3%83%C2%94%C3%83%C2%98/PIC%C3%82%C2%B5%C3%82%C2%A5%C3%83%C2%86%C3%82%C2%AC%C3%82%C2%BB%C3%83%C2%BAC%C3%83%C2%93%C3%83%C2%AF%C3%83%C2%91%C3%83%C2%94%C3%82%C2%B1%C3%83%C2%A0%3Cwbr%3E%C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/10.jpg" />

        圖 11-3 PICC 普通選項設定圖 11-4 PICC 全局選項設定

        11.8.3 PICC 全局選項設定(PICC Global)

        全局選項將影響項目中所有 C 和匯編原程序的編譯,詳細的設定內容見圖 11-4。其中

        必須關注的有:

        &O1540; Compile for MPLAB ICD:如果你準備用 ICD 調試 C 語言編譯后的代碼,那么此項

        就必須打鉤選中。這樣編譯后的結果就能保證 ICD 本身使用的芯片資源(一小部

        分的程序和數據空間)不被應用程序所占用。

        &O1540; Treat ‘char’ as signed:為了提高編譯后的代碼效率,PICC 缺省認定‘char’型變量也

        是無符號數。如果在設計中需要使用帶符號的‘char’型變量,此項就應該被選中。

        &O1540; Floating point ‘double’ width:同樣為了提高編譯后的代碼效率,PICC 缺省認定

        ‘double’型的雙精度浮點數變量的實現長度為 24 位(等同于普通 float 型浮點數)。

        在這里可以選擇使其長度達 32 位。這樣數值計算的精度將得到提高,但代碼長度

        將增加,計算速度也會降低,所以請在權衡利弊后作出你自己的決定。

        11.8.4 C 編譯器選項設定(PICC Compiler)

        項目中所有的 C 原程序都將通過 C 編譯器編譯成機器碼,這些選項決定了 C 編譯器是

        如何工作的。所有選項又分為兩組:普通選項(General)和高級選項(Advanced),分別見

        圖 11-5A 和 11-5B。

        C 編譯器的普通選項最重要的就是針對代碼優化的設定。如果沒有特殊原因,應該設定

        全局優化級別為 9 級(最高級別優化),同時使用匯編級優化,這樣最終得到的代碼效率最

        高(長度和執行速度兩方面)。按筆者的使用經驗,僅從代碼長度去比較,使用最高級別優

        化后代碼長度至少可以減少 20%(2K 字以上的程序)。而且 PICC 的優化器相當可靠,一般

        %C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/11.jpg" src="file:///F:/data/%C3%83%C2%8F%C3%83%C2%82%C3%83%C2%94%C3%83%C2%98/PIC%C3%82%C2%B5%C3%82%C2%A5%C3%83%C2%86%C3%82%C2%AC%C3%82%C2%BB%C3%83%C2%BAC%C3%83%C2%93%C3%83%C2%AF%C3%83%C2%91%C3%83%C2%94%C3%82%C2%B1%C3%83%C2%A0%3Cwbr%3E%C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/11.jpg" /> %C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/12.jpg" src="file:///F:/data/%C3%83%C2%8F%C3%83%C2%82%C3%83%C2%94%C3%83%C2%98/PIC%C3%82%C2%B5%C3%82%C2%A5%C3%83%C2%86%C3%82%C2%AC%C3%82%C2%BB%C3%83%C2%BAC%C3%83%C2%93%C3%83%C2%AF%C3%83%C2%91%C3%83%C2%94%C3%82%C2%B1%C3%83%C2%A0%3Cwbr%3E%C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/12.jpg" />

        (A)常用選項 (B) 高級選項

        圖 11-5 C 編譯器選項設定

        不會因為使用優化從而使生成的程序出現錯誤。碰到的一些問題也基本都是用戶編寫的原程

        序有漏洞所導致,例如一些變量應該是 volatile 型但編程員沒有明確定義,在優化前程序可

        以正常運行,一旦使用優化,程序運行就出現異常。顯然,把出現的這些問題歸罪到編譯器

        是毫無道理的。

        使用優化后可能對原程序級的調試帶來一些不便之處。因 PICC 可能會重組編譯后的代

        碼,例如多處重復的代碼可能會改成同一個子程序調用以節約程序空間,這樣在調試過程中

        跟蹤原程序時可能會出現程序亂跳的現象,這基本是正常的。若為了強調更直觀的代碼調試

        過程,你可以將優化級別降低甚至關閉所有優化功能,這樣調試時程序的運行就可以按部就

        班了。

        C 編譯器的高級選項設定基本都是針對診斷信息輸出的,和生成的代碼無關。用得相對

        較多的選項有:

        &O1540; Generate assembly list file:編譯器生成 C 原程序的匯編列表文件(*.lst)。在此文件

        中列出了每一行 C 原代碼對應的匯編指令,但這些都是優化前的代碼。簡單的一

        C 語句被翻譯成匯編指令后可能有好幾條。有時匯編列表文件可以作為解決問

        題的輔助手段。如果你懷疑編譯器生成的代碼有錯誤,不妨先產生對應的匯編列表

        文件,看看在優化前一條 C 語句被編譯后的匯編碼到底是什么。

        &O1540; Compile to assembly only:這一選項的作用是把&n, bsp; C 原程序編譯成匯編指令文件

        (*.as),此時將不生成目標文件,也不進行最后的連接定位。這一選項在 C 和匯

        編混合編程時特別有用。通過解讀 C 程序對應的匯編指令,可以掌握 C 程序中存

        取變量的具體方法,然后用在自己編寫的匯編指令中。我們將在稍后專門做介紹。

        11.8.5 連接器選項設定(PICC Linker)

        連接器 PICC Linker 的選項基本不用作太多的改變,在圖 11-6 的對話框中顯示了可設定的各類

        項目。其中有兩項有用的信息輸出可以考慮加以利用:

        &O1540; Generate map file:生成連接定位映射文件。在此映射文件中詳細列出了所有程

        序用到的變量的具體物理地址;所有函數的入口地址;函數相互之間調用的層次關系和深度等。這

        些信息對于程序的調試將非常有用。此文件將以擴展名“*.map”的形式存放在同一個項目路徑

        下,需要時可以用任何文本編輯器打開觀察。

        %C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/13.jpg" src="file:///F:/data/%C3%83%C2%8F%C3%83%C2%82%C3%83%C2%94%C3%83%C2%98/PIC%C3%82%C2%B5%C3%82%C2%A5%C3%83%C2%86%C3%82%C2%AC%C3%82%C2%BB%C3%83%C2%BAC%C3%83%C2%93%C3%83%C2%AF%C3%83%C2%91%C3%83%C2%94%C3%82%C2%B1%C3%83%C2%A0%3Cwbr%3E%C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/13.jpg" />

        圖 11-6 PICC 連接器選項設定

        &O1540; Display memory-segment usage:顯示詳細的內存分配和使用情況報告。用戶可以

        了解到程序空間和數據存儲器空間資源分配的細節。下面列舉了在一個項目編譯后實際的內存使用

        信息,為方便理解筆者用“//”添加了一些注釋:

        Psect Usage Map: //程序段定位表

        Psect | Contents | Memory Range

        ----------|------------------------------|--------------------

        powerup | Power on reset code | $0000 - $0003

        intentry | Interrupt service routine | $0004 - $000C

        intcode | Interrupt service routine | $000D - $002C

        intret | Interrupt service routine | $002D - $0035

        init | Initialization code | $0036 - $003D

        end_init | Initialization code | $003E - $0040

        clrtext | Memory clearing code | $0041 - $0047

        const3 | Strings and constant data | $0048 - $0060

        const | Strings and constant data | $0061 - $0071

        const2 | Strings and constant data | $0072 - $0076

        text | Program and library code | $0576 - $0582

        text | Program and library code | $0583 - $07C7

        float_te | Arithmetic routine code | $07C8 - $07FF

        rbss_0 | Bank 0 RAM variables | $0021 - $0042

        temp | Temporary RAM data | $0043 - $0047

        nvram | Persistent RAM data | $0048 - $004A

        intsave | Registers saved on interrupt | $004B - $004D

        intsave | Registers saved on interrupt | $007F - $007F

        intsave_1 | Saved copy of W in bank 1 | $00FF - $00FF

        rbit_0 | Bank 0 bit variables | $0100 - $0104

        config | User-programmed CONFIG bits | $2007 - $2007

        Memory Usage Map:

        //程序空間代碼定位地址分布

        //存儲空間使用情況報告

        Program ROM $0000 - $0076 $0077 ( 119) words

        Program ROM $0576 - $07FF $028A ( 650) words

        $0301 ( 769) words total Program ROM

        //bank0 數據空間變量地址分布

        Bank 0 RAM $0021 - $004D $002D ( 45) bytes

        Bank 0 RAM $007F - $007F $0001 ( 1) bytes

        $002E ( 46) bytes total Bank 0 RAM

        //bank1 數據空間變量地址分布

        Bank 1 RAM $00FF - $00FF $0001 ( 1) bytes total Bank 1 RAM

        //bank0 數據空間位變量地址分布

        Bank 0 Bits $0100 - $0104 $0005 ( 5) bits total Bank 0 Bits

        //配置字地址

        Config Data $2007 - $2007 $0001 ( 1) words total Config Data

        Program statistics:

        //程序總體資源消耗統計

        Total ROM used 769 words (18.8%) //生成代碼字總數和程序空間使用率

        Total RAM used 48 bytes (25.0%) //使用數據字節數和數據空間使用率

        例 11-7 編譯后程序使用的內存信息

        11.8.6 匯編器選項設定(PICC Assembler)

        PICC 環境提供了自己的匯編編譯器,它和 Microchip 公司提供的 MPASM 編譯器在原

        程序的語法表達方面要求稍有不同。另外,PICC 的匯編編譯器要求輸入原程序文件的擴展

        名是“*.as”,而 MPASM 缺省認定的原程序以“*.asm”為擴展名。

        在基于 PICC 編譯環境下開發 PIC 單片機的 C 語言應用程序時基本無需關心其匯編編譯

        器,除非是在混合語言編程時用匯編語言編寫完整的匯編原程序模塊文件。其編譯選項設定

        的對話框見圖 11-7,最重要的是優化使能控制項“Enable optimization”,一般情況下應該使

        用匯編器的優化以節約程序空間。




        評論


        技術專區

        關閉
        主站蜘蛛池模板: 宁晋县| 霍林郭勒市| 巴彦县| 西乡县| 兴国县| 富裕县| 咸丰县| 车致| 扶余县| 乐业县| 江安县| 高陵县| 临泽县| 深水埗区| 温宿县| 吴忠市| 黔西县| 娄底市| 平乐县| 宣恩县| 青田县| 海淀区| 贞丰县| 乐安县| 湖口县| 贡山| 大新县| 中牟县| 汽车| 绥中县| 葵青区| 沂水县| 布尔津县| 和龙市| 岳普湖县| 九江市| 韶关市| 遵义县| 九龙县| 潮州市| 许昌市|