You are on page 1of 13

Thieát keá öùng duïng cho PIC

Baøi döï thi


16F877A

LCD 16x2 Tree Menu

Phaïm Minh Tuaán. Email: emailchotoi@yahoo.com


1. Giôùi thieäu chung:
PIC khoâng coøn môùi meû nöõa, nhöõng öùng duïng cuûa doøng Vi Ñieàu Khieån hoï PIC cuûa haõng Microchip ñöôïc söû duïng raát nhieàu trong thöïc
teá, trong coâng nghieäp … Moät trong nhöõng yeâu caàu cuûa ÖÙng duïng töø 1 Vi Ñieàu Khieån ñoù laø thaân thieän vôùi ngöôøi duøng, deã daøng söû duïng,
deã daøng naâng caáp. Giao tieáp giöõa maùy moùc vaø ngöôøi duøng phaûi thoâng qua thieát bò xuaát, nhaäp chuaån. Tuy nhieân, khi caàn thöïc hieän nhieàu
coâng vieäc coù tuøy choïn thì dó nhieân neáu khoâng toái öu phaàn meàm thì thieát bò nhaäp lieâu laø coàng keành vaø khoâng thaân thieän vôùi ngöôøi söû
duïng. Baøi döï thi cuûa toâi: LCD 16x2 Tree Menu chæ laø moät öùng duïng ñôn giaûn ñeå giaûi queát vaán ñeà maø ñaõ ñöôïc raát nhieàu ngöôøi giaûi
quyeát, toâi gôûi baøi treân tinh thaàn hoïc hoûi.

Tree Menu hoaëc ñoäng nhö theá naøo? … Coù theå hình dung nhö sau, taát caû nhöõng gì baïn caàn thoâng baùo hay hieån thò ñeán ngöôøi duøng
coù caàu truùc nhö sau:

+ Menu 1

+ Sub Menu 1 - 1

+ Sub Menu 1 - 2

+ Sub Sub Menu 1 -2 - 1

+ Menu 2

+ Sub Menu 2 -1

Tuy nhieân neáu hieån thò ra LCD thì baïn chæ coù 2 doøng ñeå hieån thò. Caùch giaûi quyeát laø baïn chæ hieån thò 2 doøng, vaø söû duïng caùc nuùt
nhaán ñeà ñieàu khieån hieån thò Menu naøy vaø thöïc hieän caùc chæ thò töø ñoù. ÔÛ ñaây phaàn cöùng ñöôïc thieát keá söû duïng 4 nuùt nhaán laø UP –
DOWN – ENTER – CANCEL: Söû duïng nhö sau, neáu nhaán UP – DOWN seõ duyeät treân caùc Menu cuøng caáp vaø taïi moät thôøi ñieåm chæ hieån
thò 2 Item. Nuùt nhaán ENTER seõ hieån thò Menu con cuûa Item ñöôïc choïn neáu noù co Menu con, neáu khoâng thì thi haønh chæ thò. Nuùt CANCEL
trôû veà Menu caáp treân cuûa Item ñöôïc choïn 1 caáp.

Maïch phaàn cöùng cuûa Thieát keá naøy ñôn giaûn nhö sau ( Chæ duøng ñeå moâ phoûng – Veõ treân Proteus 7), vaø döôùi ñoù laø loïat hình moâ
phoûng thieát keá sau khi hoøan thaønh.
emailchotoi@y ahoo.com

2
LCD?
LM016L

VDD
VSS

VEE

RW
RS

D0
D1
D2
D3
D4
D5
D6
D7
E
U? R1 R2 R3 R4

1
2
3

4
5
6

7
8
9
10
11
12
13
14
1k 1k 1k 1k
13 OSC1/CLKIN RB0/INT 33
CANCEL

RW
EN
RS

D4
D5
D6
D7
14 34
OSC2/CLKOUT RB1
35
RB2
2 RA0/AN0 RB3/PGM 36
3 37 ENTER
RA1/AN1 RB4
4 38
RA2/AN2/VREF-/CVREF RB5
5 RA3/AN3/VREF+ RB6/PGC 39
6 40 DOWN
RA4/T0CKI/C1OUT RB7/PGD
7 RA5/AN4/SS/C2OUT
15
RC0/T1OSO/T1CKI UP
8 16
RE0/AN5/RD RC1/T1OSI/CCP2
9 RE1/AN6/WR RC2/CCP1 17
10 18
RE2/AN7/CS RC3/SCK/SCL
23
RC4/SDI/SDA
1 MCLR/Vpp/THV RC5/SDO 24
25
RC6/TX/CK
RC7/RX/DT 26

