#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;
}
12864lcd显示屏多级菜单代码实现
最新推荐文章于 2022-03-30 10:49:04 发布