1:MISO:出力(AVR→PC) 2:VCC:電源 3:SCK:クロック(PC→AVR) 4:MOSI:入力(PC→AVR) 5:/RES:リセット 6:GND:グラウンド
1: #include <avr/io.h>
2: #include <util/delay.h>
3: /*Support _delay_ms(time) and _delay_us(time) function*/
4:
5: #define cbi(port, bit) (port)&=~(1<<(bit))
6: /*PORTの指定BITに1をセット*/
7: #define sbi(port, bit) (port)|=(1<<(bit))
8: /*PORTの指定BITにクリア*/
9:
10: #define RS 0
11: #define RW 1
12: #define EN 2
13:
14: #define ctrl PORTD
15: #define ddr_ctrl DDRD
16: #define data_out PORTD
17: #define data_in PIND
18: #define ddr_data DDRD
19:
20: void write_to_lcd(uint8_t chr) { 21: uint8_t hChar, lChar, temp_data;
22:
23: temp_data = data_out & 0x0F;//Doc 4 bit thap cua data_out de mask
24:
25: hChar = chr & 0xF0;
26: lChar = (chr<<4) & 0xF0;
27:
28: data_out = (hChar | temp_data);//Chu ly la phai xuat ky tu o bit cao truoc
29: sbi(ctrl, EN); //Can phai tao xung canh xuong moi lan xuat du lieu
30: cbi(ctrl, EN); //Hai dong nay nham tao xung canh xuong de biet xuat du lieu
31:
32: data_out = (lChar | temp_data);
33: sbi(ctrl, EN);
34: cbi(ctrl, EN);
35: }
36:
37: char read_from_lcd(void) { 38: char hChar, lChar;
39:
40: data_out |= 0xF0;
41:
42: sbi(ctrl, EN);
43: ddr_data &= 0x0F;//Set 4 bit cao cua PORTD lam input
44: hChar = data_in & 0xF0;
45: cbi(ctrl, EN);
46:
47: sbi(ctrl, EN);
48: lChar = data_in & 0xF0;
49: cbi(ctrl, EN);
50: lChar >>=4;
51:
52: return (hChar|lChar);
53: }
54:
55: void wait_lcd(void) { 56: char temp_val;
57:
58: while(1) { 59: cbi(ctrl, RS);//RS=0; the following data is command
60: sbi(ctrl, RW);//LCD to AVR
61:
62: //Khi RS=0, RW=1, doc lu lieu D7->D0 tu LCD vao AVR de kiem tra xem LCD co ranh ko, BF=D7
63: temp_val = read_from_lcd();
64: if(bit_is_clear(temp_val, 7)) break;
65: /*
66: Khi RW=1; du lieu se doc tu LCD ra ngoai.
67: De biet co the biet duoc LCD co ban hay ko, du dung co Busy Flag BF
68: Do LCD la mot thiet hoat dong tuong doi cham, so vo VDK, nen neu BF=1 thi phai doi cho xu ly xong nhiem vu hien tai.
69: Neu BF=0, co the xu ly tiep yeu cau lenh tiep theo.
70: */
71: }
72: cbi(ctrl, RW);//ready for next step
73: ddr_data=0xFF;//ready to out
74: //Tiep theo co the ghi tu AVR->LCD
75: }
76:
77: void init_lcd(void) { 78: ddr_ctrl = 0xFF;
79: ddr_data = 0xFF;
80: //La chan output, AVR->LCD, ghi D7->D0 la 0xFF
81:
82: cbi(ctrl, RS);//the following data is command
83: cbi(ctrl, RW);//AVR to LCD
84: cbi(ctrl, EN);
85:
86: sbi(ctrl, EN);//Muc dich la tao xung suon tac dong
87:
88: /*Khi vua khoi dong LCD thi mode 8 se duoc chon
89: LCD se co gang doc het cac chan tu D7:D0 de lay du lieu
90: Neu D3:D0 khong duoc ket noi voi AVR, viec doc lan dau tien co the dan den sai so
91: De su dung mode 4 bit, gui lenh FUNCTION SET voi tham so DL=0(0010xxxx)den LCD de bao che do mode muon su dung
92: */
93: sbi(data_out, 5);
94: cbi(ctrl, EN);
95: wait_lcd();
96:
97: /*
98: Ghi ma FUNCTION SET vao LCD, 0x28=(001)0.1000
99: Mode 4 bit, LCD 2 dong, font 5x8
100: */
101: write_to_lcd(0x28);
102: wait_lcd();
103:
104: /*
105: Display control, 0x0E=(0000.1)110
106: 0000.1=ma lenh display control, 110-xac lap hien thi LCD, hien thi cursor, khong blinking
107: */
108: cbi(ctrl, RS);//the following data is command
109: write_to_lcd(0x0E);
110: wait_lcd();
111:
112: /*
113: Entry mode set 0x06
114: Hien thi tang, khong shift.
115: */
116: cbi(ctrl, RS);
117: write_to_lcd(0x06);
118: wait_lcd();
119:
120: }
121:
122: /*
123: Khi khi ma lenh 0x02 AVR->LCD
124: Con tro cursor se tu dong di chuyen ve vi tri dau tien tren LCD (home)
125: */
126: void home_lcd(void) { 127: cbi(ctrl, RS);//The following data is COMMAND
128: write_to_lcd(0x02);
129: wait_lcd();
130: }
131:
132: /*
133: Di chuyen con tro cursor den vi tri dong x, cot y
134: Thuc chat day la lenh set DDRAM address
135: Lenh nay co dang 1xxx.xxx, la mot so 7 bit chua dia chi DDRAM se di chuyen den
136: Cung 1 cot, vi tri duoc xac dinh = (64*(y-1))
137: Xac dinh dong duoc ghi = (x-1)
138: Ma lenh set dia chi DDRAM, ma 0x80
139: */
140: void move_lcd(uint8_t y, uint8_t x) { 141: uint8_t Ad;
142:
143: Ad = 64*(y-1)+(x-1)+0x80;
144: cbi(ctrl, RS);
145: write_to_lcd(Ad);
146: wait_lcd();
147: }
148:
149: /*Xoa man hinh screen*/
150: void ctrl_lcd(void) { 151: cbi(ctrl, RS);
152: write_to_lcd(0x01);
153: wait_lcd();
154: }
155:
156: /*Hien thi 1 ky tu tu AVR->LCD*/
157: void putChar_lcd(uint8_t chr) { 158: sbi(ctrl, RS);
159: write_to_lcd(chr);
160: wait_lcd();
161: }
162:
163: /*Hien thi 1 chuoi ky tu tu AVR->LCD*/
164: void putString_lcd(char* str, unsigned char len) { 165: unsigned char i;
166: for (i=0; i<len; i++)
167: if (str[i]>0) { 168: putChar_lcd(str[i]);
169: } else { 170: putChar_lcd(' '); 171: }
172: }
173:
174: int main (void) { 175: /*Data Dirrections for PORTC and PORTD pins*/
176: DDRB = 0xFF;
177: PORTB = 0x00;
178:
179: init_lcd();
180: ctrl_lcd();
181:
182: putChar_lcd(' '); 183: putChar_lcd(' ');; 184:
185: putChar_lcd('D'); 186: putString_lcd("emo of the", 10); 187: move_lcd(2, 1);
188: putString_lcd("2x16 LCD Display", 16); 189:
190: while (1) { 191: cbi(PORTB, 0);
192: _delay_ms(100);
193: sbi(PORTB, 0);
194: _delay_ms(100);
195:
196: };
197: }