Код: Выделить всё
#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;
}
}
}