Организация навигации по меню на примере дисплея 4х20 с контроллером HD44780

Модератор: boogyman

Ответить
Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Организация навигации по меню на примере дисплея 4х20 с контроллером HD44780

#1

Сообщение AntonChip »

Код: Выделить всё

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "hd44780.h"
#include "I2C.h"
#include "ds1307.h"

#define enter           101
#define up              102
#define down            103
#define back            104

#define work            201
#define menu            202
#define menu_1          203
#define menu_2          204
#define menu_1_1        205
#define menu_1_1_1      206
#define menu_1_1_2      207
#define menu_1_2        208
#define menu_1_3        209
#define menu_1_4        210
#define menu_2_1        211
#define menu_2_2        212
#define menu_2_3        213
#define menu_2_4        214

uint8_t parametr_1,parametr_2,parametr_3,parametr_4; 
uint8_t second, minute, hour, day, month, year;
uint8_t status, kod_key, kod_key_pr, cursor_1, cursor_2;

ISR (TIMER2_OVF_vect) // Опрос клавиатуры раз в 32 мс
{
     if((PINB&(1 << PB0)) == 0) kod_key = enter;
else if((PINB&(1 << PB1)) == 0) kod_key = up;
else if((PINB&(1 << PB2)) == 0) kod_key = down;
else if((PINB&(1 << PB3)) == 0) kod_key = back;
else kod_key = 0;
}

void zastavka(void)
{
lcd_gotoxy(0, 0);
lcd_puts("                    ");
lcd_gotoxy(0, 1);
lcd_puts("  :  :      /  /20  ");
lcd_gotoxy(0, 2);
lcd_puts("                    ");
lcd_gotoxy(0, 3);
lcd_puts("   RADIOPARTY.RU    ");
}