19 EN
RD0/PSP0 RS
RD1/PSP1 20
21 RW
RD2/PSP2
22
RD3/PSP3 D4
RD4/PSP4 27
28 D5
RD5/PSP5 D6
RD6/PSP6 29
30 D7
RD7/PSP7
PIC16F877A
emailchotoi@yahoo.com

3
emailchotoi@yahoo.com

4
2. Löu ñoà giaûi thuaät
Löu ñoà giaûi thuaät ñöôïc veõ moät caùch toång quaùt ñeå ngöôøi xem coù theå deã daøng hình dung yù töôûng cuûa ngöôøi vieát. Khoâng quaù
chuù troïng chi tieát , moïi chuù thích chi tieát naèm trong chöông trình chinh.
emailchotoi@y ahoo.com

5
emailchotoi@y ahoo.com

6
emailchotoi@y ahoo.com

7
3. Chöông trình chính
Chöông trình ñöôïc vieát baèng C, trình dòch CCS C, trong chöông trình coù söû duïng driver cho LCD cuûa CCS
Code

1. /*+-----------------------------------------------------------------------+*
2. *| Chuong trinh Dung de hien thi MENU dieu khien len LCD 16x2 |*
3. *| MENU co dang cay(TREE) 1 MENU chinh co the co nhieu MENU con |*
4. *| DE DANG them vao MENU bat ky dau hay sua chua de su dung lai |*
5. *|***********************************************************************|*
6. *| Chuong trinh duoc viet voi Pham Minh Tuan: SVDH Su Pham Ky Thuat HCMC |*
7. *| Moi thac mac xin lien he email: emailchotoi@yahoo.com |*
8. *|***********************************************************************|*
9. *| Phan cung ket noi voi 1 LCD nhu sau (Su dung LCD driver cua CCS C) |*
10. *| PIC | LCD |*
11. *| ---------------------- |*
12. *| RD4->7 | D4->7 |*
13. *| RD0 | EN |*
14. *| RD1 | RS |*
15. *| RD2 | RW |*
16. *| va ket noi voi cac phim nhan nhu sau: |*
17. *| RB4 : CANCEL |*
18. *| RB5 : ENTER |*
19. *| RB6 : DOWN |*
20. *| RB7 : UP |*
21. *+-----------------------------------------------------------------------+*/
22.
23. #include "16F877A.h"
24. #device adc=10
25. #fuses NOLVP, NOWDT, HS
26. #use delay(clock=4000000)
27. #include "lcd_driver.c"
28.
29. /* Dinh nghia MA PHIM se duoc dung de dieu khien Menu
30. * UP - DOWN : Lua chon mot Muc trong Menu
31. * ENTER: Neu co Menu co, thi hien thi Menu con, nguoc lai thi hanh lenh
32. * CANCEL: Tro ve Menu cap bac truoc no
33. */
34. #define UP 0xB0
35. #define DOWN 0x70
36. #define ENTER 0xD0
37. #define MENU 0xF0
38. #define CANCEL 0xE0
39.
40. /* Dinh nghia gia tri CHI MUC cho Menu Chinh, Menu con, tien cho viec so sanh
41. * O day su dung tat ca la 12 Dong MENU
42. */
43. #define ALL_MENU 14
emailchotoi@y ahoo.com

44. #define BEGIN 0x00 //Mac dinh day la Chi Muc goc
45. #define MICROCHIP 0x01
46. #define ATMEL 0x02
47. #define XILINX 0x03
48. #define PIC16 0x04
49. #define PIC18 0x05
50. #define DSPIC 0x06
51. #define PIC877A 0x07
52. #define PIC84 0x08

