12864lcd顯示屏多級選單程式碼實現
阿新 • • 發佈:2019-02-03
#include <avr/io.h> #include <util/delay.h> #include "lcd.h" #define menu_level 3 //選單表個數 #define menu_mete 14 //所有選單選項個數 struct option{ uchar key_level;//當前選單選項所屬選單表 uchar enter_index;//進入的index uchar cancel_index;//退出index uchar key_word[16];//選單描述文字 uchar word_mete;//選單文字個數 }; struct option menu_option[menu_mete] ={ {0,4,0,"時間功能設定",12},//0 {0,9,1,"溫溼功能設定",12},//1 {0,menu_mete-1,2,"實時顯示",8},//2 {0,menu_mete-1,3,"關於系統",8},//3 {1,menu_mete-1,0,"系統時間設定",12},//4 {1,menu_mete-1,0,"系統日期設定",12},//5 {1,menu_mete-1,0,"鬧鐘一設定",10},//6 {1,menu_mete-1,0,"鬧鐘二設定",10},//7 {1,menu_mete-1,0,"鬧鐘三設定",10},//8 {2,menu_mete-1,0,"溫度上限設定",12},//9 {2,menu_mete-1,0,"溫度下限設定",12},//10 {2,menu_mete-1,0,"溼度上限設定",12},//11 {2,menu_mete-1,0,"溼度下限設定",12}, //12 {0,0,0,"",0}//13 }; uchar level[menu_level][3] ={ {0,3,4}, {4,8,5}, {9,12,4} }; uchar first_line_disp_index=0;//螢幕第一行顯示的選單index值 uchar select_line=1;//當前選擇的行 uchar select_index=0;//當前選擇的行的引索(index) uchar last_index=0;//進入功能函式前的引索值 uchar last_first_line_index = 0; uchar last_line = 0; void turn_select_white(void); void reflash_lcd(void); void on_menu_step_down(void); void on_menu_step_up(void); void on_menu_enter(void); void on_menu_back(void); /*void wait_until_key_pressed(void) { uchartemp1,temp2; //uint i; do { temp1 = PIND; _delay_ms(10); temp2 = PIND; temp1 &=temp2; } while(temp1& _BV(PIND2)); loop_until_bit_is_set(PIND,PIND2); }*/ void key_jump(void) { if( (PINC& 0x10)==0x00) on_menu_step_up(); else if ((PINC & 0x04) ==0x00) on_menu_enter(); else if ((PINC & 0x20) ==0x00 ) on_menu_step_down(); else if ((PINC & 0x08) ==0x00) on_menu_back(); } uchar is_menu_level_start(void) { uchari=menu_level; do { if( select_index == level[--i][0]) return1; } while(i); return 0; } uchar is_menu_level_end(void) { uchari=menu_level; do { if(select_index== level[--i][1]) return1; } while (i); return 0; } void on_menu_step_down(void) { lcd_gotoxy(0,select_line-1); lcd_putc(0x20); if(is_menu_level_end()) { first_line_disp_index= level[menu_option[select_index].key_level][0]; select_line= 1; select_index= level[menu_option[select_index].key_level][0]; reflash_lcd(); } else { if(select_line==4) { first_line_disp_index+=4; select_line=1; select_index= first_line_disp_index; reflash_lcd(); } else { select_line++; select_index++; turn_select_white(); } } } void on_menu_step_up(void) { lcd_gotoxy(0,select_line-1); lcd_putc(0x20); if(is_menu_level_start() ) { if((level[menu_option[select_index].key_level][2] % 4) ==0) { first_line_disp_index= level[menu_option[select_index].key_level][1] -3;//level[menu_option[select_index].key_level][1]-4+1 select_line=4; select_index= level[menu_option[select_index].key_level][1]; } else { first_line_disp_index=level[menu_option[select_index].key_level][0]+level[menu_option[select_index].key_level][2]-(level[menu_option[select_index].key_level][2] % 4); select_line=1; select_index=first_line_disp_index; } reflash_lcd(); } else { if(select_line==1) { first_line_disp_index-=4; select_line=4; select_index-= 1; reflash_lcd(); } else { select_line--; select_index--; turn_select_white(); } } } void on_menu_enter(void) { last_index =select_index; last_first_line_index= first_line_disp_index; last_line =select_line; first_line_disp_index= menu_option[select_index].enter_index; select_index= menu_option[select_index].enter_index; select_line =1; reflash_lcd(); } void on_menu_back(void) { first_line_disp_index= last_first_line_index; select_line =last_line; select_index= last_index; reflash_lcd(); } void reflash_lcd(void) { uchari,count; lcd_clr_screen(); count =level[menu_option[select_index].key_level][1]-first_line_disp_index+1; if(count>4) count=4;//level[menu_option[select_index].key_level][2]-; //else //count=4; for(i=0;i<count;i++) { lcd_gotoxy(1,0+i); lcd_puts(& menu_option[first_line_disp_index+i].key_word[0]); } turn_select_white(); } void turn_select_white(void) { lcd_gotoxy(0,select_line-1); lcd_putc(0x1A); } int main (void) { ucharrecent_key = 0x00; DDRD =~_BV(PIND2); PORTD |=_BV(PIND2); DDRC &=0b111000011; PORTC |=0b000111100; lcd_init(); lcd_clr_gram(); reflash_lcd(); while(1){ if(PINC != recent_key) { recent_key= PINC; key_jump(); _delay_ms(10); } } return 0; }