Понадобился дублер сигналов с пульта кондиционеров.
Сигналы должен был считывать и воспроизводить без зависимости от протоколов.
Было решено считывать длительности сигналов и пауз между ними и сохранять длительности в массив в микросекундах.
Потом воспроизводить их последовательность обратно.
В протеусе вроде все сохраняется и воспроизводится по длительности норм, но вот что то не могу решить вроде простую задачку – с несущей частотой ИК диода.
Как ее правильнее реализовать, исходя из моего кода?
Код: Выделить всё
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
uint16_t signal[200]; // Массив хранения счетчика
uint8_t n_signal; // Переменная порядкового номера записи в массив
uint8_t sw; // Переменная последовательности действий Свитч1
ISR(INT0_vect){ // Обраьотчик внешнего прерывания (читаем импульсы)
switch (sw){
case 0:
TIMSK|=(1<<TOIE1); // Разрешаем прирывание по переполнению
TCCR1B|=(1<<CS10); // настройка таймер-счетчика без делителя, 1 такт=1мкс
TCNT1=0; // Обнуляем счетный регистр
sw=1; // Переход к следующему действию
PORTD&= ~(1<<PIND7);
break;
case 1:
signal [n_signal]=TCNT1; // Сохраняем значение счетчика в массив
TCNT1=0;
n_signal++; // Инкркментируем порядковый номер в массиве
break;
}
}
ISR(TIMER1_OVF_vect){ // Обработчик прерывания по переполнению (отклчаем все, если пауза длинная)
TCCR1B&= ~(1<<CS10); // Выключаем таймер-счетчик
TIMSK&= ~(1<<TOIE1); // Запрещаем прирывание по переполнению
GICR&= ~(1<<INT0); // Запрещаем работу внешнего прерывания
TCNT1=0; // Обнуляем счетный регистр
print_N_Signals(); //выводим количиство считаных имульсов
sw=0;
n_signal=0;
}
ISR(TIMER1_COMPB_vect){ // Обрпботчик прерывания по совпадению
n_signal++;
if (signal[n_signal]!=0)
{
PORTD^=(1<<PIND5); // Инвертируем состояние ИК светодиода
TCNT1=0; // Обнуляем счетный регистр
OCR1B= signal[n_signal]; // устанавливаем в регистр совпадения Новое сохраненное значение
}
else
{
TCCR1B&= ~(1<<CS10); // Выключаем таймер-счетчик
TIMSK&= ~(1<<OCIE1B); // Запрешаем прирывание по совпадению
OCR1B=0; // Обнуляем регистр сравнения
TCNT1=0; // Обнуляем счетный регистр
PORTD&= ~(1<<PIND5); // Отключаем ИК светодиод
print_N1_Signals(); // Выводим количиство Блинков имульсов
n_signal=0;
}
}
int main(void)
{
lcd_init();
DDRD &= ~(1<<2); // Порт пина 3 INT1 на вход
PORTD|=(1<<PIND2); // Пин порта 3 - Высокий потенциал
DDRD &= ~(1<<4); // Порт пина 4 (кнопка) на вход
PORTD|=(1<<PIND4); // Пин порта 4 - Высокий потенциал
DDRD &= ~(1<<1); // Порт пина 1 (кнопка) на вход
PORTD|=(1<<PIND1); // Пин порта 1 - Высокий потенциал
DDRD|=(1<<7); // Настройка порта Сигнального светодиода
PORTD&= ~(1<<PIND7); // Настройка пина Сигнального светодиода
DDRD|=(1<<5); // Настройка порта ИК светодиода
PORTD&= ~(1<<PIND5); // Настройка пина ИК светодиода
sei(); // разрешить глобально прерывания.
print_N_Signals(); //выводим количиство считаных имульсов
_delay_ms(5);
while (1)
{
if (~PIND&(1<<PIND4)){ // кнопка старта записи сигнала
_delay_ms(200);
n_signal=0;
print_N_Signals();
MCUCR|=(1<<ISC00); // Настраиваем прерывание по любому изменению уровня
GICR|=(1<<INT0); // Разрешаем работу внешнего прерывания
PORTD|=(1<<PIND7); // Зажигаем светодиод
}
if (~PIND&(1<<PIND1)){ // кнопка старта воспроизведения сигнала
_delay_ms(200);
n_signal=0;
if (signal[n_signal]!=0){
TCCR1B|=(1<<CS10); // Включаем таймер-счетчик без делителя
TIMSK|=(1<<OCIE1B); // Разрешаем прирывание по совпадению
PORTD|=(1<<PIND5); // Зажигаем IR светодиод
OCR1B|= signal[n_signal]; // устанавливаем в регистр совпадения первое сохраненное значение
}
}
}
}