int main (void)
{
DDRB = 0x00;
PORTB = 0xFF;	
	
TCCR2 |= (1 << CS22)|(1 << CS21)|(1 << CS20); // T2 для опроса клавиатуры раз в 30 мс
TIMSK |= (1 << TOIE2); // разрешение прерывания по переполнению T2

lcd_init(LCD_DISP_ON); // Инициализация LCD

I2CInit(); // Инициализация I2C

uint8_t temp;
DS1307Read(0x00, &temp);

temp &=~(1 << 7); // Запускаем часы очисткой 7 бита
DS1307Write(0x00,temp);

zastavka();
status = work; // Состояние - работа
sei(); // Общее разрешение прерываний

while(1)
{

if(status == work)
{
uint8_t data;

DS1307Read(0x00,&data); // Читаем секунды
second = (((data & 0xF0) >> 4)*10)+(data & 0x0F);
lcd_gotoxy(6, 1); 
lcd_num_to_str(second, 2);
	
DS1307Read(0x01,&data); // Читаем минуты 
minute = (((data & 0xF0) >> 4)*10)+(data & 0x0F);
lcd_gotoxy(3, 1); 
lcd_num_to_str(minute, 2);
	
DS1307Read(0x02,&data); // Читаем часы
hour = (((data & 0xF0) >> 4)*10)+(data & 0x0F);
lcd_gotoxy(0, 1); 
lcd_num_to_str(hour, 2);

DS1307Read(0x04,&data); // Читаем день месяца
day = (((data & 0xF0) >> 4)*10)+(data & 0x0F);
lcd_gotoxy(10, 1); 
lcd_num_to_str(day, 2);

DS1307Read(0x05,&data); // Читаем месяц
month = (((data & 0xF0) >> 4)*10)+(data & 0x0F);
lcd_gotoxy(13, 1); 
lcd_num_to_str(month, 2);

DS1307Read(0x06,&data); // Читаем год
year = (((data & 0xF0) >> 4)*10)+(data & 0x0F);
lcd_gotoxy(18, 1); 
lcd_num_to_str(year, 2);  
}

if(kod_key != kod_key_pr) // если была нажата кнопка
  {
  switch(status)
    {
	case work:
	switch(kod_key)
	  {
 	  case enter: // если "ввод"
	  lcd_clrscr(); status = menu_1; cursor_1 = 0;
	  break;
	  }
	  break;

	  case menu_1:
	  lcd_gotoxy(2, 0);
	  lcd_puts("MENU_1_1"); 
	  lcd_gotoxy(2, 1);
	  lcd_puts("MENU_1_2"); 
	  lcd_gotoxy(2, 2);
      lcd_puts("MENU_1_3");
	  lcd_gotoxy(2, 3);
      lcd_puts("MENU_1_4");
	  lcd_gotoxy(0, cursor_1);
	  lcd_puts(">");
	  switch (kod_key)
	    {
		case enter:
		if(cursor_1 == 0)   status = menu_1_1;
		if(cursor_1 == 1) {	status = menu_1_2; cursor_1 = 0;}
		if(cursor_1 == 2) {	status = menu_1_3; cursor_1 = 0;}
		if(cursor_1 == 3) {	status = menu_1_4; cursor_1 = 0;}
		lcd_clrscr();     	
		break; 
					
		case up:
		if(cursor_1-- <= 0) cursor_1 = 4;
		if(cursor_1 == 4) {	status = menu_2; cursor_1 = 3; lcd_clrscr();} 						
		lcd_gotoxy(0, cursor_1 + 1); lcd_puts(" ");
		break;
						
		case down:
		if(cursor_1++ >= 4) cursor_1 = 0; 
		if(cursor_1 == 4) {	status = menu_2; cursor_1 = 0; lcd_clrscr();} 
		lcd_gotoxy(0, cursor_1 - 1); lcd_puts(" ");
		break;
		} 
	  break;

	  case menu_2:
	  lcd_gotoxy(2, 0);
	  lcd_puts("TIME/DATE"); // Время и дата
	  lcd_gotoxy(2, 1);
	  lcd_puts("MENU_2_2");
	  lcd_gotoxy(2, 2);
      lcd_puts("MENU_2_3");
	  lcd_gotoxy(2, 3);
      lcd_puts("OUT"); // Выход
	  lcd_gotoxy(0, cursor_1);
	  lcd_puts(">");
	    switch (kod_key)
		  {
		  case enter:
		  if(cursor_1 == 0) { status = menu_2_1; cursor_1 = 7; cursor_2 = 1; lcd_clrscr(); }
		  if(cursor_1 == 1) { status = menu_2_2; cursor_1 = 0; lcd_clrscr(); }
		  if(cursor_1 == 2)	{ status = menu_2_3; lcd_clrscr(); }
		  if(cursor_1 == 3)	{ status = menu_2_4; lcd_clrscr(); }
     	  lcd_clrscr();
		  break; 
					
		  case up:
		  if(cursor_1-- <= 0)  cursor_1 = 4; 
		  if(cursor_1 == 4)   {lcd_clrscr(); status = menu_1; cursor_1 = 3;} 
		  lcd_gotoxy(0, cursor_1 + 1); lcd_puts(" ");
		  break;
						
		  case down:
		  if(cursor_1++ >= 4)  cursor_1 = 0; 
		  if(cursor_1 == 4) {lcd_clrscr(); status = menu_1; cursor_1 = 0;} 
		  lcd_gotoxy(0, cursor_1 - 1); lcd_puts(" ");
		  break;
		  } 
		break;

		case menu_1_1:
		lcd_gotoxy(2, 0);
		lcd_puts("MENU_1_1_1");
		lcd_gotoxy(2, 1);
		lcd_puts("MENU_1_1_2");
		lcd_gotoxy(0, cursor_1);
		lcd_puts(">");	
		lcd_gotoxy(0, !cursor_1); lcd_puts(" ");					
		  switch (kod_key)
		  {
		  case enter:
		  if(cursor_1 == 0) {lcd_clrscr(); status = menu_1_1_1; cursor_1 = 0;}
		  if(cursor_1 == 1) {lcd_clrscr(); status = menu_1_1_2; cursor_1 = 0;}
     	  lcd_clrscr();
		  break; 
					
		  case up:
		  if(cursor_1-- <= 0) cursor_1 = 1;
		  break;
						
		  case down:
		  if(cursor_1++ >= 1) cursor_1 = 0; 
		  break;
		  				
		  case back:
		  lcd_clrscr(); status = menu_1; cursor_1 = 0;
		  break; 
		  } 
		break;

		case menu_1_1_1:
		lcd_gotoxy(0, 0);
		lcd_puts("PARAMETR_1");
        lcd_gotoxy(13, 0);
		lcd_num_to_str(parametr_1, 2);
		lcd_gotoxy(0, 1);
		lcd_puts("PARAMETR_2");
		lcd_gotoxy(13, 1);
		lcd_num_to_str(parametr_2, 2);
		lcd_gotoxy(0, 2);
        lcd_puts("PARAMETR_3");
		lcd_gotoxy(13, 2);
		lcd_num_to_str(parametr_3, 2);
		lcd_gotoxy(0, 3);
        lcd_puts("PARAMETR_4");
        lcd_gotoxy(13, 3); 
        lcd_num_to_str(parametr_4, 2);
		lcd_gotoxy(11, cursor_1);
		lcd_puts(">");
		lcd_gotoxy(11, cursor_1 - 1);
		lcd_puts(" ");					    
		switch (kod_key)
		  {
		  case enter:
		  if(cursor_1++ >= 3) cursor_1 = 0; 
		  break; 
			
		  case up:
		  if(cursor_1 == 0) {if(parametr_1++ >= 10) parametr_1 = 0;}
		  if(cursor_1 == 1) {if(parametr_2++ >= 10) parametr_2 = 0;}						
		  if(cursor_1 == 2) {if(parametr_3++ >= 10) parametr_3 = 0;}
     	  if(cursor_1 == 3) {if(parametr_4++ >= 10) parametr_4 = 0;}
		  break;
						
		  case down:
		  if(cursor_1 == 0) {if(parametr_1-- <= 0) parametr_1 = 10;}
		  if(cursor_1 == 1) {if(parametr_2-- <= 0) parametr_2 = 10;}
		  if(cursor_1 == 2) {if(parametr_3-- <= 0) parametr_3 = 10;}
     	  if(cursor_1 == 3) {if(parametr_4-- <= 0) parametr_4 = 10;}
		  break;
						
		  case back:
		  lcd_clrscr(); status = menu_1_1; cursor_1 = 0;
		  break; 
		  } 
		break;
				
		case menu_1_1_2:
		lcd_gotoxy(0, 0);
		lcd_puts("   PRESS KEY BACK   ");
		switch (kod_key)
		  {
		  case back:
		  lcd_clrscr(); status = menu_1_1; cursor_1 = 1;
		  break;
		  } 
		break;
				
		case menu_1_2:
		lcd_gotoxy(0, 0);
		lcd_puts("   PRESS KEY BACK   ");
    	switch (kod_key)
		  {
		  case back:
		  lcd_clrscr(); status = menu_1; cursor_1 = 1;
          break;
		  }  
		break;

		case menu_1_3:
		lcd_gotoxy(0, 0);
		lcd_puts("   PRESS KEY BACK   ");
    	switch (kod_key)
		  {
		  case back:
		  lcd_clrscr(); status = menu_1; cursor_1 = 2;
          break;
		  }  
		break;
				
		case menu_1_4:
		lcd_gotoxy(0, 0);
		lcd_puts("   PRESS KEY BACK   ");
    	switch (kod_key)
		  {
		  case back:
		  lcd_clrscr(); status = menu_1; cursor_1 = 3;
          break;
		  }  
		break;
			
		case menu_2_1:
		lcd_gotoxy(0, 0);
        lcd_puts("Time:"); // Время
        lcd_gotoxy(7, 0); 
        lcd_num_to_str(hour, 2);
        lcd_gotoxy(10, 0); 
        lcd_num_to_str(minute, 2);
        lcd_gotoxy(13, 0); 
        lcd_num_to_str(second, 2);
		lcd_gotoxy(0, 2);
		lcd_puts("Date:"); // Дата
		lcd_gotoxy(7, 2);
        lcd_num_to_str(day, 2);
        lcd_gotoxy(10, 2); 
        lcd_num_to_str(month, 2);
        lcd_gotoxy(13, 2); 
        lcd_num_to_str(year, 2);
        lcd_gotoxy(cursor_1, cursor_2);
		lcd_puts("^^"); 
        lcd_gotoxy(cursor_1 - 3, cursor_2);
		lcd_puts("  ");
  	
		switch (kod_key)
		  {
		  case enter:
		  cursor_1 = cursor_1 + 3;
		  if(cursor_1 > 13 && cursor_2 == 1) { cursor_1 = 7; cursor_2 = 3; lcd_gotoxy(13, 1); lcd_puts("  ");}
		  if(cursor_1 > 13 && cursor_2 == 3) { cursor_1 = 7; cursor_2 = 1; lcd_gotoxy(13, 3); lcd_puts("  ");}
          break; 
		  		
    	  case up:
		  if(cursor_1 == 7  && cursor_2 == 1) { if(hour++ >= 23) hour = 0;}
		  if(cursor_1 == 10 && cursor_2 == 1) { if(minute++ >= 59) minute = 0;}
		  if(cursor_1 == 13 && cursor_2 == 1) { if(second++ >= 59) second = 0;}
		  if(cursor_1 == 7  && cursor_2 == 3) { if(day++ >= 31) day = 1;}
		  if(cursor_1 == 10 && cursor_2 == 3) { if(month++ >= 12) month = 1;}
		  if(cursor_1 == 13 && cursor_2 == 3) { if(year++ >= 99) year = 0;}
		  break;
		  				
		  case down:
		  if(cursor_1 == 7  && cursor_2 == 1) { if(hour-- <= 0) hour = 23;}
		  if(cursor_1 == 10 && cursor_2 == 1) { if(minute-- <= 0) minute = 59;}
		  if(cursor_1 == 13 && cursor_2 == 1) { if(second-- <= 0) second = 59;}
		  if(cursor_1 == 7  && cursor_2 == 3) { if(day-- <= 1) day = 31;}
		  if(cursor_1 == 10 && cursor_2 == 3) { if(month-- <= 1) month = 12;}
		  if(cursor_1 == 13 && cursor_2 == 3) { if(year-- <= 0) year = 99;}
		  break;
						
		  case back: // Пишем данные в RTC, перед тем как выйти из меню
		  temp = ((hour/10)<<4)|(hour%10);     DS1307Write(0x02,temp);
	      temp = ((minute/10)<<4)|(minute%10); DS1307Write(0x01,temp);
	      temp = ((second/10)<<4)|(second%10); DS1307Write(0x00,temp);
		  temp = ((day/10)<<4)|(day%10);       DS1307Write(0x04,temp);
	      temp = ((month/10)<<4)|(month%10);   DS1307Write(0x05,temp);
	      temp = ((year/10)<<4)|(year%10);     DS1307Write(0x06,temp);					
		  lcd_clrscr(); status = menu_2; cursor_1 = 0;
		  break;
		  }  
		break;

		case menu_2_2:
		lcd_gotoxy(0, 0);
		lcd_puts("   PRESS KEY BACK   ");
		switch (kod_key)
		  {
		  case back:
		  lcd_clrscr(); status = menu_2; cursor_1 = 1;
		  break;
		  }  
		break;

		case menu_2_3:
		lcd_gotoxy(0, 0);
		lcd_puts("   PRESS KEY BACK   ");
		switch (kod_key)
		  {
		  case back:
		  lcd_clrscr(); status = menu_2; cursor_1 = 2;
    	  break;
		  }  
		break;

		case menu_2_4:
    	lcd_clrscr();
		status = work;
		zastavka();
		break;
		}
   // Если нажаты одна из этих кнопок нет автоповтора
   /*if(kod_key == enter || kod_key == back)*/ kod_key_pr = kod_key;
   // иначе автоповтор
  // else kod_key_pr = 0;

      }
   }
}
phpBB [youtube]
menu_lcd420_atmega8.rar
Проект AVRStudio4
(88.45 КБ) 592 скачивания
Ответить