190 likes | 305 Views
嵌入式系統入門. 嵌入式系統的範例. 微波爐 數位相機 家用遙測裝置. 微波爐. 嵌入式處理晶片. CPU. ROM. RAM. BUS. 輸入介面. 輸出介面. 輸入鍵. 開門. 馬達. 風扇. 磁電管. 燈具. 喇叭. 數位相機. 光學感應器. A/D 轉換. 馬達. 使用者開關. 系統控制器. 快閃單元. LCD 銀幕. 影像儲存裝置. 計算機介面. 連到 PC 的纜線. 嵌入式系統處理器區塊圖. 位址 資料 控制. 平行 I/O 連接埠. CPU. 序列 I/O 連接埠. 內部記憶體.
E N D
嵌入式系統的範例 • 微波爐 • 數位相機 • 家用遙測裝置 2
微波爐 嵌入式處理晶片 CPU ROM RAM BUS 輸入介面 輸出介面 輸入鍵 開門 馬達 風扇 磁電管 燈具 喇叭 3
數位相機 光學感應器 A/D 轉換 馬達 使用者開關 系統控制器 快閃單元 LCD銀幕 影像儲存裝置 計算機介面 連到 PC 的纜線 4
嵌入式系統處理器區塊圖 位址 資料 控制 平行 I/O 連接埠 CPU 序列 I/O 連接埠 內部記憶體 計時器/計數器 D/A轉換 A/D轉換 5
範例 :鍵盤與顯示 BUS 鍵盤 顯示裝置 DATAIN DATAOUT CPU INSTATUS OUTSTATUS 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 INSTATUS OUTSTATUS 1 : 代表輸入裝置已有資料進入 0 :代表輸入裝置沒有資料: 1 : 代表顯示裝置已準備好 0 :代表顯示裝置尚在處理上一個輸出中 6
記憶體映射 I/O • 將裝置的狀態暫存器與資料暫存器偽裝成記憶體的一部份 • 輸入 : 裝置介面卡會有一個偵測電路,一但偵測到位址匯流排上的位址代表其裝置時,就將裝置暫存器的值放到資料匯流排上. • 輸出 : 裝置介面卡會有一個偵測電路,一但偵測到位址匯流排上的位址代表其裝置時,就將資料匯流排上的資料設到對應暫存器當中. 0000 FFFB OUTSTATUS=FFFC DATA OUT =FFFD INSTATUS=FFFE DATAIN=FFFF 7
輸出入程式的設計 • 輸出入程式的設計方式大致可分為兩類 • 輪詢 (Polling) : • 不斷的偵測輸出入狀態,直到可以輸出入為止接著將資料輸出入到對應位址中 • 中斷 : • 搭配硬體,當有輸入發生時,硬體會通知 CPU,然後直接跳到預設好的中斷函數執行. 8
輸出入程式範例– 組合語言 • 程式功能 : 從鍵盤讀入一行字,並顯示到銀幕上. • 説明 : 以輪詢 (Polling) 的方式, 不斷從鍵盤讀入字元後, 顯示該字元到輸出裝置, 直到讀到換行字元為止. OUTSTATUS EQU $FFFC // 顯示器狀態 DATAOUT EQU $FFFD // 顯示暫存器 INSTATUS EQU $FFFE // 鍵盤狀態 DATAIN EQU $FFFF // 鍵盤暫存器 CR EQU $A // 換行字元 BUF DCD 100 // 輸入行儲存區 Move #BUF, R1 // R0 用來當儲存區指標,用以儲存下一個字元 READ TestBit #3, INSTATUS // 測試鍵盤是否有鍵被按下 Branch=0 READ // 一直測到有鍵被按下為止 MoveByte DATAIN, (R0) // 將該輸入鍵值儲存到儲存區 ECHO TestBit #3, OUTSTATUS // 測試顯示器是否可以輸出了 Branch=0 ECHO // 一直測試到可以輸出為止 MoveByte (R0), DATAOUT // 將剛剛讀入的鍵值送到顯示器顯示 Compare #CR, (R0)+ // 看看是否是換行字元 Branch!=0 READ // 若不是,則繼續讀下一個字 9
輸出入程式範例– C 語言 • 程式功能 : 從鍵盤讀入一行字,並顯示到銀幕上. • 説明 : 以輪詢 (Polling) 的方式, 不斷從鍵盤讀入字元後, 顯示該字元到輸出裝置, 直到讀到換行字元為止. #define OUTSTATUS (volatile char *) 0xFFFC // 顯示器狀態 #define DATAOUT (volatile char *) 0xFFFD // 顯示暫存器 #define INSTATUS (volatile char *) 0xFFFE // 鍵盤狀態 #define DATAIN (volatile char *) 0xFFFF // 鍵盤暫存器 void main() { char buf[100]; // buf = 輸入行儲存區 char* LOC=buf; // LOC = 輸入行儲存位址 while (1) { while (INSTATUS & 0x8 == 0) {} // 一直測到有鍵被按下為止 *LOC = *DATAIN; // 將該輸入鍵值儲存到儲存區 while (OUTSTATUS & 0x8 == 0) {} // 測試顯示器是否可以輸出了 *DATAOUT = *LOC; // 將剛剛讀入的鍵值送到顯示器顯示 LOC ++; // 前進到下一個字元 if (*LOC == ‘\n’) // 若是換行字元,則離開迴圈 break; } } 10
系統架構圖 VDD VDD VDD Go BCD轉7段式解碼器 BCD轉7段式解碼器 BCD轉7段式解碼器 … … … Stop PB7-4 PA7-4 PA3-0 3 2 1 0 CPU 計時器/計數器
反應計時器的功能 • 使用者按下 Go 開關後,啟動計時器 • 三秒後系統開啟 LED 的燈光 • 當使用者看到 LED 燈光後,必須盡速按下 Stop 鍵 • 系統會測量該使用者共花了多少時間才出現反應 (時間以 1/100 秒為單位, 以 X.XX 的形式出現在 三個 七段顯示器上) 13
記憶體空間映射 FFFFFFD0 FFFFFFD4 FFFFFFD8 FFFFFFD9 計時器初始值 CNTM 計時器內容值 COUNT 計時器相關資訊 計時器控制暫存器CTCONT 計時器狀態暫存器 CTSTAT FFFFFFF0 FFFFFFF1 FFFFFFF2 FFFFFFF3 FFFFFFF4 FFFFFFF5 FFFFFFF6 FFFFFFF7 輸入埠 A 資料 PAIN 輸出埠 A 資料 PAOUT 埠 A 的方向 PADIR 輸入埠 B 資料PBIN 輸出入相關資訊 輸出埠 B 資料 PBOUT 埠 B 的方向 PBDIR 輸出入狀態暫存器 PSTAT 輸出入控製暫存器 PCONT 14
輸出入相關資訊 7 6 5 4 3 2 1 0 IAOUT=1 A 輸出埠的中斷被引發了 IAIN=1 A 輸入埠的中斷被引發了 IBOUT=1 B 輸出埠的中斷被引發了 IBIN=1 B 輸入埠的中斷被引發了 PSTAT 輸出入狀態暫存器 PASIN IBOUT PASOUT IBIN PBSIN IAOUT PBSOUT IAIN 7 6 5 4 3 2 1 0 PCONT 輸出入控制暫存器 PASOUT=1 A 輸出埠的資料可寫入了 PASIN=1 A 輸入埠的資料可讀取了 PBSOUT=1 B 輸出埠的資料可寫入了 PBSIN=1 B 輸入埠的資料可讀取了 ENBOUT=1 B 輸出埠允許寫入資料 ENBIN=1 B 輸入埠允許讀取資料 ENAOUT=1 A 輸出埠允許寫入資料 ENAIN=1 A 輸入埠允許寫入資料 ENBOUT ENBIN ENAOUT ENAIN
計時器相關資訊 CTSTAT 計時控制暫存器 7 6 5 4 3 2 1 0 0:計數器 1:計時器 1:開始 1:停止 1:啟用中斷 CTCONT 計時狀態暫存器 7 6 5 4 3 2 1 0 1:計數器為 0 16
反應計時器的 C 語言程式 #define PAIN (volatile char*) 0xFFFFFFF0 // A 的輸入暫存器 #define PAOUT (char*) 0xFFFFFFF1 // A 的輸出暫存器 #define PADIR (char*) 0xFFFFFFF2 // A 的方向暫存器 #define PBIN (volatile char*) 0xFFFFFFF3 // B 的輸入暫存器 #define PBOUT (char*) 0xFFFFFFF4 // B 的輸出暫存器 #define PBDIR (char*) 0xFFFFFFF5 // B 的方向暫存器 #define CNTM (char*) 0xFFFFFFD0 // 計數暫存器 #define COUNT (char*) 0xFFFFFFD4 // 計時暫存器 #define CTCONT (char*) 0xFFFFFFD8 // 計時器狀態暫存器 void main() { unsigned int counter_value, total_value; unsigned int actual_time, seconds, tenths, hundredths; // Initialize the parallel ports. *PADIR = 0xFF; // A 連接到前兩個七段顯示器, 因此設定方向為輸出 *PBDIR = 0xF4; // 設定B前半方向為輸出, LED 為輸出, Go, Stop 鍵為輸入 *PAOUT = 0x0; // 七段顯示器顯示 0 *PBOUT = 0x4; // 熄滅LED 燈 17
反應計時器的 C 語言程式 - 續 while (1) { // 無窮迴圈 while ((*PBIN & 0x2) == 0); // 等待按下 Go 鍵 *CNTM = 300000000; // 設定計時器為300,000,000(三秒) *CTCONT = 0x1; // 啟動計時器 while ((*CTSTAT & 0x1) == 0); // 等候 3 秒鐘直到計時器到達 0 *PBOUT = 0x0; // 點亮 LED 燈 *CNTM = 0xFFFFFFFF; // 設定最大計時初始值 (下數計時器) *CTCONT = 0x1; // 開始計數 while ((*PBIN & 0x1) == 0); // 等待 Stop 鍵被按下 *PBOUT = 0x4; // 熄滅 LED 燈 *CTCONT = 0x2; // 停止計數 counter_value = *COUNT; // 計算總時間 total_count = (0xFFFFFFFF - counter_value); // 計算花費時間 (一億分之一秒為單位) actual_time = total_count / 1000000; // 除以百萬, 以百分之一秒為單位 seconds = actual_time / 100; // 取得秒數 tenths = (actual_time - seconds * 100) /10; // 取得 0.1 秒數 houndredths = actual_time - (seconds * 100 + tenths * 10); // 取得 0.01 的秒數 *PAOUT = ((seconds << 4) | tenths); // 顯示前兩個數字 *PBOUT = (houndredths << 4) | 0x4); // 顯示第三個數字, 同時熄滅LED.燈 } } 18
參考文獻 • Computer Organization, 5/e • Carl Hamacher, Zvonko Vranesic, Safwat Zaky • Section 2.7 : 輸出入作業 • Chapter 9 : 嵌入式系統 19