1. 程式人生 > >12864lcd顯示屏多級選單程式碼實現

12864lcd顯示屏多級選單程式碼實現

#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;

}