Новичок
Регистрация: 19.04.2011
Сообщений: 2
Репутация: 10
|
Здравствуйте!
Прошу помощи у знатоков! Задача заключается в том, чтобы кнопкой power на пульте ДУ потушить гирлянду, а повторным нажатием на power включить гирлянду с того же case, на котором она была выключена? Чтобы после подачи питания на контроллер (если питание было выключено) программа также продолжила работу с того же case на котором питание было выключено. Что я не так делаю? Срабатывание от кнопки POWER не постоянное (иногда надо трижды нажать, чтобы произошло переключение программы или вызов программы после отключения питания). И не удается включить последнюю исполняемую программу после подачи питания (т.е. не задействую кнопку POWER, подать питание и сразу включилась бы последняя исполняемая программа). Код:
#include "delay.h" #include "rc5.h" #include "main.h" eeprom int d_eep; int lastCommand = 1; // последняя полученная команда. Считываем её с eeprom int state = 0; // состояние void main (void) { PORTB = 0b00000000; DDRB = 0b00000000; // светодиоды и на РВ7 ИК-порт PORTC = 0b00000000; DDRC = 0b00000000; // светодиоды PORTD = 0b00000000; DDRD = 0b11111100; // светодиоды Rc5_SetRx(); lastCommand = d_eep; #asm ("sei") while(1) { if (rc5.dataOK) { rc5.dataOK = 0; if (rc5.command == 12) { // нажатие кнопки POWER if (state) { // если гирлянда включена state = 0; PORTD=0b00000000; d_eep = lastCommand; // тушим гирлянду и сохраняем lastCommand в eeprom } else { state = 1; lastCommand = d_eep; rc5.command = lastCommand; } } if (state) // если включено state = 1; switch (rc5.command) { case 1: while (rc5.dataOK==0) { // программа по нажатию 1 lastCommand = rc5.command; // сохраняем последнее нажатие d_eep = lastCommand; PORTD=0b00000100; delay_ms(500); PORTD=0b00001000; delay_ms(500); PORTD=0b00000100; delay_ms(500); } break; case 2: while (rc5.dataOK==0) { // программа по нажатию 2 lastCommand = rc5.command; // сохраняем последнее нажатие d_eep = lastCommand; PORTD=0b00001100; delay_ms(500); PORTD=0b00011000; delay_ms(500); PORTD=0b00010100; delay_ms(500); } break; case 3: while (rc5.dataOK==0) { // программа по нажатию 3 lastCommand = rc5.command; // сохраняем последнее нажатие d_eep = lastCommand; PORTB=0b00000000; PORTD=0b00000100; delay_ms(100); PORTB=0b00000000; PORTD=0b00001100; delay_ms(100); PORTB=0b00000000; PORTD=0b00011100; delay_ms(100); PORTB=0b00000000; PORTD=0b00111100; delay_ms(100); PORTB=0b00000000; PORTD=0b01111100; delay_ms(100); PORTB=0b00000000; PORTD=0b11111100; delay_ms(100); PORTB=0b00000001; PORTD=0b11111100; delay_ms(100); PORTB=0b00000011; PORTD=0b11111100; delay_ms(100); } break; } } } delay_ms(700); rc5.dataOK = 0; } |
||
Оценка
|
Новичок
Регистрация: 08.05.2012
Сообщений: 184
Репутация: 36
|
а если так
eeprom int d_eep@0x10; тогда у вас переменная точно будет сидеть на своем месте в еепром |
||
Оценка
|
Новичок
|
вы все делаете не так.
эффекты гирлянды нужно сделать асинхронными, т.е. по таймеру, а не задержками в главном цикле. я бы вообще рекомендовал создать двумерный массив во FLASH, где по одному измерению номер эффекта, а по другому - последовательность, выводимая в порт. в этом случае по таймеру надо просто брать из массива очередной элемент в строке и выводить в порт. в этом случае в основном цикле вы будете только принимать команды с пульта и их обрабатывать.
__________________
меня всегда можно найти здесь: http://arv.radioliga.com |
||
Оценка
|
Новичок
Регистрация: 19.04.2011
Сообщений: 2
Репутация: 10
|
Цитата:
вы все делаете не так.
эффекты гирлянды нужно сделать асинхронными, т.е. по таймеру, а не задержками в главном цикле. я бы вообще рекомендовал создать двумерный массив во FLASH, где по одному измерению номер эффекта, а по другому - последовательность, выводимая в порт. в этом случае по таймеру надо просто брать из массива очередной элемент в строке и выводить в порт. в этом случае в основном цикле вы будете только принимать команды с пульта и их обрабатывать. Буду разбираться. |
||
Оценка
|
Новичок
Регистрация: 20.11.2012
Сообщений: 43
Репутация: 25
|
RC5 хорошо по прерываниям захватывается (ждешь первый перепад, отступаешь по таймеру 444мкс - пол импульса, далее через 888мкс фиксируешь состояния, и поскольку события достаточно редкие, декодирование выполняешь сразу в обработчике прерывания - соотв есть возможность прервать процесс, если в пакете ошибка) нагрузка минимальная. по готовности флаг. Тогда совершенно не важно что делаешь в главном цикле, главное чтобы все твои ожидания не стопорили прерывания и задействованный таймер не трогали, а так, просто "просыпаешь" посылку. Вообще в главном цикле обычно не хорошо ждать с целью выстроить длительный алгоритм в цепочку. Режешь алгоритм на элементарные стадии, сопоставляешь стадиям флаги. В главном цикле проверяешь флаги состояния (например таймер еще не вышел) если еще нужно ждать - просто пропускаешь обработку и даешь главному циклу крутиться дальше.
|
||
Оценка
|
Обратная связь РадиоЛоцман Вверх |