跳轉到內容

嵌入式系統/PIC程式設計

來自華夏公益教科書,開放的書籍,開放的世界

本模組假設

  • 您,讀者,瞭解一些使用 C 和彙編的程式設計知識。
  • 您擁有 MPLAB ICD 2 和 PICDEM 2 Plus 演示板。
  • 您已 選擇了一個 PICmicro 微控制器,並希望對其進行程式設計。(本書中的示例將重點介紹 PIC18F452 微控制器,因為它隨演示板一起提供。相同流程適用於大多數其他 PICmicro。)

在開始之前,

  • Microchip Technology Inc 安裝最新的 MPLAB IDE 和 MPLAB C18 編譯器。在編寫本書時,最新的 MPLAB 版本是 7.40。

簡單 I/O 入門

[編輯 | 編輯原始碼]

我們將從使用 PORTA 和 PORTB 的簡單輸入輸出程式開始。讓我們點亮電路板上的 LED。我們應該將值 0x0A 分配給 PORTB。這將點亮 RB3 和 RB1 上的 LED。每次按下 RA4 上的開關按鈕時,值將被取反;因此 LED 將在 RB3/RB1 和 RB2/RB0 之間切換。

首先,啟動 MPLAB IDE。在選單欄中,選擇“專案”→“專案嚮導”。點選“下一步”,然後選擇 PIC18F452 作為您的裝置。再次選擇“下一步”。在“活動工具套件”下,選擇 Microchip C18 工具套件,在“工具套件內容”下選擇 MPLAB C18 C 編譯器 (mcc18.exe)。現在,我們必須給專案命名併為其選擇一個目錄。由於我們將進行簡單的 I/O 操作,讓我們將其命名為 Simple_IO。然後選擇一個目錄。在這種情況下,我將使用 c:\example\simpleIO。點選“下一步”按鈕。我們沒有要新增到專案中的任何檔案。所以,再次點選“下一步”按鈕。現在,我們已經完成了專案嚮導。點選“完成”按鈕。

專案設定完成後,我們應該建立一個名為 SimpleIO.c 的 C 檔案。在選單欄中,選擇“檔案”→“新建”。新編輯器彈出後,選擇“檔案”→“另存為”。在新的視窗中,將新建立的檔案儲存為 SimpleIO.c。在“專案視窗”(其中 Simple_IO.mcv 是標題)中,右鍵單擊“原始檔”。從選單中選擇“新增檔案...”。從您剛才儲存的位置選擇 SimpleIO.c。在同一個視窗中,選擇“連結器指令碼”,然後從選單中選擇“新增檔案...”。在 Microchip C18 C 編譯器目錄下(預設情況下是 C:\MCC18),轉到 c:\安裝目錄/lkr 並輸入 18f452.lkr 作為檔名。將以下程式碼輸入編輯器。

#include <p18f452.h>

// Configurations
#pragma config OSC = HSPLL, OSCS = ON, PWRT = ON, BOR = OFF, WDT = OFF, LVP = OFF

// Main body
void main() {

    // Initializing ports
    PORTA = 0;
    PORTB = 0;

    // Set RA4 as input and RB3-RB0 as output
    TRISA |= 0x10;
    TRISB &= 0xF0;

    // Set value 0x0A to PORTB
    PORTB = 0x0A;
	
    // If button is pressed, toggle PORTB
    while(1) {
        if(PORTAbits.RA4 != 0)
            PORTB = ~PORTB;
    }
}

點選工具欄上的“儲存”按鈕,或從選單欄中選擇“檔案”→“儲存”。接下來,點選“專案”→“全部構建”或工具欄頂部的“全部構建”按鈕。確保在“輸出”視窗中沒有錯誤或警告。將您的 MPLAB ICD 2 連線到您的電腦,並將 PICDEM 2 Plus 演示板連線到 ICD(請參閱提供的說明書)。現在,選擇“偵錯程式”→“選擇工具”→“MPLAB ICD 2”。確保輸出視窗中沒有錯誤。接下來,點選“偵錯程式”→“程式設計”來對微控制器進行程式設計。成功對微控制器進行程式設計後,點選“偵錯程式”→“執行”。您也可以點選工具欄上的“執行”按鈕。在演示板上,RB3 和 RB1 上的 LED 應該亮起。

現在,在演示板上多次按下 RA4 上的開關。注意到有什麼不對勁嗎?LED 會閃爍,但不會一直地在 RB3/RB1 和 RB2/RB0 之間切換。如果您只是按下開關而沒有鬆開,所有 LED 都會亮起。這不是我們想要的結果。讓我們再次檢視程式碼,找出問題所在。請注意,在 while 迴圈中,只要 RA4 讀取到 0,PORTB 上的值就會被反轉。由於微控制器以 16 MHz 的速度執行,快速按下開關,最多可能消耗 500us,可能會導致 PORTB 中的值反轉超過 1000 次。這就是為什麼 LED 似乎會在每次按下開關時隨機亮起的原因。必須修改程式碼以檢測開關的按下和鬆開。

LED 閃爍

[編輯 | 編輯原始碼]

材料

  • 來自“PIC16F877A 入門”的電路
  • 100 歐姆電阻
  • LED

電路

  1. 引腳 RB7 連線到電阻
  2. 電阻連線到 LED
  3. LED 連線到地

程式碼

//all these # below set up the PIC
#include <16F877A.h>
#device adc=8
#FUSES NOWDT      //No Watch Dog Timer
#FUSES HS         //Highspeed Osc > 4mhz
#FUSES PUT        //Power Up Timer
#FUSES NOPROTECT  //Code not protected from reading
#FUSES NODEBUG    //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP      //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD      //No EE protection
#use delay(clock=20000000) 				// Sets crystal oscillator at 20 megahertz
#use rs232(baud=9600, xmit=PIN_C6, invert) //Sets up serial port output pin & baud rate

//main program starts here
void main() {
   //Infinite program loop starts.  LED blinks forever.
   while(true){
      output_high(PIN_B7);    //send a “1” to pin RB7, making RB7 “High” at 5v
				//this will turn on the LED hooked to RB7
      delay_ms(500);  		//wait half a second, delays for 500ms 
      output_low(PIN_B7);     //send a “0” to pin RB7, making RB7 “Low” at 0v
      delay_ms(500);		//wait half a second, delays for 500ms
   }
}

說明

您可以輕鬆地新增更多 LED,並使它們以不同的模式閃爍。為了使程式碼更易讀,請使用

#define RED_LED   PIN_B7
#define GREEN_LED PIN_B6
…
…
output_high(RED_LED);
output_high(GREEN_LED);

編譯器,彙編器

[編輯 | 編輯原始碼]

進一步閱讀

進一步閱讀

[編輯 | 編輯原始碼]

嵌入式系統

華夏公益教科書