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;

}


©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页