|
Новичок
Регистрация: 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мкс фиксируешь состояния, и поскольку события достаточно редкие, декодирование выполняешь сразу в обработчике прерывания - соотв есть возможность прервать процесс, если в пакете ошибка) нагрузка минимальная. по готовности флаг. Тогда совершенно не важно что делаешь в главном цикле, главное чтобы все твои ожидания не стопорили прерывания и задействованный таймер не трогали, а так, просто "просыпаешь" посылку. Вообще в главном цикле обычно не хорошо ждать с целью выстроить длительный алгоритм в цепочку. Режешь алгоритм на элементарные стадии, сопоставляешь стадиям флаги. В главном цикле проверяешь флаги состояния (например таймер еще не вышел) если еще нужно ждать - просто пропускаешь обработку и даешь главному циклу крутиться дальше.
|
||
|
Оценка
|
| Обратная связь РадиоЛоцман Вверх |