[ SDCC For 8051 ] 02-General Purpose Input/Output-GPIO
8051 / C51 系列微處理器從 80 年代問世以來普遍應用於各種消費與工業領域,具備 4 組雙向 I/O 埠總共有 32 腳位可以做為外接裝置介面。本文章介紹 8051 的通用輸入輸出埠 GPIO並以發光二極體 LED 作為操作演示。
8051 的 GPIO
8051 具有 4 組通用輸出輸入埠 ( General Purpose Input/Output, GPIO ) 其中每一組各具備 8 個雙向腳位,因此一個 8051 微處理器擁有 32 雙向對外溝通腳位。
我們可以從系統方塊圖了解到各 I/O 埠的名稱。
從系統方塊圖可以得知共有 P0 、P1、P2、P3 等四組埠口,除此之外因應燒錄程式與對外延伸記憶體控制還有 EA,ALE,PSEN,Vcc,GND,RST,XTAL等,常見的 PDIP 直插式包裝如下圖所示。
各腳位功能說明如下。
回到目錄
GPIO 的控制
8051 的 I/O 埠各擁有一組 8 位元暫存器做控制且配有位址提供操作使用各個 I/O 埠可以位元定址,其位址如下所示。
撰寫程式時我們不需要特別去指定各個埠口位址,標頭檔如內部已經將各個暫存器位址寫好。由於 I/O 埠屬於特殊功能暫存器 ( Special Function Register, SFR ),使用時為了程式的可讀性會將 I/O 埠口指定一個標籤與位址關鍵字 sfr 可以用來指定特殊功能暫存器,例如 Port 0 寫成 sfr P0 = 0x80,表示指定標籤 P0 的位址為 0x80 而 0x80 在 8051 中就是埠口 0 ,因為每個埠口各自擁有 8 位元分別控制 8 個腳位作為對外聯絡介面,在程式當中也會賦予各個腳位一個標籤,例如 P0_0 代表 Port 0 的 Bit 0 腳位其位址為 0x80,P0_1 代表 Port 0 的 Bit 1 腳位其位址為 0x81,依此類推,由於開發平台採用的編譯器不同使得語法會稍有不同,但是原理都是一樣的。
回到目錄
電路圖
回到目錄
新建專案
本次使用 8051 的 Port1 的低 4 位元控制外接 LED 燈,讓燈號依序亮滅並持續重複動作。
由於 LED 燈有外接電源因此要讓 LED 燈亮則腳位需輸出低電位,反之輸出高電位則 LED 燈滅。
在 Embedded IDE 中點擊 New Project,選擇 Internal Template 內建模板
,接著選擇 89C52 SDCC Quickstart 。
最後輸入專案名稱,例如本專案命名為 LED,輸入完成後按下 Enter 鍵並選擇存放資料夾即完成專案的建立。
專案建立完成後右下角會有提示是否切換工作目錄,可以選擇 Yes 自動切換。
回到目錄
撰寫程式
切換到工作目錄後可以看到自動建立的檔案,點開資料夾 src 旁的 > 箭頭符號可以開啟該目錄,裡面有一名為 main.c 的檔案就是主程式所在。滑鼠左鍵點擊 main.c 打開檔案後會看到自動建立的程式碼,我們可以全選後刪除重新撰寫。
程式流程圖
首先引入標頭檔 < lint.h > 與 < 8051.h >。
#include <lint.h>
#include <8051.h>
為了能讓眼睛看到 LED 亮滅因此需要延遲一段時間,建立名為 delay 的副程式。
void Delay(unsigned int cnt)
{
while( cnt > 0) cnt — ;
}
進入主程式首先做初始設定將 Port1 全輸出 1 讓 LED 燈全滅。
並且宣告一個變數儲存 LED 燈輸出狀態。
void main(void)
{
P1 = 0xFF;
unsigned char LED = 0x01;
}
最後,進入無限迴圈將 LED 燈狀態輸出並稍作延遲後依序點亮下一個 LED 燈。
While(1)
{
P1 = ~LED; // 將 LED 取反向後輸出至 Port 1
Delay(20000);
LED = LED << 1; // LED = 0x01 / 0x02 / 0x04 / 0x08
if(LED > 0x08) LED = 0x01;
}
回到目錄
編譯與成果
程式撰寫完成後回到 Embedded IDE 環境,點開專案名稱後按下編譯鍵進行編譯。
完成後畫面底下終端機會顯示編譯過程並提示按下任意鍵關閉終端機。
回到專案目錄,在 Bulid \ Debug 目錄底下可以找到後綴 .hex 的檔案,即編譯完成可以進行燒錄。
成果
回到目錄
總結
本文章演示使用 VScode 與 Embedded IDE 環境操作 8051 的 GPIO,總結如下。
- 8051 有 4 組 I/O 埠口分別是 P0、P1、P2、P3。
- P0 ~ P3 由特殊功能暫存器 SFR 控制。
- 各埠口擁有獨立位址 P0=0x80,P1=0x90,P2=0xA0,P3=0xB0。
- 每一組埠口擁有 8 個雙向 I/O。
- P0 內部有 Open-Drain 輸出結構,若要作為輸出使用外部需接上拉電阻。
- P1 ~ P3 內部配有上拉電阻。
回到目錄
完整程式碼
#include<lint.h>
#include<8051.h>
void Delay(unsigned int cnt)
{
while(cnt > 0) cnt--;
}
void main(void)
{
P1 = 0xFF;
unsigned char LED = 0x01;
while (1)
{
P1 = ~LED;
Delay(20000);
LED = LED << 1;
if(LED > 0x08) LED = 0x01;
}
}