Здравствуйте уважаемые,
Есть готовый проект декодирование сигналов протокола NEC на ATmega8 ( http://radioparty.ru/prog-av....ecoding ). Хотелось переписать скрипт для ATmega324A. Вот что у меня вышло:
Код
// Декодирование сигналов протокола NEC
#define F_CPU 16000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#define LED_BLINKER(ms,times) for (uint8_t q = 0; q < times; q++) {_delay_ms(ms); PORTD |= _BV(PD7); _delay_ms(ms); PORTD &= ~_BV(PD7); } _delay_ms(25);
#define LED_BLINKER2(ms,times,after) for (uint8_t q = 0; q < times; q++) {_delay_ms(ms); PORTD |= _BV(PD7); _delay_ms(ms); PORTD &= ~_BV(PD7); } _delay_ms(after);
unsigned char signal_time;
static unsigned char ir_ok,ir_decode_ok;
unsigned char ir_code[4]; // Массив для хранения значений адресов и команд
unsigned char ir_signal[33]; // Массив для хранения значений интервалов
// Прерывание по совпадению T1(каждые 560мкс)
ISR(TIMER1_COMPA_vect)
{
signal_time++; // Счетчик интервалов
}
// Внешнее прерывание по INT0
ISR(INT0_vect)
{
static unsigned char i;
// Определяем начало приема посылки
if(signal_time > 9) // (4,5ms+562us)/560 = 9
i = 0; // Выбираем первый интервал
ir_signal [i]= signal_time; // Записываем в буфер значения интервалов
signal_time = 0; // Обнуляем счетчик интервалов
i++; // Следующий интервал
if(i == 33) // Если все интервалы приняты
ir_ok = 1; // Устанавливаем флаг окончания приема сигнала
}
// Функция декодирования сигнала
void ir_decode(void)
{
unsigned char k = 0;
unsigned char signal_length,value = 0;
for(unsigned char i = 0; i < 4; i++) // Обработка байтов адреса или команды
{
for(unsigned char j = 0; j < 8; j++) // Обработка 8-ми битов адреса или команды
{
k++;
value = value >> 1; // Сдвигаем биты вправо
signal_length = ir_signal[k]; // Выбираем следущее значение интервала
if(signal_length > 4) // Если интервал больше (1,675ms+562us)/560 = 4
value = value | 0x80; // Добавляем к старшему разряду единицу
}
ir_code [i]= value; // Запоминаем в буфере байт адреса или команды
value = 0; // Обнуляем значение адреса или команды
}
// Производим явное приведение типов и проверяем принятые байты
if(((unsigned char)ir_code[0] == (unsigned char)~ir_code[1]) && ((unsigned char)ir_code[2] == (unsigned char)~ir_code[3]))
{
ir_decode_ok = 1; // Устанавливаем флаг окончания декодирования сигнала
ir_ok = 0; // Сбрасываем флаг окончания приема сигнала
}
else
{
ir_decode_ok = 0; // Сбрасываем флаг окончания декодирования сигнала
ir_ok = 0; // Сбрасываем флаг окончания приема сигнала
}
}
int main(void)
{
/* ATMEGA8
MCUCR |= (1 << ISC01); // Внешнее прерывание по заднему фронту
GICR |= (1 << INT0); // Разрешение внешнего прерывния по INT0
TCCR1B |= (1 << WGM12)|(1 << CS10); // Режим CTC, предделитель 1
OCR1A = 279; // 1000000/2*(279+1) = 1786Hz(560us)
TIMSK |= (1 << OCIE1A); // Разрешаем прерывание по совпадению Т1
*/
/* ATMEGA324A */
EICRA |= _BV(ISC01); // Внешнее прерывание по заднему фронту
EIMSK |= _BV(INT0); // Разрешение внешнего прерывния по INT0
TCCR1B |= _BV(WGM12); // Режим CTC
TCCR1B |= _BV(CS11); // предделитель(prescaler) clk/8
OCR1A = 559; // 16000000/2*N*(559+1) = 1786Hz(560us) , N = 8 aici, a nu se confunda 559+1 de la 560us, este doar o coincidenta
TIMSK1 |= _BV(1/*OCIEA*/); // Разрешаем прерывание по совпадению Т1
sei(); // Глобально разрешаем прерывания
/* LED BLINK */
DDRD = 0;
DDRD |= _BV(PD7);
while(1) {
if(ir_ok) {
ir_decode(); // Если сигнал принят, декодируем его
LED_BLINKER2(3,10,5);
}
if(ir_decode_ok) // Если обработка сигнала завершена, выводим данные на дисплей
{
LED_BLINKER(5,1);
ir_decode_ok = 0; // Сбрасываем флаг окончания декодирования сигнала
}
}
}
Но, не работает) Я чтото не так делаю в коде или проблема в схеме.
П.С. вместо TSOP1738 у меня TSOP31238, но думаю тоже самое.