8
53.
54. #define AVR 0x0A
55. #define MCS51 0x0B
56. #define COOLRUNNER 0x0C
57. #define VIRTEX 0x0D
58. #define ABOUT 0x0E
59. #define NAME 0x0F
60.
61. /* Co the giai thich Cau truc cua Menu duoc su dung nhu sau:
62. * +MenuID la ID(dinh danh) cua Dong Menu do
63. * +SubMenu la ID(dinh danh) cua Dong Menu Truoc no 1 BAC
64. * +MenuName gom 17 ky tu Chua toi da 16 ky tu in ra LCD la 1 ky tu ket
thuc(Chuoi)
65. */
66. struct TypeMenu {
67. int8 MenuID;
68. int8 SubMenu;
69. char MenuName[16];//17
70. };
71. int8 ContainMenu, STATE = BEGIN, PAGE = 0, LEVEL[7], LevelPtr=0;
72. Boolean AccessENTER = TRUE, AccessCANCEL=TRUE;
73.
74. /*Cau truc cua Menu o day duoc hinh dung nhu sau:
75. * BEGIN
76. * + MICROCHIP
77. * | + 8 BIT PIC16
78. * | | + PIC 16F877A
79. * | | + PIC 16F84
80. * | + 8 BIT PIC18
81. * | + 16 BIT dsPIC
82. * + ATMEL
83. * | + 8 BIT AVR
84. * | + 8 BIT MCS51
85. * + XILINX
86. * | + CoolRunner
87. * | + VirTex-4
88. */
89. const struct TypeMenu MenuOfTuan[ALL_MENU]
90. ={{MICROCHIP, BEGIN, "MicroChip" },
91. {ATMEL, BEGIN, "Atmel" },
92. {XILINX, BEGIN, "Xilinx" },
93. {PIC16, MICROCHIP, "8 Bit PIC16" },
94. {PIC18, MICROCHIP, "8 Bit PIC18" },
95. {DSPIC, MICROCHIP, "16 Bit dsPIC"},
96. {AVR, ATMEL, "8 Bit AVR" },
97. {MCS51, ATMEL, "8 Bit MCS51" },
98. {COOLRUNNER, XILINX, "CoolRunner" },
99. {VIRTEX, XILINX, "Virtex-4" },
100. {PIC877A, PIC16, "PIC 16F877A" },
101. {PIC84, PIC16, "PIC 16F84" },
102. {ABOUT, BEGIN, "About" },
emailchotoi@y ahoo.com

103. {NAME, ABOUT, "Pham Minh Tuan"}};


