680 likes | 809 Views
第 4 章. I/O 埠基本輸入輸出控制. 基本輸入輸出控制. LED 7 段顯示器 指撥開關 按鈕開關 四位數 7 段顯示器多工掃描 文字型 LCD. I/O 埠結構圖. 埠結構圖 ( 輸出 ). 埠結構圖 ( 下拉輸入 ). 埠結構圖 ( 上拉輸入 ). A 埠相關的暫存器. P_IOA_Dir( 讀 / 寫 )($7002H ) A 埠的方向暫存器 P_IOA_Attrib( 讀 / 寫 )($7003H) A 埠的屬性暫存器 P_IOA_Data( 讀 / 寫 )($7000H) A 埠的資料暫存器
E N D
第4章 I/O埠基本輸入輸出控制
基本輸入輸出控制 • LED • 7段顯示器 • 指撥開關 • 按鈕開關 • 四位數7段顯示器多工掃描 • 文字型LCD
A 埠相關的暫存器 • P_IOA_Dir(讀/寫)($7002H ) A 埠的方向暫存器 • P_IOA_Attrib(讀/寫)($7003H) A 埠的屬性暫存器 • P_IOA_Data(讀/寫)($7000H) A 埠的資料暫存器 • P_IOA_Buffer (讀/寫) ($7001H) A 埠的緩衝暫存器 • P_IOA_Latch(讀)($7004H) A 埠的栓鎖暫存器
B 埠相關的暫存器 • P_IOB_Dir(讀/寫)($7007H ) B 埠的方向暫存器 • P_IOB_Attrib(讀/寫)($7008H) B 埠的屬性暫存器 • P_IOB_Data(讀/寫)($7005H) B 埠的資料暫存器 • P_IOB_Buffer (讀/寫) ($7006H) B 埠的緩衝暫存器
P_IOA_Data 與 P_IOA_Buffer 區別 • 讀取 IO 埠 • 從埠讀取資料的兩種方式:從 P_IOA_Data讀取資料相當於讀取埠接腳的訊號。 然而,從 P_IOA_Buffer 讀取資料相當於從資料暫存器中讀取資料。 • data = *P_IOA_Buffer//從 A 埠資料暫存器中讀取資料 • data = *P_IOA_Data //從 A 埠接腳讀取資料 • 寫入 IO 埠 • 這裏有兩種寫入IOA 資料的方法,向 P_IOA_Data 寫入資料結果等於向 P_IOA_Buffer 寫入資料。 • data = 0x0000; • *P_IOA_Data = data ;//寫資料到 P_IOA_Data • *P_IOA_Buffer = data;//寫資料到 P_IOA_Buffer
規劃IO埠 • 規劃IOA[3~0] 為具下拉電阻的輸入埠,IOA[7~4]為具上拉電阻的輸入埠, IOA[11~8]為具資料暫存器的高電位輸出埠,IOA[15~12] 為具資料暫存器的低電位輸出埠 • 解: *P_IOA_Dir = 0xFF00; *P_IOA_Attrib = 0xFF00; *P_IOA_Data = 0x0FF0;
規劃B Port為同相低電位輸出 *P_IOB_Dir=0xffff; *P_IOB_Attrib=0xffff; *P_IOB_Data=0x0000;
規劃B Port為反相的低電位輸出 *P_IOB_Dir = 0xffff; *P_IOB_Attrib = 0x0000; *P_IOB_Data = 0;
規劃 A Port 為具下拉電阻輸入 *P_IOA_Dir = 0x0000; *P_IOA_Attrib = 0x0000; *P_IOA_Data = 0x0000;
LED閃爍(B Port) #include "SPCE061A.H" int main() { //規劃BPort為同相低電位輸出 *P_IOB_Dir=0xffff; *P_IOB_Attrib=0xffff; *P_IOB_Data=0x0000; //IO初始化完成 while (1) { *P_IOB_Data=0xff00; //IOB Port 亮 *P_IOB_Data=0xffff; // IOB Port 滅 } }
延遲副程式 void delay(int n) { int i; for (i=0; i<n; i++) ; *P_Watchdog_Clear = 0x0001; }
延遲副程式(delay_ms) void delay_ms(int n) { int i,j; for (i = 0; i < n; i++ ) for (j = 0; j < 33 ; j++) //用示波器量 *P_Watchdog_Clear = 0x0001;//清除看門狗計數器 }
LED閃爍(B Port)2 #include "SPCE061A.H" int main() { //規劃BPort為同相低電位輸出 *P_IOB_Dir=0xffff; *P_IOB_Attrib=0xffff; *P_IOB_Data=0x0000; //IO初始化完成 while (1) { *P_IOB_Data=0xff00; //IOB Port 亮 delay_ms(500); // 0.5 秒 *P_IOB_Data=0xffff; // IOB Port 滅 delay_ms(500); } }
上機操作(ICE) • 將下載線一邊接電腦Print Port,另外一邊接開發板(61板)或實驗箱(61箱) • 調整Jump • 接上61板或實驗箱(61箱)電源
IOA 輸入 IOB輸出 void Init_A_Port() { //規劃 A Port 為具下拉電阻輸入 *P_IOA_Dir = 0x0000; *P_IOA_Attrib = 0x0000; *P_IOA_Data = 0x0000; } void Init_B_Port() { // B Port為同相低電位輸出 *P_IOB_Dir = 0xffff; *P_IOB_Attrib = 0xffff; *P_IOB_Data = 0x0000; }
程式架構 #include “spce061a.h” void Init_A_Port(); void Init_B_Port(); void delay_ms( int ); void main() { Init_A_Port(); Init_B_Port(); ................. } void Init_A_Port() { ...........} void Init_B_Port() { ............ } void delay_ms() { ................ }
LED單燈左移 int main() { int i; char table[8]={0xFFFE,0xFFFD,0xFFFB,0xFFF7,0xFFEF,0xFFDF,0xFFBF,0xFF7F}; Init_B_Port(); //規劃 B Port 為同相低電位輸出 while (1) for (i =0; i < 8; i++) { *P_IOB_Data = table[i]; delay_ms(500); } }
指撥開關(IOA輸入 IOB輸出) while (1) { key = *P_IOA_Data; key &= 0x00ff; *P_IOB_Data = key; }
清除看門狗計數器 內定約0.75秒自動系統重置 *P_Watchdog_Clear = 0x0001;
LED花樣變化 • B PORT 向左步步高昇(8個LED) • B PORT 向左步步高昇(8個LED)又遞減 • B PORT由兩側向中間亮(8個LED) • B PORT由中間向兩側亮(8個LED) • B PORT由兩側向中間亮再中間向兩側亮(8個LED) • B PORT奇數LED同時亮,再來偶數LED同時亮,輪流交替(8個LED) • B PORT LED左移二回後右移五回,重複輪流(8個LED)
掃描按鍵(消除開關彈跳) unsigned intKeyScan(void) { unsigned int Data; unsigned int Temp; Data = *P_IOA_Data; //讀取IOA埠輸入 Data = Data&0x000f; //僅取低4位有效值 if(Data!=0) //非零則表示有鍵按下 { Delay(); //延時消除彈跳(消除抖動) Temp = *P_IOA_Data; Temp = Temp&0x000f; //僅取低4位有效值 if(Data != Temp) Data = 0; //兩次讀數不相等,則置返回值為0,表示不穩定 } return Data; //返回鍵值 }
開關彈跳Delay void Delay(void) { unsigned int Count; for ( Count = 0; Count <= 3000; Count++ ) *P_Watchdog_Clear = 0x0001; //清看門狗 }
掃描按鍵(消除開關彈跳)2 unsigned intKeyScan(void) { unsigned int Data; unsigned int Temp; Data = *P_IOA_Data; //讀取IOA埠輸入 Data = Data & 0x000f; //僅取低4位有效值 delay(10000); //延時去彈跳 *P_Watchdog_Clear = 0x0001; //清看門狗 return Data; //返回鍵值 }
暫停單燈左移1 int main() { unsigned int a,key,state=1,i=0; Init_A_Port(); //規劃 A Port 為帶下拉電阻輸入 Init_B_Port(); //規劃 B Port 為同相低電位輸出 while (1) { key = *P_IOA_Data; //讀取 A Port值 key &= 0x000f; //保留右邊 4 bit delay(10000); // 影響靈敏度 if ( key == 0x0001 ) if (state ==1 ) state = 0; else state = 1; if (state == 1) { *P_IOB_Data = table[i++]; if ( i == 8 ) i=0; } } }
暫停單燈左移2 int main() { unsigned int a,key,i=0; Init_A_Port(); //規劃 A Port 為帶下拉電阻輸入 Init_B_Port(); //規劃 B Port 為同相低電位輸出 while (1) { key = KeyScan(); if (key != 0) if (state == 1) state = 0; else state = 1; if (state == 1) { *P_IOB_Data = table[i++]; if ( i == 8 ) i=0; delay_ms(500); } } }
0~9往上數 #include "SPCE061a.H" char TABLE[10]={0xFFC0,0xFFF9,0xFFA4,0xFFB0,0xFF99,0xFF92,0xFF82,0xFFF8,0xFF80,0xFF90}; //共陽 int main() { int i; Init_B_Port(); //規劃 B Port 為同相低電位輸出 while (1) for (i = 0; i < 10; i++ ) { *P_IOB_Data = TABLE[i]; delay_ms(500); } }
四位數七段顯示器 • 方法一:4顆七段 • 優點:程式容易撰寫 • 缺點:共須4*9=36隻接腳,消耗電流大 • 方法二: 4顆七段(多工掃描) • 優點:共須4+8=12隻接腳,消耗電流小 • 缺點:程式較困難,自已送出字型碼 • 方法三: 4顆七段(多工掃描)加7447 • 優點:共須4+4=8隻接腳,消耗電流小 • 缺點:程式較困難,且需7447解碼IC
顯示5678 • *P_IOB_Data = 0x00E8; //個位數 • *P_IOB_Data = 0x00D7; //十位數 • *P_IOB_Data = 0x00B6; //百位數 • *P_IOB_Data = 0x0075; //千位數 • E=1110 • D=1101 • B=1011 • 7=0111
LCD模組 • 文字型:2*20, 2*16,4*20(列行) • 繪圖型:128*64, 320*240,1024*68
寫入命令副程式 void LCD_Cmd(unsigned char cmd) { *P_IOA_Data =0x8000 ; // En=1, RW=0, RS=0 write command *P_IOB_Data = cmd; // control word delay(2); // delay *P_IOA_Data =0x0000; // E=0; 禁能 LCD }
寫入資料副程式 void LCD_SendData(unsigned char data) { *P_IOA_Data =0xA000 ; // En=1, RW=0, RS=1 write data *P_IOB_Data = data; // data word delay(2); // delay *P_IOA_Data =0x2000; // E=0; 禁能 LCD }