Các chân vào (General purpose I/O input pins) ra đƣợc điều khiển bởi 4 thanh ghi:
Hình 3.1. Các chân vào ra đƣợc dùng cho mục đích chung
- Mỗi chân GPIO đƣợc điều khiển bởi 4 bít để điều khiển hƣớng dữ liệu, set, xóa và trạng thái của chân.
- Mỗi bít trong thanh ghi IODIR: 0 cho phép cấu hình các chân là đầu vào 1 cho phép cấu hình các chân là đầu ra
Trang 43
- Khi các chân là đầu ra thì các bít tƣơng ứng trên các thanh ghi IOSET và IOCLR cho phép ngƣời lập trình điều khiển trạng thái của các bít.
- Để xóa chân nào thì đƣa set bít đó =1 tƣơng ứng trong thanh ghi IOCLR - Để đọc nội dung của chân sử dụng thanh ghi IOPIN
Thí dụ 1: Viết chƣơng trình điều khiển led đơn sáng nhấp nháy
Ghép nối một led đơn với chân P0.0 của LPC2101, Sơ đồ nối chân Proteus:
Chƣơng trình điều khiển:
//Thi du chuong trinh dieu khien led nhap nhay tai chan p0.1 //LPC 2101
#include"LPC21xx.h" void delay(unsigned int a); int main(void){ IODIR0=0x00000001 ; while(1){ IOSET0=0x00000001 ; delay(0x100000);
Trang 44 IOCLR0=0x00000001 ;
delay(0x100000); } }
void delay(unsigned int a){ unsigned int i;
for (i=0;i<a;i++){;} }
Thí dụ 2: Chƣơng trình hiển thị chữ trên LCD
Sơ đồ trên proteus:
Chƣơng trình điều khiển:
Trang 45 Tệp lcd.h định nghĩa địa chỉ dành cho lcd:
/***************************************/ /* LCD routines for OLIMEX LPC-MT-2106 */ /* 16x2 Character LCD 1602K */
/* 4-bit mode operation */
/***************************************/ /* DEFINE IOMASK */
#define LCD_D4 0x10 //P0.04 #define LCD_D5 0x20 //P0.05
Trang 46 #define LCD_D6 0x40 //P0.06 #define LCD_D7 0x80 //P0.07 #define LCD_EN 0x400000 //P0.22 #define LCD_RS 0x800000 //P0.23 #define LCD_RW 0x1000000 //P0.24 #define LCD_DATA (LCD_D4|LCD_D5|LCD_D6|LCD_D7) #define LCD_IOALL (LCD_D4|LCD_D5|LCD_D6|LCD_D7|LCD_EN|LCD_RS|LCD_RW) #define LCD_GPIO_SEL0 0x0000FF00 //MASK for P0.04-P0.07 #define LCD_GPIO_SEL1 0x0003F000 //MASK for P0.22-P0.24
/* Functions Header */ /* internal I/O functions */
#define lcd_rs_set() IOSET |= LCD_RS #define lcd_rs_clr() IOCLR |= LCD_RS #define lcd_en_set() IOSET |= LCD_EN #define lcd_en_clr() IOCLR |= LCD_EN #define lcd_rw_set() IOSET |= LCD_RW #define lcd_rw_clr() IOCLR |= LCD_RW
/* wait until lcd controller is free */
void lcd_wait();
void lcd_out_data4(unsigned char); void lcd_write_nibbles(unsigned char); void lcd_write_control(unsigned char);
/* initialize both the GPIO of lpc and LCD */
void lcd_init();
#define lcd_clear() lcd_write_control(0x01) #define lcd_cursor_home() lcd_write_control(0x02) #define lcd_display_on() lcd_write_control(0x0E) #define lcd_display_off() lcd_write_control(0x08) #define lcd_cursor_blink() lcd_write_control(0x0F) #define lcd_cursor_on() lcd_write_control(0x0E)
Trang 47
#define lcd_cursor_off() lcd_write_control(0x0C) #define lcd_cursor_left() lcd_write_control(0x10) #define lcd_cursor_right() lcd_write_control(0x14) #define lcd_display_sleft() lcd_write_control(0x18) #define lcd_display_sright() lcd_write_control(0x1C) /* put a character out to lcd */
void lcd_putchar(unsigned char); /* print a string */
void lcd_print(unsigned char*);
Tệp lcd.c định nghĩa các phƣơng thức liên quan đến các thao tác trên LCD: #include "lcd.h"
#include "lpc210x.h" void lcd_wait(){
int loop=2800; //more than enough //busy loop
while(loop--); }
void lcd_out_data4(unsigned char val){ IOCLR |= (LCD_DATA);
IOSET |= (val<<4); }
void lcd_write_nibbles(unsigned char val){ //higher-order byte lcd_en_set(); lcd_out_data4((val>>4)&0x0F); lcd_en_clr(); lcd_wait(); //lower-order byte lcd_en_set(); lcd_out_data4((val)&0x0F); lcd_en_clr();
Trang 48 lcd_wait();
}
void lcd_write_control(unsigned char val){ lcd_rs_clr();
lcd_write_nibbles(val); }
void lcd_init(){
PINSEL0 &= (~LCD_GPIO_SEL0); PINSEL1 &= (~LCD_GPIO_SEL1); /* we only work on OUTPUT so far */ IODIR |= LCD_IOALL;
/* IO init complete, init LCD */ /* init 4-bit ops*/
lcd_rs_clr(); lcd_rw_clr(); lcd_en_clr(); //wait VDD raise > 4.5V lcd_wait(); //dummy inst lcd_write_nibbles(0x30); lcd_write_nibbles(0x30); lcd_write_nibbles(0x30); //FUNCTION SET //001DL N F XX //DL=1: 8bit //DL=0: 4bit //N=0: 1 line display //N=1: 2 line display //F=0: 5x7 dots //F=1: 5x10 dots //our case:
Trang 49 //0010 1000 lcd_en_set(); lcd_out_data4(0x2); lcd_en_clr(); lcd_wait(); lcd_write_nibbles(0x28); //LCD ON lcd_write_nibbles(0x0E); //Clear Display lcd_write_nibbles(0x01); //Entry mode lcd_write_nibbles(0x06); }
void lcd_putchar(unsigned char c){ lcd_rs_set();
lcd_write_nibbles(c); }
void lcd_print(unsigned char* str){ int i;
//limit 1 line display for prints for (i=0;i<16 && str[i]!=0;i++){ lcd_putchar(str[i]);
}}
Tệp test.c chứa chƣơng trình chính: #include "lpc210x.h"
#include "lcd.h" int main(void) {
lcd_init();
lcd_print("Trieu Dai Gia"); return 1;
Trang 50 }