Пишу менюшку для LCD на HD44780...В общем : котролеер--ATMega48 дисплей--смотри выше

, имеется 3 кнопки для управления меню : "влево" ,"вправо" , "enter" Меню на 3 пункта , циклическое. Пункты менрю названы move, heat, mixing . При нажатии кнопки enter при выведеном на экран соотв. пункте меню зажигается доп. символ во в второй строке, типа выполняется действие сотв. этому пункту. При повторном нажатии в этом же пункте на enter действие прекращается , значек исчезает .
Все работает , пока в качестве действия просто зажигаются/гаснут светодиоды . А если нужно так: действие 1 пункта--светодиод мигает , переходим на 2-й пункт , светодиод продолжает мигать , включаем/выключаем другой СД. Вот с миганием как раз-то и не
получается

СД мигает до тех пор пока находимся в соотв пункте меню , а после перехода в другой---перестает. Как правильнее сделать обработку, чтобы СД продолжал мигать при переходе в другие пункты ? Привожу полный текст кода, постарался все прокомментировать
Код: Выделить всё
#include <avr/io.h>//Стандартная библиотека ввода/вывода
#include <avr/interrupt.h>//Библиотека прерываний
#include "bits_macros.h" //макросы для работи с битами , в кавычках т.к. нах. в папке
//с проектом
unsigned char mode=0;//Переменная пункта меню
int enter=0;//Переменная нажатия кнопки Enter
unsigned char ON0=1; //Переменная вывода значка и действия для пункта меню 1
unsigned char ON1=1; //Переменная вывода значка и действия для пункта меню 2
unsigned char ON2=1; //Переменная вывода значка и действия для пункта меню 3
int flag=0;//Флаг вывода на экран пункта меню
#define RS 2 //Вывод RS ЖКИ на вывод PD2 МК
#define E 3 //Вывод E ЖКИ на вывод PD3 МК
#define TIME 10//10
//вращение мотора влево , для L293D
#define left() SetBitVal(PORTB,1,1);\
SetBitVal(PORTB,2,0);
//вращение мотора вправо , для L293D
#define right() SetBitVal(PORTB,1,0);\
SetBitVal(PORTB,2,1);
//остановка мотора, для L293D
#define stop() SetBitVal(PORTB,1,0);\
SetBitVal(PORTB,2,0);
void lcd_init (void);//Инициализация ЖКИ
void lcd_dat (unsigned char lcd);//Программа записи данн
void lcd_com (unsigned char lcd);//Программа записи комманд в ЖКИ
void pause (unsigned int a);//Переменная для программы задержки(паузы)
void l_pause (unsigned int b); // длинная пауза
void MOVE (void);//Двигаем каретку
void HEAT (void); //Греем воду
void MIXING (void);//Перемешиваем воду
void l_r_move (void);//двигаемся туда-сюда
//Обработчик прерываний по таймеру 0, в нем опрашиваем кнопки
ISR(TIMER0_OVF_vect)
{
if ((PINC &(1<<PC0))==0)//Если низкий уровень на PC0 есть
{
pause(1000); //Ждем 0.01с
pause(1000);
if ((PINC &(1<<PC0))==0)//Если низкий уровень на PC0 есть
{
while ((PINC &(1<<PC0))==0);//Ждем отжатия клавиши
mode=(mode+1)%3;//Меняем переменнюу пункта меню в +1
flag=0;//Меняем флаг на 0
}
TCNT0=0x00;//Очищаем счетчик таймера 0
TIFR0=0x00; //и флаг переполнения
}
else //Если на PC0 нет низкого уровня
if ((PINC &(1<<PC1))==0)//проверяем низкий уровень на PC1
{
pause(1000); //Если есть Ждем 0.01 с
pause(1000);
if ((PINC &(1<<PC1))==0) //проверяем низкий уровень на PC1 еще раз
{
while ((PINC &(1<<PC1))==0); //Ждем отжатия клавиши
mode=(mode-1)%3;////Меняем переменнюу пункта меню в - 1?
if (mode==255)//(0-1)%3=255, если этого условия не проверять, то при переходе
mode=mode-1;//из п3 в п1 (при следовании назад), нужно нажать кнопку 2 раза
flag=0;//Меняем флаг на 0
}
TCNT0=0x00;//Очищаем счетчик таймера0
TIFR0=0x00; //И флаг переполнения
}
else
if ((PINC &(1<<PC2))==0)//Если низкий уровень на PC2 есть (кн. enter)
{
pause(1000);
pause(1000);
if ((PINC &(1<<PC2))==0)
{
while ((PINC &(1<<PC2))==0);//Ждем отжатия клавиши
{enter=1 ;//enter нажат
if (mode==0) //при каком пункте на экране нажат,то действие и вкл...
{ON0=!ON0;}//прекидываем флаг действия делать\не делать , триггер
//для каждого пункта меню соотв.
if (mode==1)
{ON1=!ON1;}
if (mode!=0 && mode!=1)//третий пункт меню
{ON2=!ON2;}
}
}
TCNT0=0x00;//Очищаем счетчик таймера0
TIFR0=0x00; //И флаг переполнения
}
return;
}
//Программа вывода строки на ЖКИ
void lcd_string( char *s )
{
while( *s ) //цикл пока указатель существует
lcd_dat( *s++ ); //выводить строку
}
//Программа инициализации таймера 0
void init_timer (void)
{
TIMSK0=(1<<TOIE0); //Разрешить прерывания по переполнению таймера 0
TCCR0B=(0<<CS00)|(1<<CS01)|(0<<CS02); //Делитель =/64
}
//Программа обработки переменной меню
void menu(void)
{
if (mode==0)//Если переменная меню=0
{
if (flag== 0)//Если флаг=0
{
// lcd_com(1);//Чистим экран ЖКИ 0x80
lcd_com(0b10000100);//курсор на 04 позицию.........................
lcd_string("<MOVE>");//Выводим название первого пункта меню 1
lcd_dat(0b00100000) ;//затираем символ от <MIXING>
lcd_com(0b10001011);//курсор на 0B позицию..
lcd_dat(0b00100000) ;//затираем символ от <MIXING>
flag=1;//Переключаем флаг=1
enter=0; //Переключаем enter=0,т.к еще не нажат enter при таком номере меню
MOVE();//идем ф-цию действия для этого пункта меню
}
}
else //иначе
if (mode==1)//Если переменная меню=1
{
if (flag==0)//Если флаг=0
{
// lcd_com(1);//Чистим экран
lcd_com(0b10000100);//курсор на 04 позицию.
lcd_string("<HEAT>");//Выводим название первого пункта меню 2
lcd_dat(0b00100000) ;//затираем символ от <MIXING>
lcd_com(0b10001011);//курсор на 0B позицию..
lcd_dat(0b00100000) ;//затираем символ от <MIXING>
flag=1;//Переключаем флаг=1
enter=0; //Переключаем enter=0, т.к еще не нажат enter при таком номере меню
HEAT();//идем ф-цию действия для этого пункта меню
}
}
else //В любом другом случаи
{
if (flag==0)//Если флаг=0
{
// lcd_com(1);//Чистим экран ЖКИ
lcd_com(0b10000100);//курсор на 04 позицию.
lcd_string("<MIXING>");//Выводим название первого пункта меню 3
//lcd_dat(0b11110101);
flag=1;//Переключаем флаг=1
enter=0;//Переключаем enter=0, т.к еще не нажат enter при таком номере меню
MIXING();//идем ф-цию действия для этого пункта меню
}
}
}
//Программа формирвоания задержки
void pause (unsigned int a)
{ unsigned int i;
for (i=a;i>0;i--);
}
//Программа передачи команд в ЖКИ
void lcd_com (unsigned char lcd)
{ unsigned char temp;
temp=(lcd&~(1<<RS))|(1<<E); //RS=0 – это команда
PORTD=temp; //Выводим на portD старшую тетраду команды, сигналы RS, E
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи команды
temp=((lcd*16)&~(1<<RS))|(1<<E); //RS=0 – это команда
PORTD=temp; //Выводим на portD младшую тетраду команды, сигналы RS, E
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи команды
pause (10*TIME); //Пауза для выполнения команды
}
//Программа записи данных в ЖКИ
void lcd_dat (unsigned char lcd)
{ unsigned char temp;
temp=(lcd|(1<<RS))|(1<<E); //RS=1 – это данные
PORTD=temp; //Выводим на portD старшую тетраду данных, сигналы RS, E
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи данных
temp=((lcd*16)|(1<<RS))|(1<<E); //RS=1 – это данные
PORTD=temp; //Выводим на portD младшую тетраду данных, сигналы RS, E
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи данных
pause(5*TIME); //Пауза для вывода данных
}
//Программа иниализации ЖКИ
void lcd_init (void)
{
lcd_com(0b101011); //4-проводный интерфейс, 5x8 размер символа 101011
pause(100*TIME);
lcd_com(0b1100); //Показать изображение, курсор не показывать
pause(100*TIME);
lcd_com(0x01); //Очистить DDRAM и установить курсор на 0x00 1
pause (100*TIME);
}
//При переключении кнопок продолжает выполняться предыдущее действие ,пока не нажат
//enter в меню этого действия (отключение)
void HEAT(void)
{ while (mode==1)
if(enter==1)
{
if (ON1==1)
{
lcd_com(0b11000100);//курсор на 44 позицию..
lcd_dat(0b00100000); //пробел
SetBitVal(PORTB,3 ,0) ;// выкл диод
SetBitVal(PORTB,4 ,0) ;// выкл диод
}
if (ON1!=1)
{
lcd_com(0b11000100);//курсор на 44 позицию..
lcd_dat(0b11110101);//значек "пузырьки",нагрев
SetBitVal(PORTB,4 ,1) ;
}
}
}
void MIXING (void)
{ while (mode!=0 && mode!=1)
if(enter==1)
{
if (ON2==1)
{
lcd_com(0b11000111);//курсор на 47 позицию..
lcd_dat(0b00100000); //пробел
SetBitVal(PORTB,5,0);//выкл. диод
}
if (ON2==0)
{
lcd_com(0b11000111);//курсор на 47 позицию..
lcd_dat(0b01111110);//значек "перемешивание"
SetBitVal(PORTB,5,1);// вкл диод
}
}
}
void MOVE (void)
{ while (mode==0 )
if(enter==1)
{
if (ON0==1)
{
lcd_com(0b11000010);//курсор на 44 позицию..
lcd_dat(0b00100000); //пробел
}
if (ON0==0)
{
lcd_com(0b11000010);//курсор на 44 позицию..
lcd_dat(0b11111100);//перемешивание
SetBitVal(PORTB,1,1);
pause(10000);
pause(10000);
SetBitVal(PORTB,1,0);
pause(10000);
pause(10000);
}} }
//Основная программа
int main(void)
{
DDRD=0xFC;; //Инициализация портов
PORTD=0x00;
DDRC=0x00;
PORTC=0xFF;
DDRB=0xFF;
PORTB=0x00;
//Задержка, чтобы ЖКИ успел включиться
pause(1000);
lcd_init(); //Инициализация ЖКИ
pause(1000);
init_timer();//Инициализация таймера 0
sei();//Глобально разрешаем прерывания
while(1)//Вечный цикл
{
menu();//Запуск обработки пунктов меню
} }