Проводное дистанционное управление автомагнитоллой JVC?

Обсуждаем контроллеры компании Atmel.
Ответить
DrRain
Первый раз сказал Мяу!
Сообщения: 30
Зарегистрирован: Чт янв 01, 2015 18:52:59

Проводное дистанционное управление автомагнитоллой JVC?

Сообщение DrRain »

Доброго времени суток.
Сразу оговорюсь, с AVR знаком очень поверхностно (делал простенькую систему управления нагрузкой с определенным алгоритмом).
Теперь поставил перед собой задачу, сделать пульт управления магнитолой JVC.
В наличии имею описание протокола управления, и значения интересующих меня команд, знаю куда эти команды нужно подавать, и думаю что разберусь со схемотехникой.
Осталось дело за малым, написать программу :) на данный момент у меня каша в голове, для начала мне требуется помощь в упорядке моих действий.
1 делать все буду на Atmega8 (ибо их есть у меня)
2 со схемотехникой тоже все более менее понятно: (5 кнопок, каждая привязана к отдельному пину на МК, при нажатии каждой из кнопок на пин который будет управлять магнитолой должен выходить двоичный код.
Для ясности немного описания протокола:
http://nice.artip.ru/ik-upravlenie-protokol-jvc
3 нужно понять общую структуру программы, и в этом я поплыл :)
как я сейчас понимаю:
3.1) заводим таймер Т2 с частотой 38кГц
3.2) описываем команды и привязываем их к кнопкам
3.3) а вот как генерировать вывод команд да еще и на определенной частоте, я не понимаю совсем никак :)

Если я говорю ерунду, вы меня сильное не бейте, это всего моя вторая затея, и в теоретической части я очень не очень, мне сильно проще сначала разбирать примеры, а уже потом подкреплять все это теорией :)
Pnjom-Penb
Мучитель микросхем
Сообщения: 469
Зарегистрирован: Вс авг 30, 2015 03:52:59

Re: Проводное дистанционное управление автомагнитоллой JVC?

Сообщение Pnjom-Penb »

DrRain писал(а):3.3) а вот как генерировать вывод команд да еще и на определенной частоте, я не понимаю совсем никак
Дык, это ж просто - после распознавания команды, кладете в переменную "Цомманд" код команды и взводите флаг "ЦоммандРэди" (флагом может служить условие if ("Цомманд">0)). Далее в прерывании выводите код 'цомманды' на выход, побитно. По окончании передачи, сбрасываете флаг (обнуляете "Цомманд"). Только таймер понадобится на удвоенную частоту, чтобы выводить как питы, так и лэнды. ;)

_____
Addition: Чёт я поленился читать описание протокола по ссылке, а зря... С учетом того, что там написано, можно либо формировать всё вообще без таймера NOPами (тогда времянки регулируются выбором соответствующей тактовой), либо также - с таймером, имеющим период 526мкс, и описанием команды, включающим 0b10 для единичек и 0b1000 для нулей. Длина команды при этом становится переменной (т.е. её нужно б. хранить в описании) и в памяти она займет, например, 16бит*4/8+1=9байт.

Низкая тактовая хороша для ПДУ на батарейках, но потребует больше памяти для хранения waveform команды, высокая тактовая позволит формировать сигнал из более коротких описаний команд вызовом процедур, выводящих waveform ноликов и единиц. Описание станет короче - 16 бит (2 байта), то бишь - памяти потребууется меньше, а батереек - больше.

Получается, NOPами проще и дешевше, если есть керамичечкий резонатор на частоту кратную 3.802kHz (1.0 / 526мкс).
DrRain
Первый раз сказал Мяу!
Сообщения: 30
Зарегистрирован: Чт янв 01, 2015 18:52:59

Re: Проводное дистанционное управление автомагнитоллой JVC?

Сообщение DrRain »

ну вот, я совсем запутался... :(
задачу я хотел бы решить максимально малой кровью, да и зачем искать резонатор при наличии 3х независимых счетчиков в самом МК.
как я понял ШИМ это не про этот случай?
нужно подавать импульсы шириной 526мкс с периодичностью 1 или 2мс
для того чтобы успеть все это посчитать оптимальной тактовой частотой приняли 38 кГц (526мкс 20 циклов, 0 это 40 циклов, а 1 это 80 циклов )
как я понимаю вывод команды на управляющий пин будет выглядеть как

Код: Выделить всё

//начало команды
PORTB = 00000001;
if (count > (количество циклов на 8,4 мс))
  {PORTB = 00000000;
    if (count > (количество циклов на 4,2 мс))
   {PORTB = 00000001;
      if (count > 20)
      {PORTB = 00000000;
       if (count > 40) 
       {PORTB = 00000001;
}
}
}
}else count =0


если утрированно команда будет выглядеть примерно так? :)
Pnjom-Penb
Мучитель микросхем
Сообщения: 469
Зарегистрирован: Вс авг 30, 2015 03:52:59

Re: Проводное дистанционное управление автомагнитоллой JVC?

Сообщение Pnjom-Penb »

DrRain писал(а):если утрированно команда будет выглядеть примерно так? :)
На уровне журналюги - да, примерно так, однако, на уровне даже начинающего программиста - не так. Все эти if'ы контроллер проскочит подряд, поэтому, даже если предположить, что переменная count объявлена как volatile и меняется таймером, все равно такой код не заработает.
Пойдем "в лоб", для начала...

В ПДУ мелкосхема тактируется от керамического резонатора на 300-500kHz, что намекает на то, что последовательность формируется "в лоб", без таймеров, например так:

Код: Выделить всё

void    SendPit()
{
        PORTx.BITy = 1;
        NOP();
        PORTx.BITy = 0;
        NOP();
}
void    SendLend()
{
        PORTx.BITy = 1;
        NOP();
        PORTx.BITy = 0;
        NOP();
        NOP();
        NOP();
}
void    main()
{
static uint16_t
            uiaCommandLst[20] = { // битовые послед-ти всех команд
                0bBBBBBBBBBBBBBBBBBBBB,
                0bBBBBBBBBBBBBBBBBBBBB,
                0bBBBBBBBBBBBBBBBBBBBB,
                0bBBBBBBBBBBBBBBBBBBBB,
                ...
            };

    while(1)
    {
      uint16_t uiCommand, uiMask, uiCode;

      uiCode        = GgetCode();                      // получить код клавиши, ...
      uiCommand = uiaCommandLst[uiCode];   // транслировать его в код команды

      for(uiMask = 0bF000; uiMask > 0; uiMask >>= 1;)  // Для всех 20-ти бит - ...
      {
        (uiCommand & uiMask)? SendLend();SendPit();    // выдать на выход посл-ть,
                                                                                // соотв-ю очередному биту
      }
    }
}

Это очень схематичный код. Следует подобрать длительность NOP'ов так, чтобы в сумме с выводом в порт получилась правильная выдержка времени. Процедуры SendPit(), SendLend() имеет смысл писать на языке ассемблера, чтобы длительность их исполнения была точно известна.
Ответить

Вернуться в «AVR»