[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Декодирование сигналов протокола NEC на ATmega324
christianДата: Суббота, 22.04.2017, 20:22 | Сообщение # 1
Группа: Пользователи
Сообщений: 4

Статус: Offline
Здравствуйте уважаемые,
Есть готовый проект декодирование сигналов протокола 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, но думаю тоже самое.


 
  • Страница 1 из 1
  • 1
Поиск: