/*+-----------------------------------------------------------------------+*
*| Chuong trinh Dung de hien thi MENU dieu khien len LCD 16x2 |*
*| MENU co dang cay(TREE) 1 MENU chinh co the co nhieu MENU con |*
*| DE DANG them vao MENU bat ky dau hay sua chua de su dung lai |*
*|***********************************************************************|*
*| Chuong trinh duoc viet voi Pham Minh Tuan: SVDH Su Pham Ky Thuat HCMC |*
*| Moi thac mac xin lien he email: emailchotoi@yahoo.com |*
*|***********************************************************************|*
*| Phan cung ket noi voi 1 LCD nhu sau (Su dung LCD driver cua CCS C) |*
*| PIC | LCD |*
*| ---------------------- |*
*| RD4->7 | D4->7 |*
*| RD0 | EN |*
*| RD1 | RS |*
*| RD2 | RW |*
*| va ket noi voi cac phim nhan nhu sau: |*
*| RB4 : CANCEL |*
*| RB5 : ENTER |*
*| RB6 : DOWN |*
*| RB7 : UP |*
*+-----------------------------------------------------------------------+*/
#include "16F877A.h"
#device adc=10
#fuses NOLVP, NOWDT, HS
#use delay(clock=4000000)
#include "lcd_driver.c"
/* Dinh nghia MA PHIM se duoc dung de dieu khien Menu
* UP - DOWN : Lua chon mot Muc trong Menu
* ENTER: Neu co Menu co, thi hien thi Menu con, nguoc lai thi hanh lenh
* CANCEL: Tro ve Menu cap bac truoc no
*/
#define UP 0xB0
#define DOWN 0x70
#define ENTER 0xD0
#define MENU 0xF0
#define CANCEL 0xE0
/* Dinh nghia gia tri CHI MUC cho Menu Chinh, Menu con, tien cho viec so sanh
* O day su dung tat ca la 12 Dong MENU
*/
#define ALL_MENU 14
#define BEGIN 0x00 //Mac dinh day la Chi Muc goc
#define MICROCHIP 0x01
#define ATMEL 0x02
#define XILINX 0x03
#define PIC16 0x04
#define PIC18 0x05
#define DSPIC 0x06
#define PIC877A 0x07
#define PIC84 0x08
#define AVR 0x0A
#define MCS51 0x0B
#define COOLRUNNER 0x0C
#define VIRTEX 0x0D
#define ABOUT 0x0E
#define NAME 0x0F
/* Co the giai thich Cau truc cua Menu duoc su dung nhu sau:
* +MenuID la ID(dinh danh) cua Dong Menu do
* +SubMenu la ID(dinh danh) cua Dong Menu Truoc no 1 BAC
* +MenuName gom 17 ky tu Chua toi da 16 ky tu in ra LCD la 1 ky tu ket thuc(Chuoi)
*/
struct TypeMenu {
int8 MenuID;
int8 SubMenu;
char MenuName[16];//17
};
int8 ContainMenu, STATE = BEGIN, PAGE = 0, LEVEL[7], LevelPtr=0;
Boolean AccessENTER = TRUE, AccessCANCEL=TRUE;
/*Cau truc cua Menu o day duoc hinh dung nhu sau:
* BEGIN
* + MICROCHIP
* | + 8 BIT PIC16
* | | + PIC 16F877A
* | | + PIC 16F84
* | + 8 BIT PIC18
* | + 16 BIT dsPIC
* + ATMEL
* | + 8 BIT AVR
* | + 8 BIT MCS51
* + XILINX
* | + CoolRunner
* | + VirTex-4
*/
const struct TypeMenu MenuOfTuan[ALL_MENU]
={{MICROCHIP, BEGIN, "MicroChip" },
{ATMEL, BEGIN, "Atmel" },
{XILINX, BEGIN, "Xilinx" },
{PIC16, MICROCHIP, "8 Bit PIC16" },
{PIC18, MICROCHIP, "8 Bit PIC18" },
{DSPIC, MICROCHIP, "16 Bit dsPIC"},
{AVR, ATMEL, "8 Bit AVR" },
{MCS51, ATMEL, "8 Bit MCS51" },
{COOLRUNNER, XILINX, "CoolRunner" },
{VIRTEX, XILINX, "Virtex-4" },
{PIC877A, PIC16, "PIC 16F877A" },
{PIC84, PIC16, "PIC 16F84" },
{ABOUT, BEGIN, "About" },
{NAME, ABOUT, "Pham Minh Tuan"}};
/* Cau truc dung de chua Menu se hien thi trong Mang MENU da Dinh nghia */
struct typeMenu MenuPoiter[5];
//Luu Y la Ngo vao o day chinh la su thay doi co y nghia doi voi 1 HAM
/*+ ---------------------------------------------------------------------------+*
*| Ham QueryMenu: dung LOC ra nhung Item la Menu CON cua trang |*
*| thai(STATE) hien tai |*
*| + Ngo vao: Trang thai hien tai (STATE) |*
*| + Tra ve So luong MENU CON cua trang thai(STATE) hien tai |*
*+----------------------------------------------------------------------------+*/
int8 QueryMenu() {
int8 i,j=0, NumMenu = 0;
for(i=0; i
if(MenuOfTuan[i].SubMenu == STATE) {
NumMenu++; //Neu Menu duoc kiem tra co chi muc
} //giong voi SubMenu cua Menu hien tai
} // thi no la Menu CON cua Menu do
if(NumMenu) {
for(i=0; i
if(MenuOfTuan[i].SubMenu == STATE) { //Nhieu hon 0 thi COPY no vao
MenuPoiter[j] = MenuOfTuan[i]; //MenuPointer de hien thi
j++;
}
}
}
return NumMenu; //Tra ve so luong Menu da kiem tra
}
/*+---------------------------------------------------------------------------+*
*| Ham QueryLastMenu: Dung lay trang thai CAP TREN cua TRANG THAI hien tai |*
*| Khi An CANCEL thi phai tro ve MENU TREN CAP cua MENU hien tai |*
*| Vi du: Khi dang o STATE la PIC16 thi khi an CANCEL phai tro ve MENU |*
*| TREN CAP cua no 1 bac tuc la STATE MICROCHIP |*
*| +Ngo vao : Khong |*
*| +Tra ve: Trang thai TREN 1 CAP cua trang thai HIEN TAI |*
*+---------------------------------------------------------------------------+*/
int8 QueryLastMenu() {
int8 i; //Mang Menu dang duoc hien thi co SubMenu
for(i=0; i
if(MenuOfTuan[i].MenuID == MenuPoiter[0].SubMenu) //mot bac
return MenuOfTuan[i].SubMenu;
}
return 0x00;
}
/*+---------------------------------------------------------------------------+*
*| Ham HasSubMenu: Co chuc nang kiem Tra Xem 1 Item Co ton tai Menu CON ko |*
*| Dieu nay la can thiet, Neu mot Item co Menu CON thi Khi AN ENTER |*
*| phai Hien thi TAT CA Menu CON cua Item nay, neu Ko co Menu CON thi THI |*
*| HANH Chuc nang cua Item do |*
*| + Ngo vao: Trang thai hien tai (STATE) |*
*| + Tra ve Gia tri TRUE neu co Menu CON, nguoc lai la FALSE |*
*+---------------------------------------------------------------------------+*/
BOOLEAN HasSubMenu() {
int8 i;
for(i=0; i
if(STATE == MenuOfTuan[i].SubMenu) //Neu trang thai hien tai giong voi
return TRUE; //SubMenu thi no chinh la Menu con
} //cua Trang thai HIEN TAI, nghia la co
return FALSE; //Menu con, nguoc lai: KHONG CO
}
/*+---------------------------------------------------------------------------+*
*| Ham ProcessMenu: Dung de hien thi Mang Menu MenuPoiter da duoc LOC |*
*| Co Phan trang de khi Chi muc tro den 1 Item vuot qua so Item thi Reset |*
*| +Ngo vao: PAGE -> Chi muc (TRANG) cua mot Mang menu da loc (MenuPoiter) |*
*| ContainMenu -> So Menu trong Mang Menu |*
*| +Tra ve: KHONG |*
*+---------------------------------------------------------------------------+*/
void ProcessMenu() {
int8 PageTemp; //LCD co 2 dong, PAGE tro dong 1, PageTemp->d2
if(PAGE == 0xFF) { //Khi an UP or DOWN lam cho PAGE giam tu 0->0xFF
PAGE = ContainMenu - 1; //hay hi PAGE > Tong so Menu hien thi ....
PageTemp = 0; //Thi can phai tro LAI sao cho khi nhin thay
} //Menu nhu duoc cuon tron.->DAY LA 1 CACH
else if(PAGE >= ContainMenu) {
PAGE = 0;
PageTemp = 1;
} else if(PAGE == (ContainMenu - 1)) PageTemp = 0;
else PageTemp = PAGE + 1;
//In ra dong thu 1, va dong thu 2
printf(lcd_putc,"\f>%s",MenuPoiter[PAGE].MenuName);
if(ContainMenu > 1)
printf(lcd_putc,"\n %s",MenuPoiter[PageTemp].MenuName);
}
/*+---------------------------------------------------------------------------+*
*| Ham ProcessAction: La Ham QUANG TRONG nhat trong ca chuong trinh |*
*| Ham nay tuy thuoc vao gia tri PHIM NHAN dua vao ma thi hanh MENU 1 cach |*
*| phu hop, se giai thich ro hon trong noi dung cua HAM |*
*| +Ngo vao: gia tri PHIM NHAN, TRANG hien tai, TRANG THAI hien tai |*
*| +Tra ve: KHONG |*
*+---------------------------------------------------------------------------+*/
void ProcessAction(int16 Key) {
if(STATE == BEGIN) AccessCANCEL = FALSE; //Neu TRANG THAI dang o CAP cao nhat
else AccessCANCEL = TRUE; // thi NUT NHAN CANCEL bi vo hieu
switch(Key) {
case ENTER:
if(!AccessENTER) break; //Neu la nut nhan ENTER va ENTER duoc cho phep
LEVEL[LevelPtr] = PAGE; //Luu Trang Hien hanh, va ngan xep
LevelPtr++; //len 1 don vi
STATE = MenuPoiter[PAGE].MenuID; //Lay trang thai MOI, ung voi su lua chon
PAGE = 0; //Khoi dau tu TRANG 0
ContainMenu = QueryMenu(); //Kiem tra co bao nhien MENU CON
if(ContainMenu) {
ProcessMenu(); //Neu nhieu hon 0, thi hien thi
}else {
AccessENTER = FALSE; //Nguoc lai la Item cuoi cung, ko co Menu con
switch(STATE){ //Do do Disable nut ENTER, va Kiem tra xem
case PIC877A: //Neu tu Item PIC 16F877A thi thuc hien
lcd_putc("\fHi 16F877A");
break;
case PIC84: //Neu tu PIC 16F84 thi ...
lcd_putc("\fHi 16F84");
break;
case AVR: //...
lcd_putc("\fHi AVR");
break;
case MCS51:
lcd_putc("\fHi MCS51");
break;
case COOLRUNNER:
lcd_putc("\fHi Cool Runner");
break;
case VIRTEX:
lcd_putc("\fHi VirTex");
break;
case PIC18:
lcd_putc("\fHi PIC 18F4550");
break;
case DSPIC:
lcd_putc("\fHi dsPIC");
break;
}
}
break;
case UP: //Neu la NUT UP va ENTER duoc cho phep
if(!AccessENTER) break;
PAGE --; //Giam TRANG HIEN TAI va HIEN THI
ProcessMenu();
break;
case DOWN: //Neu la NUT DOWN va ENTER duoc cho phep
if(!AccessENTER) break;
PAGE ++; //Tang TRANG HIEN TAI va HIEN THI
ProcessMenu();
break;
case CANCEL: //Neu la CANCEL va NUT CANCEL duoc cho phep
if(!AccessCANCEL) break;
if(LevelPtr) LevelPtr--; //Lay TRANG da luu truoc do tu ngan xep
PAGE = LEVEL[LevelPtr]; //giam con tro ngan xep
if(!HasSubMenu()) { //Neu Item Hien hanh khong co Menu CON
AccessENTER = TRUE; //Cho Phep nhu ENTER tro lai
STATE = MenuPoiter[PAGE].SubMenu;
} else { //Neu trang hien hanh co Menu CON
STATE = QueryLastMenu(); //Lay TRANG THAI Tren no 1 CAP
}
ContainMenu = QueryMenu();
ProcessMenu(); //Hien thi Menu
break;
case MENU:
ContainMenu = QueryMenu();
ProcessMenu();
Break;
}
}
/*
Chuong trinh con Quet PHIM dung de TEST cho MENU nay, khong QUAN TRONG, co ban
la no se goi MA PHIM UP, DOWN, ENTER, CANCEL toi cho ham ProcessAction khi mot
trong cac PHIM duoc nhan va duoc tha (OnRelease)
*/
int8 keyscan() {
int8 inB, varRet;
inB = input_b()&0xF0;
if(inB != 0xF0){
varRet = inB;
delay_ms(20);
inB = input_b()&0xF0;
if(inB == 0xF0) {
return varRet;
} else {
return 0;
}
}
}
/*Chuong trinh CHINH
*/
void Main() {
int8 key;
set_tris_b(0xFF); //Khoi tao PORTB -> INPUT
lcd_init(); //Khoi tao LCD
processAction(MENU); //Hien thi MENU Chinh
while(1){
key = keyscan(); //Cho Phim NHAN
if(key) { //Neu PHIM nhan HOP LE, hien thi
processAction(key);
}
}
}
| |
|
| | | | | | | |
No comments:
Post a Comment