104.
105.
106. /* Cau truc dung de chua Menu se hien thi trong Mang MENU da Dinh nghia */
107. struct typeMenu MenuPoiter[5];
108.
109. //Luu Y la Ngo vao o day chinh la su thay doi co y nghia doi voi 1 HAM
110. /*+ ---------------------------------------------------------------------------+*
111. *| Ham QueryMenu: dung LOC ra nhung Item la Menu CON cua trang |*

9
112. *| thai(STATE) hien tai |*
113. *| + Ngo vao: Trang thai hien tai (STATE) |*
114. *| + Tra ve So luong MENU CON cua trang thai(STATE) hien tai |*
115. *+----------------------------------------------------------------------------+*/
116. int8 QueryMenu() {
117. int8 i,j=0, NumMenu = 0;
118. for(i=0; i<ALL_MENU; i++) {
119. if(MenuOfTuan[i].SubMenu == STATE) {
120. NumMenu++; //Neu Menu duoc kiem tra co chi muc
121. } //giong voi SubMenu cua Menu hien tai
122. } // thi no la Menu CON cua Menu do
123. if(NumMenu) {
124. for(i=0; i<ALL_MENU; i++) { //Neu so luong Menu can hien thi
125. if(MenuOfTuan[i].SubMenu == STATE) { //Nhieu hon 0 thi COPY no vao
126. MenuPoiter[j] = MenuOfTuan [i]; //MenuPointer de hien thi
127. j++;
128. }
129. }
130. }
131. return NumMenu; //Tra ve so luong Menu da kiem tra
132. }
133.
134.
135. /*+---------------------------------------------------------------------------+*
136. *| Ham QueryLastMenu: Dung lay trang thai CAP TREN cua TRANG THAI hien tai |*
137. *| Khi An CANCEL thi phai tro ve MENU TREN CAP cua MENU hien tai |*
138. *| Vi du: Khi dang o STATE la PIC16 thi khi an CANCEL phai tro ve MENU |*
139. *| TREN CAP cua no 1 bac tuc la STATE MICROCHIP |*
140. *| +Ngo vao : Khong |*
141. *| +Tra ve: Trang thai TREN 1 CAP cua trang thai HIEN TAI |*
142. *+---------------------------------------------------------------------------+*/
143. int8 QueryLastMenu() {
144. int8 i; //Mang Menu dang duoc hien thi co SubMenu
145. for(i=0; i<ALL_MENU; i++) { //Giong nhau va giong voi Dinh danh(ID)tren no
146. if(MenuOfTuan[i].MenuID == MenuPoiter[0].SubMenu) //mot bac
147. return MenuOfTuan[i].SubMenu;
148. }
149. return 0x00;
150. }
151.
152.
153. /*+---------------------------------------------------------------------------+*
154. *| Ham HasSubMenu: Co chuc nang kiem Tra Xem 1 Item Co ton tai Menu CON ko |*
155. *| Dieu nay la can thiet, Neu mot Item co Menu CON thi Khi AN ENTER |*
156. *| phai Hien thi TAT CA Menu CON cua Item nay, neu Ko co Menu CON thi THI |*
157. *| HANH Chuc nang cua Item do |*
158. *| + Ngo vao: Trang thai hien tai (STATE) |*
159. *| + Tra ve Gia tri TRUE neu co Menu CON, nguoc lai la FALSE |*
160. *+---------------------------------------------------------------------------+*/
161. BOOLEAN HasSubMenu() {
162. int8 i;
emailchotoi@y ahoo.com

163. for(i=0; i<ALL_MENU; i++) { //Duyet ta ca trong danh sach cac Item
164. if(STATE == MenuOfTuan[i].SubMenu) //Neu trang thai hien tai giong voi
165. return TRUE; //SubMenu thi no chinh la Menu con
166. } //cua Trang thai HIEN TAI, nghia la co
167. return FALSE; //Menu con, nguoc lai: KHONG CO
168. }
169.
170.
171. /*+---------------------------------------------------------------------------+*

10
172. *| Ham ProcessMenu: Dung de hien thi Mang Menu MenuPoiter da duoc LOC |*
173. *| Co Phan trang de khi Chi muc tro den 1 Item vuot qua so Item thi Reset |*
174. *| +Ngo vao: PAGE -> Chi muc (TRANG) cua mot Mang menu da loc (MenuPoiter) |*
175. *| ContainMenu -> So Menu trong Mang Menu |*
176. *| +Tra ve: KHONG |*
177. *+---------------------------------------------------------------------------+*/
178. void ProcessMenu() {
179. int8 PageTemp; //LCD co 2 dong, PAGE tro dong 1, PageTemp->d2
180. if(PAGE == 0xFF) { //Khi an UP or DOWN lam cho PAGE giam tu 0->0xFF
181. PAGE = ContainMenu - 1; //hay hi PAGE > Tong so Menu hien thi ....
182. PageTemp = 0; //Thi can phai tro LAI sao cho khi nhin thay
183. } //Menu nhu duoc cuon tron.->DAY LA 1 CACH
184. else if(PAGE >= ContainMenu) {
185. PAGE = 0;
186. PageTemp = 1;
187. } else if(PAGE == (ContainMenu - 1)) PageTemp = 0;
188. else PageTemp = PAGE + 1;
189.
190. //In ra dong thu 1, va dong thu 2
191. printf(lcd_putc,"\f>%s",MenuPoiter[PAGE].MenuName);
192. if(ContainMenu > 1)
193. printf(lcd_putc,"\n %s",MenuPoiter[PageTemp].MenuName);
194. }
195.
196.
197. /*+---------------------------------------------------------------------------+*
198. *| Ham ProcessAction: La Ham QUANG TRONG nhat trong ca chuong trinh |*
199. *| Ham nay tuy thuoc vao gia tri PHIM NHAN dua vao ma thi hanh MENU 1 cach |*
200. *| phu hop, se giai thich ro hon trong noi dung cua HAM |*
201. *| +Ngo vao: gia tri PHIM NHAN, TRANG hien tai, TRANG THAI hien tai |*
202. *| +Tra ve: KHONG |*
203. *+---------------------------------------------------------------------------+*/
204. void ProcessAction(int16 Key) {
205. if(STATE == BEGIN) AccessCANCEL = FALSE; //Neu TRANG THAI dang o CAP cao nhat
206. else AccessCANCEL = TRUE; // thi NUT NHAN CANCEL bi vo hieu
207. switch(Key) {
208. case ENTER:
209. if(!AccessENTER) break; //Neu la nut nhan ENTER va ENTER duoc cho phep
210. LEVEL[LevelPtr] = PAGE; //Luu Trang Hien hanh, va ngan xep
211. LevelPtr++; //len 1 don vi
212. STATE = MenuPoiter[PAGE].MenuID; //Lay trang thai MOI, ung voi su lua
chon
213. PAGE = 0; //Khoi dau tu TRANG 0
214. ContainMenu = QueryMenu(); //Kiem tra co bao nhien MENU CON
215. if(ContainMenu) {
216. ProcessMenu(); //Neu nhieu hon 0, thi hien thi
217. }else {
218. AccessENTER = FALSE; //Nguoc lai la Item cuoi cung, ko co Menu con
219. switch(STATE){ //Do do Disable nut ENTER, va Kiem tra xem
220. case PIC877A: //Neu tu Item PIC 16F877A thi thuc hien
221. lcd_putc("\fHi 16F877A");
emailchotoi@y ahoo.com

222. break;
223. case PIC84: //Neu tu PIC 16F84 thi ...
224. lcd_putc("\fHi 16F84");
225. break;
226. case AVR: //...
227. lcd_putc("\fHi AVR");
228. break;
229. case MCS51:
230. lcd_putc("\fHi MCS51");

11
231. break;
232. case COOLRUNNER:
233. lcd_putc("\fHi Cool Runner");
234. break;
235. case VIRTEX:
236. lcd_putc("\fHi VirTex");
237. break;
238. case PIC18:
239. lcd_putc("\fHi PIC 18F4550");
240. break;
241. case DSPIC:
242. lcd_putc("\fHi dsPIC");
243. break;
244. }
245.
246. }
247. break;
248.
249. case UP: //Neu la NUT UP va ENTER duoc cho phep
250. if(!AccessENTER) break;
251. PAGE --; //Giam TRANG HIEN TAI va HIEN THI
252. ProcessMenu();
253. break;
254. case DOWN: //Neu la NUT DOWN va ENTER duoc cho phep
255. if(!AccessENTER) break;
256. PAGE ++; //Tang TRANG HIEN TAI va HIEN THI
257. ProcessMenu();
258. break;
259. case CANCEL: //Neu la CANCEL va NUT CANCEL duoc cho phep
260. if(!AccessCANCEL) break;
261. if(LevelPtr) LevelPtr--; //Lay TRANG da luu truoc do tu ngan xep
262. PAGE = LEVEL[LevelPtr]; //giam con tro ngan xep
263. if(!HasSubMenu()) { //Neu Item Hien hanh khong co Menu CON
264. AccessENTER = TRUE; //Cho Phep nhu ENTER tro lai
265. STATE = MenuPoiter[PAGE].SubMenu;
266. } else { //Neu trang hien hanh co Menu CON
267. STATE = QueryLastMenu(); //Lay TRANG THAI Tren no 1 CAP
268. }
269. ContainMenu = QueryMenu();
270. ProcessMenu(); //Hien thi Menu
271. break;
272. case MENU:
273. ContainMenu = QueryMenu();
274. ProcessMenu();
275. Break;
276. }
277. }
278.
279. /*
280. Chuong trinh con Quet PHIM dung de TEST cho MENU nay, khong QUAN TRONG, co ban
281. la no se goi MA PHIM UP, DOWN, ENTER, CANCEL toi cho ham ProcessAction khi mot
emailchotoi@y ahoo.com

282. trong cac PHIM duoc nhan va duoc tha (OnRelease)


283. */
284. int8 keyscan() {
285. int8 inB, varRet;
286. inB = input_b()&0xF0;
287. if(inB != 0xF0){
288. varRet = inB;
289. delay_ms(20);
290. inB = input_b()&0xF0;

12
291. if(inB == 0xF0) {
292. return varRet;
293. } else {
294. return 0;
295. }
296. }
297. }
298.
299.
300. /*Chuong trinh CHINH
301. */
302. void Main() {
303.
304. int8 key;
305. set_tris_b(0xFF); //Khoi tao PORTB -> INPUT
306. lcd_init(); //Khoi tao LCD
307. processAction(MENU); //Hien thi MENU Chinh
308. while(1){
309. key = keyscan(); //Cho Phim NHAN
310. if(key) { //Neu PHIM nhan HOP LE, hien thi
311. processAction(key);
312. }
313. }
314. }
315.

Code

Coù gôûi keøm theo toøan boä file maõ nguoàn cuûa chöông trình vaø file moâ phoûng
emailchotoi@y ahoo.com

13

You might also like