Например TDA7294

Форум РадиоКот • Просмотр темы - STM32 библиотека работы с ИК пультом (NEC)
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Сб ноя 23, 2024 17:06:39

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 38 ]  1,  
Автор Сообщение
Не в сети
 Заголовок сообщения: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Пн мар 07, 2016 21:26:17 
Встал на лапы

Зарегистрирован: Вт янв 31, 2012 20:55:18
Сообщений: 94
Откуда: Екатеринбург
Рейтинг сообщения: 0
Здравствуйте, читатели форума:)
13 страниц форума и ни одного вопроса по управлению с пульта ДУ=)
Уже много времени хотелось разобраться и найти библиотеку декодирования сигналов NEC пультов.
Прочитал теорию, вроде бы всё хорошо и понятно.
С помощью программы RCExplorer (кстати, она сейчас бесплатная. Связался с её автором и он через некоторое время сделал её бесплатной) и давным-давно собранного WinLirc убедился что мой пульт использует NEC протокол. Даже не расширенный.
НО, найденная библиотека почему-то не работает корректно. Зато, как ни странно, декодирует сигналы протокола SANYO (похож на NEC).
Прикладываю "осциллограммы" кнопок пультов. В коде реализуется прием 32 байт. У sanyo их явно больше, но принимаются же!!! а у NEC идет какое-то недополучение (байт 10 не успевают проскочить)
Вложение:
SANYO.PNG [13.89 KiB]
Скачиваний: 1178
Вложение:
NEC.PNG [12.51 KiB]
Скачиваний: 886

Может посмотрите в чём дело? Прикладываю проект в CooCox. Или поделитесь библиотекой для декодирования NEC протокола?

Описание проекта:
Используется таймер TIM2, ИК-фотоприемник подключен по типовой схеме, сигнальный вывод к ножке GPIOA0 (TIM2_CH1).
К отладочной плате подключен 1602 дисплей по четырёхбитной шине.



Добавлю. Принятый код с SANYO на картинке RCExplorer
Вложение:
SANYO1.png [20.57 KiB]
Скачиваний: 584

Как мы видим, теряются 10 байт. Что делать - не знаю)


Вложения:
Комментарий к файлу: CooCox IDE 1.7.5
RemoteC.rar [265.2 KiB]
Скачиваний: 373
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Вт мар 08, 2016 01:29:42 
Прорезались зубы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 12
Зарегистрирован: Сб янв 09, 2016 15:51:17
Сообщений: 200
Рейтинг сообщения: 0
Очень странная библиотека, в своё время у меня не завелась, пришлось стряпать своё.
Вся обработка в прерывании по месту события, в последнем правильно принятом бите - вызов задачи декодирования из спячки. Тупой перебор до совпадения.
При зажатой кнопке и верности принимаемых таймингов - декодируется повтор. В случае посторонних помех - декодирование срывается но не искажается, то-есть ложных срабатываний - ноль. Чего собственно мне и требовалось.
Для иной частоты мк -проще менять TIM2->PSC = 720; в пересчёте процентах от 72мгц.
Ось своя собственная,http://forum.ixbt.com/topic.cgi?id=48:11735. Хотя здесь она применяется всего в одном месте sTask_wake(&table_simvol_bits) , можно заменить на свой метод. Но не рекомендую использование без оси - тупой метод перебора жрёт много времени мк.
Код:
/*
    /// таймер TIM2 72мгц - IR , вход CH1 + CH4
    TIM2->PSC = 720;
    TIM2->CCMR1|=TIM_CCMR1_CC1S_0 | TIM_CCMR1_IC2F_3; //TI1FP1+фильтр
    TIM2->CCMR1 |= (TIM_CCMR1_OC2M_2|TIM_CCMR1_OC2M_1);
    TIM2->CCMR2|=TIM_CCMR2_CC4S_1 | TIM_CCMR2_IC4F_3; //TI1FP2+фильтр
    TIM2->CCR2 = 15800 ;   // детектор тишины
    TIM2->SMCR = (5<<4) | 4; //TI1FP1+Reset Mode
    TIM2->CCER|= TIM_CCER_CC1E | TIM_CCER_CC4P | TIM_CCER_CC4E | TIM_CCER_CC2E;
    TIM2->DIER = TIM_DIER_CC1IE | TIM_DIER_CC2IE; // прерывание от захвата и тишины
    TIM2->CR1 = TIM_CR1_CEN;
*/

volatile uint32_t data_IR;
volatile char *time2_data;
_bitFlag table_simvol_bits;
_bitFlag time2_data_IR_RE;

#define IR_ZERO_L       56  // время передачи нуля

void TIM2_IRQHandler (void)
{
    uint16_t tmp_H;
    uint16_t tmp_L;
    static uint8_t nomer_bit = 32;
    static uint8_t status_bit = 0;
    static uint32_t time2_data_IR;
    if (TIM2->SR & TIM_SR_CC2IF)
        { TIM2->SR = 0; nomer_bit = 32;status_bit = 0; return;}
        else
        {
            tmp_L = TIM2-> CCR4; tmp_H = (TIM2->CCR1) - tmp_L;
            if (status_bit ==0 )
            { if ((tmp_H < ((uint16_t)IR_ZERO_L * 1.25)) && (tmp_L > ((uint16_t)IR_ZERO_L * 7.75))
                        && (tmp_L < ((uint16_t)IR_ZERO_L * 8.25)))
                        { nomer_bit = 32; time2_data_IR =0;status_bit++;}else; return; }else;
            if (status_bit == 1 )
            { if (tmp_H < ((uint16_t)IR_ZERO_L * 1.25))
                { if (tmp_L < ((uint16_t)IR_ZERO_L * 1.25)) nomer_bit--;
                        else
                            { if (tmp_L < ((uint16_t)IR_ZERO_L * 3.25))
                                { nomer_bit--; time2_data_IR |= (uint32_t) 1 << nomer_bit;} else;
                            }
                } else status_bit = 0;
            if (nomer_bit == 0)
                    {data_IR = time2_data_IR; sTask_wake(&table_simvol_bits); status_bit++; return;} else;
            }else;
            if (status_bit == 2 ) // H903-L4000; (H56-L224; H900-L9627;) // (H900-L4000; H56-L228) lg
            {   if ((tmp_H > ((uint16_t)IR_ZERO_L * 15.75)) && (tmp_L > ((uint16_t)IR_ZERO_L * 69))
                    && (tmp_L < ((uint16_t)IR_ZERO_L * 73))) status_bit++;
                    else status_bit = 0;  return;
            }else;
            if (status_bit == 3 )
            {   if ((tmp_H < ((uint16_t)IR_ZERO_L * 1.25)) && (tmp_L > ((uint16_t)IR_ZERO_L * 3.75))
                    && (tmp_L < ((uint16_t)IR_ZERO_L * 4.25))) status_bit++;
                    else status_bit = 0;  return;
            }else;
            if (status_bit == 4 )
            {   if ((tmp_H > ((uint16_t)IR_ZERO_L * 15.75)) && (tmp_L > ((uint16_t)IR_ZERO_L * 166))
                    && (tmp_L < ((uint16_t)IR_ZERO_L * 176)))
                    {status_bit = 3; time2_data_IR_RE = 1;}
                    else status_bit = 0;  return;
            }else;

        }

}

void table_simvol (void)
{
    for(;;)
 {
    if (data_IR == 0)  {time2_data = "..........";  } else;
  if (( data_IR >> 16) == 0x00FF) // пульт от плеера
  {
    data_IR = data_IR & 0xFFFF;
    if (data_IR == 0x38c7)  {time2_data = "POWER";  } else;
    if (data_IR == 0xd22d)  {time2_data = "LCD_ON/OF"; } else;
    if (data_IR == 0xda25)  {time2_data = "MODE";  } else;
    if (data_IR == 0x20df)  {time2_data = "3D";  } else;
    if (data_IR == 0x5aa5)  {time2_data = "PROG";  } else;
    if (data_IR == 0x50af)  {time2_data = "MITE";  } else;
    if (data_IR == 0x00ff)  {time2_data = "REPEAT"; } else;
    if (data_IR == 0x08f7)  {time2_data = "A-B";  } else;
    if (data_IR == 0xa25d)  {time2_data = "1";  } else;
    if (data_IR == 0xe817)  {time2_data = "2";  } else;
    if (data_IR == 0x48b7)  {time2_data = "3";  } else;
    if (data_IR == 0xb847)  {time2_data = "TITLE";  } else;
    if (data_IR == 0x28d7)  {time2_data = "4";  } else;
    if (data_IR == 0xe01f)  {time2_data = "5";  } else;
    if (data_IR == 0xb04f)  {time2_data = "6";  } else;
    if (data_IR == 0x1ae5)  {time2_data = "ANGLE";  } else;
    if (data_IR == 0xd827)  {time2_data = "7";  } else;
    if (data_IR == 0x926d)  {time2_data = "8";  } else;
    if (data_IR == 0x22dd)  {time2_data = "9";  } else;
    if (data_IR == 0x3ac5)  {time2_data = "SUBTITLE";  } else;
    if (data_IR == 0x9867)  {time2_data = "+10";  } else;
    if (data_IR == 0x7887)  {time2_data = "0";  } else;
    if (data_IR == 0x7a85)  {time2_data = "MENU";  } else;
    if (data_IR == 0xc837)  {time2_data = "OSD";  } else;
    if (data_IR == 0xf00f)  {time2_data = "ZOOM";  } else;
    if (data_IR == 0x728d)  {time2_data = "CH+";  } else;
    if (data_IR == 0x629d)  {time2_data = "PBC";  } else;
    if (data_IR == 0x9a65)  {time2_data = "SLOW";  } else;
    if (data_IR == 0x30cf)  {time2_data = "<<-";  } else;
    if (data_IR == 0x609f)  {time2_data = "ENTER";  } else;
    if (data_IR == 0xa05f)  {time2_data = "->>";  } else;
    if (data_IR == 0xc23d)  {time2_data = "RETURN";  } else;
    if (data_IR == 0xf20d)  {time2_data = "AUDIO";  } else;
    if (data_IR == 0xb24d)  {time2_data = "CH-";  } else;
    if (data_IR == 0x32cd)  {time2_data = "GOTO";  } else;
    if (data_IR == 0xe21d)  {time2_data = "SETUP";  } else;
    if (data_IR == 0x10ef)  {time2_data = "VOL+";  } else;
    if (data_IR == 0x42bd)  {time2_data = "<<";  } else;
    if (data_IR == 0x02fd)  {time2_data = ">>";  } else;
    if (data_IR == 0xc03f)  {time2_data = "STOP";  } else;
    if (data_IR == 0x0af5)  {time2_data = "VOL-";  } else;
    if (data_IR == 0x807f)  {time2_data = "|<<";  } else;
    if (data_IR == 0x40bf)  {time2_data = ">>|";  } else;
    if (data_IR == 0x8877)  {time2_data = "PLEY";  } else;
  }else;


  if (( data_IR >> 16) == 0x20DF) // пульт от телека LG
  {
    data_IR = data_IR & 0xFFFF;
    if (data_IR == 0x10ef)  {time2_data = "POWER";  } else;
    if (data_IR == 0x0ff0)  {time2_data = "TV/RADIO";  } else;
    if (data_IR == 0x9c63)  {time2_data = "SUBTITLE";  } else;
    if (data_IR == 0x06f9)  {time2_data = "AD(PIP/*)";  } else;
    if (data_IR == 0xd926)  {time2_data = "TV/PC";  } else;
    if (data_IR == 0xd02f)  {time2_data = "INPUT";  } else;
    if (data_IR == 0x8877)  {time2_data = "1";  } else;
    if (data_IR == 0x48b7)  {time2_data = "2";  } else;
    if (data_IR == 0xc837)  {time2_data = "3";  } else;
    if (data_IR == 0x28d7)  {time2_data = "4";  } else;
    if (data_IR == 0xa857)  {time2_data = "5";  } else;
    if (data_IR == 0x6897)  {time2_data = "6";  } else;
    if (data_IR == 0xe817)  {time2_data = "7";  } else;
    if (data_IR == 0x18e7)  {time2_data = "8";  } else;
    if (data_IR == 0x9867)  {time2_data = "9";  } else;
    if (data_IR == 0xca35)  {time2_data = "LIST";  } else;
    if (data_IR == 0x08f7)  {time2_data = "0";  } else;
    if (data_IR == 0x58a7)  {time2_data = "Q.VIEW";  } else;
    if (data_IR == 0x40bf)  {time2_data = "VOL+";  } else;
    if (data_IR == 0x7887)  {time2_data = "FAV";  } else;
    if (data_IR == 0x00ff)  {time2_data = "CH+";  } else;
    if (data_IR == 0xd52a)  {time2_data = "GUIDE";  } else;
    if (data_IR == 0xc03f)  {time2_data = "VOL-";  } else;
    if (data_IR == 0x906f)  {time2_data = "MITE";  } else;
    if (data_IR == 0x807f)  {time2_data = "CH-";  } else;
    if (data_IR == 0x4fb)  {time2_data = "TEXT";  } else;
    if (data_IR == 0x55aa)  {time2_data = "INFO";  } else;
    if (data_IR == 0x847b)  {time2_data = "T.OPT";  } else;
    if (data_IR == 0xc23d)  {time2_data = "SETTINGS";  } else;
    if (data_IR == 0x02fd)  {time2_data = "TOP";  } else;
    if (data_IR == 0xa25d)  {time2_data = "Q.MENU";  } else;
    if (data_IR == 0xe01f)  {time2_data = "LEFT";  } else;
    if (data_IR == 0x22dd)  {time2_data = "OK";  } else;
    if (data_IR == 0x609f)  {time2_data = "RIGHT";  } else;
    if (data_IR == 0x14eb)  {time2_data = "BACK";  } else;
    if (data_IR == 0x827d)  {time2_data = "BOTTOM";  } else;
    if (data_IR == 0xda25)  {time2_data = "EXIT";  } else;
    if (data_IR == 0x7e81)  {time2_data = "smplink";  } else;
    if (data_IR == 0xbd42)  {time2_data = "RES/*";  } else;
    if (data_IR == 0x8d72)  {time2_data = "STOP";  } else;
    if (data_IR == 0xf10e)  {time2_data = "<<";  } else;
    if (data_IR == 0x0df2)  {time2_data = "PLEY";  } else;
    if (data_IR == 0x5da2)  {time2_data = "PAUSE";  } else;
    if (data_IR == 0x718e)  {time2_data = ">>";  } else;
    if (data_IR == 0x4eb1)  {time2_data = "RED";  } else;
    if (data_IR == 0x8e71)  {time2_data = "GREEN";  } else;
    if (data_IR == 0xc639)  {time2_data = "YELLOW";  } else;
    if (data_IR == 0x8679)  {time2_data = "BLUE";  } else;
  }else;


    sTask_wait (&table_simvol_bits);
 }

_________________
sRtoS


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Вт мар 08, 2016 11:12:41 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 98
Рейтинг сообщений: 2090
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18151
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
трындец какой-то :(

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Вт мар 08, 2016 13:35:17 
Прорезались зубы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 12
Зарегистрирован: Сб янв 09, 2016 15:51:17
Сообщений: 200
Рейтинг сообщения: 0
У меня работает, а у вас?

_________________
sRtoS


Вернуться наверх
 
Приглашаем на вебинар «Решения SUNCO для силовой электроники. Выбираем идеальный силовой модуль»

Приглашаем 3 декабря 2024 на вебинар, посвященный силовым модулям ведущего китайского производителя SUNCO - одного из мировых лидеров по производству дискретных полупроводниковых компонентов. На вебинаре вы узнаете о новинках, включая модули 17 класса в корпусе E3, и контроле качества на всех этапах производства. Вы также узнаете о новейших продуктах – IGBT-, SiC-, диодных и тиристорных модулях, погрузитесь в современные топологии, сравните характеристики IGBT-чипов разных поколений.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Вт мар 08, 2016 13:46:03 
Встал на лапы

Зарегистрирован: Вт янв 31, 2012 20:55:18
Сообщений: 94
Откуда: Екатеринбург
Рейтинг сообщения: 0
AVI-crak писал(а):
У меня работает, а у вас?

А у меня не работает :cry:
Правда, я про свой найденный код. С ОС сталкиваться ой как не хочется - это ж дебри. Если я с портами и таймерами еще не совсем освоился, куда уж ОС....
Ну вот почему он может пропускать 10 байт-то?

Код:
NEC remote power button
NC   0xF4 Инверсия комманды
C    0x0B Комманда
NA   0xF7 инверсия адреса
A    0x08 адрес
     received     bites           | LOST Bites   |
  F   4   |  0    B   |   F    X  |  X    X
1111 0100 | 0000 1011 | 1111 01LL | LLLL LLLL


Заполнение идет с конца, т.е. потерянные байты L находятся после стартовой посылки и паузы.


Вложения:
NEC1.png [14.82 KiB]
Скачиваний: 391
Вернуться наверх
 
Решения SUNCO для надежной защиты сигнальных цепей интерфейсов от электростатических разрядов

Всплески перенапряжения являются серьезной угрозой надежности работы радиоэлектронных устройств. Причины их появления различны, это могут быть коммутационные переходные процессы в системе электропитания устройств, разряды молний, электростатические разряды. Для создания эффективной и современной системы защиты от ЭСР компания SUNCO разработала надежные и качественные супрессоры, представляющие собой TVS- и ESD-диоды, а также сборки на их основе. Компоненты SUNCO не только не уступают, но часто превосходят по характеристикам аналогичную продукцию других брендов.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Вт мар 08, 2016 14:50:53 
Прорезались зубы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 12
Зарегистрирован: Сб янв 09, 2016 15:51:17
Сообщений: 200
Рейтинг сообщения: 0
Ican писал(а):
AVI-crak писал(а):
У меня работает, а у вас?

А у меня не работает :cry:
Заполнение идет с конца, т.е. потерянные байты L находятся после стартовой посылки и паузы.

Ну собственно это и есть проблема, ик передача начинается со старших битов посылки. И первыми есно прилетают 16 бит кода фирмы - уникальный идентификатор принадлежности пульта к железяке, а уже после летит код команды кнопки. Игнорировать идентификатор не желательно, с его помощью можно различать разные пульты.

У меня void TIM2_IRQHandler (void) - это банальное прерывание из cmsis, и не имеет зависимости от ос. На выхлопе volatile uint32_t data_IR; - готовая посылка пульта.
Защита от сбоев, левых пультов, засветок и так далее. При любом отклонении от стандарта - процесс декодирования прерывается. Флагами выставляется состояние декодирования: table_simvol_bits - новые данные, time2_data_IR_RE - повтор команды (зажатая кнопка).

Весь список кнопок - это просто вариант, без ос нужно просто опрашивать флаг table_simvol_bits в бесконечном цикле, и проверять на совместимость чего там прилетело.
Хотя бесконечные циклы - огромное зло, и прежде всего в плане энергопотребления.

Алгоритм? - Дык его итак видно, в коде сплошные IF - куда уж проще.
Тут главное понять, что прилетевший на ик датчик тон 38кгц - событие в прошедшем времени, его нельзя отменить каким-либо образом. Это не радиоприёмник, где можно селекцией отстроится от помехи, тут всё топорно и прямолинейно. Есть тон - ик датчик роняет выход в ноль.
Собственно по этому принципу работает счётчик таймера, в момент прерывания по спаду - мы уже имеем на компараторах 1и4 - два значения, общее время и время единицы. Это тоже событие в прошедшем времени, остаётся просто проверить - насколько оно подходит под наши условия. Компаратор таймера CH2 для того - чтобы поймать событие: "кнопка больше не нажата". Это тоже в прошедшем времени, потому как общее время при не нажимании кнопок получается огромным, есть шанс пропустить стартовую посылку. Число в CH2 - это 1,5 максимального времени в посылке, а именно - задержка перед повтором символа "кнопка зажата". Если срабатывает компаратор CH2 - то процесс декодирования устанавливается в начальное время, и так до момента пока не прилетит первая корректная посылка.

Несколько свободных ик библиотек, в том числе и аурдино - все они измеряют время единицы и нуля в реальном времени, собственно мартышкин труд. Особо упорные измеряют время программными задержками. Причём эти библиотеки живут ещё со времён восмибитных пиков, практически без изменений.

_________________
sRtoS


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Чт мар 10, 2016 21:39:57 
Встал на лапы

Зарегистрирован: Вт янв 31, 2012 20:55:18
Сообщений: 94
Откуда: Екатеринбург
Рейтинг сообщения: 0
Разобрался. Нашел место, где грабли лежат.
было
pos = -10; // change (ТЕРЯЛОСЬ 10 первых байт!!!!)
стало
pos = 0; // change принимается все на ура. Неоптимально, зато принимается.

Всем спасибо, расходимся)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Чт апр 07, 2016 13:49:45 
Первый раз сказал Мяу!
Аватар пользователя

Зарегистрирован: Пн дек 15, 2014 19:04:08
Сообщений: 22
Откуда: г. Пермь
Рейтинг сообщения: 0
Внесу свои 5 копеек. Мне тоже понадобилось подключить пульт ДУ. Я все сделал через захват таймера. У меня плата stm32 Mini, там был свободный вход PA8. Это канал захвата №1 таймера 1. Я видел ваши и другие библиотеки и мягко говоря в шоке. Декодирование пульта это довольно простая задача. У меня больше времени ушло на настройку таймера и прерывания.
Выкладываю здесь свой вариант декодирования (только основные моменты). На выходе имеем переменную NecEnd которая равна нулю или 32-битному коду принятому от пульта. После чтения переменной ее необходимо снова сбросить в 0.

Спойлерuint32_t NecEnd, NecB; // Эти переменные нужно объявить в начале
uint16_t NecData, NecDataOld, NecD;
uint8_t NecA;

// Пример обработки кода пульта
// Хотя бы 10 раз в секунду выполнять этот код
switch (NecEnd) {
case 0: // Ничего не принято
break;
case 2653519744: // 0x9E297F80
// Обработка клавиши "1"
NecEnd=0; // Обнуляем переменную NecEnd
break;
case 2653536064: // 0x9E29BF40
// Обработка клавиши "2"
NecEnd=0;
break;
case 2653503424: // 0x9E293FC0
// Обработка клавиши "3"
NecEnd=0;
break;
default:
NecEnd=0;
}

// ======================
// Настройка таймера
void TIM1_Configuration(void)
{
// создаём переменную (структуру) для определения режима работы таймера
TIM_TimeBaseInitTypeDef Timert1_Base;
TIM_ICInitTypeDef Timert1_ICI;

// TIM1 clock enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

// Базовые настройки таймера
TIM_TimeBaseStructInit(&Timert1_Base);
Timert1_Base.TIM_CounterMode = TIM_CounterMode_Up; // Выбираем режим работы счетчика
Timert1_Base.TIM_Prescaler = 720 - 1; // пред делитель
Timert1_Base.TIM_Period = 0xFFFF; // Коэффициент деления таймера
Timert1_Base.TIM_ClockDivision = TIM_CKD_DIV1; // Определяем частоту для фильтров (tDTS)
Timert1_Base.TIM_RepetitionCounter = 0; // Этот параметр только для Т1 и Т8
TIM_TimeBaseInit(TIM1, &Timert1_Base); // Записываем настройки в регистры

// Настройки каналов таймера на захват
Timert1_ICI.TIM_Channel = TIM_Channel_1; // Выбираем канал (1-4)
Timert1_ICI.TIM_ICPolarity = TIM_ICPolarity_Falling; // Определяем полярность входа
Timert1_ICI.TIM_ICSelection = TIM_ICSelection_DirectTI; // источник: напрямую со входа
Timert1_ICI.TIM_ICPrescaler = TIM_ICPSC_DIV1; // Значение предделителя канала (отключен)
Timert1_ICI.TIM_ICFilter = 15; // Значение фильтра от 0x0 до 0xF
TIM_ICInit(TIM1, &Timert1_ICI); // Записываем настройки в регистры

// На всякий случай сбрасываем флаги
TIM_ClearFlag(TIM1, TIM_IT_CC1);

// Разрешаем таймеру генерировать прерывание по захвату 1ый канал
TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);

// Разрешаем ядру принимать прерывания
NVIC_EnableIRQ(TIM1_CC_IRQn);

// ЗАПУСК таймера TIM1
TIM_Cmd(TIM1, ENABLE);
}

// ======================
// Настройка прерывания
void TIM1_CC_IRQHandler(void)
{
// Смотрим что прерывание от таймера именно по событию захвата 1-ого канала
if (TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET)
{
NecDataOld = NecData;
NecData = TIM_GetCapture1(TIM1); // Читаем значение из регистра захвата
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1); // Очищаем флаг этого прерывания
NecD=NecData-NecDataOld;

switch (NecA) {
case 0:
if (1115<NecD && 1135>NecD){ // повтор
// NecEnd=1; // Раскомментировать строку если нужен повтор
}
else
{
if (1340<NecD && 1360>NecD) NecA=1; // стартовый импульс
}
break;
case 1:
if (100<NecD && 235>NecD){
NecA=2;
}
else
{
NecA=0;
return; // ошибка выходим
}
default:
if (100<NecD && 235>NecD){
NecA++;
NecB = (NecB<<1)+NecD/175; // принимаем 32 бита данных
if (NecA==34){
NecEnd=NecB; // данные приняты успешно
NecA=0;
}
}
else
{
NecA=0;
return; // ошибка выходим
}
}
}
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Чт апр 07, 2016 19:55:58 
Прорезались зубы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 12
Зарегистрирован: Сб янв 09, 2016 15:51:17
Сообщений: 200
Рейтинг сообщения: 0
Andry_67
Нет защиты от помех.
Поиграйся двумя разными пультами одновременно, должно быть либо честное декодирование - либо сброс посылки.

_________________
sRtoS


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Пт апр 08, 2016 13:36:05 
Первый раз сказал Мяу!
Аватар пользователя

Зарегистрирован: Пн дек 15, 2014 19:04:08
Сообщений: 22
Откуда: г. Пермь
Рейтинг сообщения: 0
Защита от помех есть. В строке
if (100<NecD && 235>NecD){
проверяется длительность между двумя импульсами и если длительность выходит за пределы то декодирование прекращается и ожидается новый стартовый импульс.
Цитата:
Поиграйся двумя разными пультами одновременно

А не надо одновременно жать на разные пульты, в этом случае ни у кого ничего работать не будет.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Сб май 14, 2022 21:44:41 
Прорезались зубы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 12
Зарегистрирован: Сб янв 09, 2016 15:51:17
Сообщений: 200
Рейтинг сообщения: 2
Допрограмировался, в поисках нахожу своё старое.
В гитхаб теперь только через телефон, bitbucket.org просто стёр всё мои каракули, ещё парочка репозитариев успела пять раз в прыжке переобуться, а один уникальный склад кода - умудрился буквально сгореть, вместе с датацентром.
А тут даже пылью не покрылось.
ik_nec.с
Спойлер
Код:
/// IK protocol NEC
/// TIMx->PSC = clock frequency of the timer / 50526

#include <stdint.h>
#include "ik_nec.h"
#include "stm32f030x6.h"

#define IK_N 0xFFU /* unnamed china */
//#define IK_N 0xDFU /* LG */
#define DECODER ((uint16_t)((~IK_N)<<8)|IK_N)

volatile uint8_t ik_out;

const uint16_t range_z[] ={
    628,1167,35,66,35,66,634,1177,0,0,
    76,278,76,278,2890,12759,798,1483,2890,12759,949,1764};

void TIM3_IRQHandler (void) //220
{
    uint32_t tmp;
    static uint8_t status = 0;
    static uint8_t poz;
    static uint32_t stor;
    if ((TIM3->SR & (TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF | TIM_SR_CC4IF))
         != (TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF)) goto uno;
    tmp = TIM3->CCR2;
    if (tmp < range_z[status << 1]) goto uno;
    if (tmp > range_z[(status << 1) + 1]) goto uno;
    switch (status)
    {
        case 0: status = 1; poz = 32; stor = 0; tmp = 10; break;
        case 1: tmp = stor << 1;
                if (TIM3->CCR1 > 170) tmp |= 1;
                stor = tmp; poz--; tmp = 12;
            if (poz == 0)
                {
                 /// watch raw IR code
                 /// stor = (~IK_N<<24)|(IK_N<<16)|(~ik_out<<8)|(ik_out)
                    if ((DECODER == (stor >> 16)) && ((((stor >> 8) ^ stor) & 0xFF) == 0xFF))
                    {
                        stor &= 0xFF; ik_out = stor; tmp = 14; status = 2;
                    }else goto uno;
                }; break;
        case 2: status = 3; tmp = 16; break;
        case 3: status = 2; tmp = 18; ik_out = stor; break;
        default: uno: status = 0; tmp = 20; break;
    };
    TIM3->SR = 0;
    TIM3->CCR3 = range_z[tmp++];
    TIM3->CCR4 = range_z[tmp];
};

void ik_tim_init(void)
{
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
    GPIOA->MODER |= _VAL2FLD(GPIO_MODER_MODER6, 2); //Alternate function mode
    GPIOA->AFR[0] |= _VAL2FLD(GPIO_AFRL_AFSEL6, 1);
    TIM3->PSC = 950; /// clock frequency of the timer / 50526 (509us = 51L)
    TIM3->CCMR1 = _VAL2FLD(TIM_CCMR1_CC1S, 1)|
                  _VAL2FLD(TIM_CCMR1_CC2S, 2);
    TIM3->CCER = _VAL2FLD(TIM_CCER_CC1P, 1)|
                 _VAL2FLD(TIM_CCER_CC2P, 0)|
                 _VAL2FLD(TIM_CCER_CC1E, 1)|
                 _VAL2FLD(TIM_CCER_CC2E, 1);
    TIM3->SMCR = _VAL2FLD(TIM_SMCR_TS, 5)| // Filtered Timer Input 1 (TI1FP1)
                 _VAL2FLD(TIM_SMCR_SMS, 4); // Reset Mode (TRGI)
    TIM3->CCMR2 = _VAL2FLD(TIM_CCMR2_OC3M,6)|
                 _VAL2FLD(TIM_CCMR2_OC4M,6);
    TIM3->CCR3 = 949; // 1357 start P
    TIM3->CCR4 = 1764;
    TIM3->DIER = TIM_DIER_CC1IE;
    TIM3->CR1 |= TIM_CR1_CEN;
    NVIC_EnableIRQ(TIM3_IRQn);
}

ik_nec.h
Спойлер
Код:
/// #include "ik_nec.h"


#ifdef _ik_nec_
 extern "C" {
#endif /* _ik_nec_ */

extern volatile uint8_t ik_out;

void ik_tim_init(void);


#ifdef _ik_nec_
}
#endif /* _ik_nec_ */
#define _ik_nec_


Написано для мелкого stm32f030f, требует таймера с поддержкой PWM Input и одним свободным контактом CH1. По протоколу NEC - необходимо выполнить реверс битов в каждом байте, с сохранением порядка байтов. Но мне лень.

_________________
sRtoS


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Ср дек 14, 2022 18:22:21 
Сверлит текстолит когтями
Аватар пользователя

Карма: 11
Рейтинг сообщений: 157
Зарегистрирован: Вт окт 23, 2007 10:01:42
Сообщений: 1274
Откуда: Волгоград
Рейтинг сообщения: 0
AVI-crak, спасибо тебе добрый человек за рабочий код для cmsis!
Оно заработало.
Дефайны только дёрнул, не знаю можно так?
Спойлер
Код:
#define _VAL2FLD(field, value)    (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
//
#define GPIO_MODER_MODER6_Pos           (12U)
#define GPIO_MODER_MODER6_Msk           (0x3U << GPIO_MODER_MODER6_Pos)        /*!< 0x00003000 */
#define GPIO_AFRL_AFSEL6_Pos            (24U)
#define GPIO_AFRL_AFSEL6_Msk            (0xFU << GPIO_AFRL_AFSEL6_Pos)         /*!< 0x0F000000 */
//
#define TIM_SMCR_TS_Pos           (4U)                                         
#define TIM_SMCR_TS_Msk           (0x7UL << TIM_SMCR_TS_Pos)                    /*!< 0x00000070 */
#define TIM_CCMR1_CC1S_Pos        (0U)                                         
#define TIM_CCMR1_CC1S_Msk        (0x3UL << TIM_CCMR1_CC1S_Pos)                 /*!< 0x00000003 */
#define TIM_CCMR1_CC2S_Pos        (8U)                                         
#define TIM_CCMR1_CC2S_Msk        (0x3UL << TIM_CCMR1_CC2S_Pos)                 /*!< 0x00000300 */
#define TIM_CCER_CC1P_Pos         (1U)                                         
#define TIM_CCER_CC1P_Msk         (0x1UL << TIM_CCER_CC1P_Pos)                  /*!< 0x00000002 */
#define TIM_CCER_CC2P_Pos         (5U)                                         
#define TIM_CCER_CC2P_Msk         (0x1UL << TIM_CCER_CC2P_Pos)                  /*!< 0x00000020 */
#define TIM_CCER_CC1E_Pos         (0U)                                         
#define TIM_CCER_CC1E_Msk         (0x1UL << TIM_CCER_CC1E_Pos)                  /*!< 0x00000001 */
#define TIM_CCER_CC2E_Pos         (4U)                                         
#define TIM_CCER_CC2E_Msk         (0x1UL << TIM_CCER_CC2E_Pos)                  /*!< 0x00000010 */
#define TIM_SMCR_SMS_Pos          (0U)                                         
#define TIM_SMCR_SMS_Msk          (0x7UL << TIM_SMCR_SMS_Pos)                   /*!< 0x00000007 */
#define TIM_CCMR2_OC3M_Pos        (4U)                                         
#define TIM_CCMR2_OC3M_Msk        (0x7UL << TIM_CCMR2_OC3M_Pos)                 /*!< 0x00000070 */
#define TIM_CCMR2_OC4M_Pos        (12U)                                       
#define TIM_CCMR2_OC4M_Msk        (0x7UL << TIM_CCMR2_OC4M_Pos)                 /*!< 0x00007000 */

В моей cmsis их не нашлось, надо бы обновить, только не разобрался откуда правильно взять.
И TIM3->PSC = 570; поставить для 48MHz пришлось.
У тебя 950 стоит, с таким значением попадаю только при 80MHz (RCC_CFGR_PLLMUL10) .
STM32F030K6T6.
А, вот ещё, сырой код (stor) без декодирования не получилось принять , поковыряю ещё...

_________________
Паялка. БП паялки 1. БП 2.
Бесперебойник.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Ср дек 14, 2022 20:53:16 
Встал на лапы
Аватар пользователя

Зарегистрирован: Пн апр 02, 2012 15:56:23
Сообщений: 143
Рейтинг сообщения: 0
На правах рекламы, можно сказать, тоже предложу вариант решения (подсмотрено на easyelectronics)
Спойлер
Код:
/**
 * @brief Class for IR receiver
 *
 * @tparam _Timer GP timer instance
 * @tparam _Pin Input pin
 * @tparam _Decoder Decoder
 */
template <typename _Timer, typename _Pin, typename _Decoder>
class IrReceiver
{
    using InputCaptureFalling = typename _Timer::InputCapture<0>;
    using InputCaptureRising = typename _Timer::InputCapture<1>;
    using TimeoutOCChannel = typename _Timer::OutputCompare<2>;

public:
    /**
     * @brief Init receiver
     *
     * @par Returns
     *  Nothing
     */
    static void Init()
    {
        _Timer::Enable();
        _Timer::SetPrescaler(_Timer::GetClockFreq() / 1000000 * 2 - 1); // 1us period
        _Timer::SetPeriod(0xffff);

        _Timer::SlaveMode::SelectTrigger(_Timer::SlaveMode::Trigger::FilteredTimerInput1);
        _Timer::SlaveMode::EnableSlaveMode(_Timer::SlaveMode::Mode::ResetMode);

        InputCaptureFalling::SetCapturePolarity(InputCaptureFalling::CapturePolarity::FallingEdge);
        InputCaptureFalling::SetCaptureMode(InputCaptureFalling::CaptureMode::Direct);
        InputCaptureFalling::EnableInterrupt();
        InputCaptureFalling::Enable();

        InputCaptureRising::SetCapturePolarity(InputCaptureRising::CapturePolarity::RisingEdge);
        InputCaptureRising::SetCaptureMode(InputCaptureRising::CaptureMode::Indirect);
        InputCaptureRising::EnableInterrupt();
        InputCaptureRising::Enable();

        TimeoutOCChannel::SetPulse(15'000);

        _Pin::Port::Enable();
        _Pin::template SetConfiguration<_Pin::Configuration::In>();
        _Pin::template SetPullMode<_Pin::PullMode::PullUp>();

        _Timer::Start();
    }

    /**
     * @brief Timer IRQ handler (call this method in TIMx_IRQHandler)
     *
     * @par Returns
     *  Nothing
     */
    static void IRQHandler()
    {
        static bool idleState = true;

        if(InputCaptureFalling::IsInterrupt()) {
            InputCaptureFalling::ClearInterruptFlag();

            uint16_t width = InputCaptureFalling::GetValue();
            uint16_t pulse = InputCaptureRising::GetValue();

            if(idleState) {
                idleState = false;
                TimeoutOCChannel::EnableInterrupt();
            }
            else {
                if(IsSimilar<_Decoder::StartWidth>(width) && IsSimilar<_Decoder::StartPulse>(pulse)) {
                    _Decoder::Start();
                }
                else if(IsSimilar<_Decoder::Width0>(width) && IsSimilar<_Decoder::Pulse0>(pulse)) {
                    _Decoder::Add0();
                }
                else if(IsSimilar<_Decoder::Width1>(width) && IsSimilar<_Decoder::Pulse1>(pulse)) {
                    _Decoder::Add1();
                }
                else {
                    idleState = true;
                }
            }
        }

        if (TimeoutOCChannel::IsInterrupt()) {
            TimeoutOCChannel::DisableInterrupt();
            TimeoutOCChannel::ClearInterruptFlag();

            if(!idleState) {
                idleState = true;
                _Decoder::Handle();
            }
        }
    }
private:
    /**
     * @brief Compare received value with decoder constant with given accuracy
     *
     * @tparam _TargetValue Constant
     * @param value Received value
     *
     * @return true If value ~ _TargetValue
     * @return false If value != _TargetValue
     */
    template<uint16_t _TargetValue>
    inline static bool IsSimilar(uint16_t value)
    {
        return ((_TargetValue * (100 - _Decoder::EpsilonInPercent) / 100) < value) && (value < (_TargetValue * (100 + _Decoder::EpsilonInPercent) / 100));
    }
};

/**
 * @brief NEC decoder
 */
class NecDecoder
{
public:
    static const uint16_t StartWidth = 13500;
    static const uint16_t StartPulse = 9000;

    static const uint16_t Width0 = 1125;
    static const uint16_t Pulse0 = 562;

    static const uint16_t Width1 = 2250;
    static const uint16_t Pulse1 = 562;

    static const uint16_t EpsilonInPercent = 20;

    /// Command
    /// @todo Add commands
    enum Command : uint16_t
    {
        NoCommand = 0
    };

    using Callback = std::add_pointer_t<void(Command command)>;

    /**
     * @brief Set the callback for command receive
     *
     * @param callback Callback
     *
     * @par Returns
     *  Nothing
     */
    static void SetCallback(Callback callback)
    {
        _callback = callback;
    }

    /**
     * @brief Start new frame
     *
     * @par Returns
     *  Nothing
     */
    static void Start()
    {
        _frame = 0;
    }

    /**
     * @brief Add bit 0 to frame
     *
     * @par Returns
     *  Nothing
     */
    static void Add0()
    {
        _frame >>= 1;
    }

    /**
     * @brief Add bit 1 to frame
     *
     * @par Returns
     *  Nothing
     */
    static void Add1()
    {
        _frame = (_frame >> 1) | 0x80000000;
    }

    /**
     * @brief End of frame (pause detect) handler
     *
     * @par Returns
     *  Nothing
     */
    static void Handle()
    {
        if ((_frame & 0xff000000) != ( (~(_frame) & 0x00ff0000) << 8)) {
            return;
        }

        if ((_frame & 0xff00) != (((~_frame) & 0x00ff) << 8)) {
            return;
        }

        uint16_t command = ((_frame & 0xff000000) >> 16) | ((_frame & 0xff00) >> 8);
       
        if(_callback)
            _callback(static_cast<Command>(command));
    }

private:
    static uint32_t _frame;
    static Callback _callback;
};

uint32_t NecDecoder::_frame;
NecDecoder::Callback NecDecoder::_callback;


Использовать максимально просто, вот пример:
Спойлер
Код:
#include <clock.h>
#include <iopins.h>
#include <timer.h>
#include <drivers/ir.h>

using namespace Zhele;
using namespace Zhele::Drivers;
using namespace Zhele::IO;
using namespace Zhele::Timers;
using namespace Zhele::Clock;

void ConfigureClock();
void ConfigureOutputPwm();
void ConfigureInputCapture();

using Receiver = IrReceiver<Timer4, Pb6, NecDecoder>;

int main()
{   
    ConfigureClock();

    Receiver::Init();
    NecDecoder::SetCallback([](NecDecoder::Command command) {
        // Do smth
    });

    for (;;)
    {
    }
}

void ConfigureClock()
{
    PllClock::SelectClockSource(PllClock::ClockSource::External);
    PllClock::SetMultiplier(9);
    Apb1Clock::SetPrescaler(Apb1Clock::Div2);
    SysClock::SelectClockSource(SysClock::Pll);
}

extern "C"
{
    void TIM4_IRQHandler()
    {
        Receiver::IRQHandler();
    }
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Чт дек 15, 2022 01:02:21 
Прорезались зубы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 12
Зарегистрирован: Сб янв 09, 2016 15:51:17
Сообщений: 200
Рейтинг сообщения: 0
Дефайны только дёрнул, не знаю можно так?

Раньше-бы посоветовал дёрнуть из кубика от st, но сейчас всё свежее приходится искать на гитхабе.
https://github.com/STMicroelectronics/c ... er/Include

_________________
sRtoS


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Сб янв 21, 2023 22:04:22 
Сверлит текстолит когтями
Аватар пользователя

Карма: 11
Рейтинг сообщений: 157
Зарегистрирован: Вт окт 23, 2007 10:01:42
Сообщений: 1274
Откуда: Волгоград
Рейтинг сообщения: 0
А можно ли перекинуть на другой таймер?
Попробовал в лоб изменить на 14 или 16 ... не вышло.
Инит:
Код:
del

Обработчик:
Код:
del

_________________
Паялка. БП паялки 1. БП 2.
Бесперебойник.


Последний раз редактировалось zenon Вс янв 22, 2023 09:49:04, всего редактировалось 1 раз.

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Сб янв 21, 2023 22:20:53 
Встал на лапы
Аватар пользователя

Зарегистрирован: Пн апр 02, 2012 15:56:23
Сообщений: 143
Рейтинг сообщения: 0
Если контроллер F100RB, то у таймера 16 всего 1 канал (у 15 их два, если что), так что эта реализация неприменима.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Сб янв 21, 2023 22:31:07 
Сверлит текстолит когтями
Аватар пользователя

Карма: 11
Рейтинг сообщений: 157
Зарегистрирован: Вт окт 23, 2007 10:01:42
Сообщений: 1274
Откуда: Волгоград
Рейтинг сообщения: 0
Хм. У меня F030K6T6, о 32-х ногах, те, если я правильно понял на PA2 можно повесить?
фиг там, нет у меня 15-го

_________________
Паялка. БП паялки 1. БП 2.
Бесперебойник.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Вс янв 22, 2023 01:22:41 
Прорезались зубы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 12
Зарегистрирован: Сб янв 09, 2016 15:51:17
Сообщений: 200
Рейтинг сообщения: 0
А можно ли перекинуть на другой таймер?

При работе с st чипами необходимо иметь STM32Cube, скачивать любым доступным способом. Это приложение необходимо для наглядного выбора периферии, и ротации ног. Что-бы не гадать на чайной гуще, и не курить тонны документации в поиске доступного варианта решения.
Таймер должен уметь работать в режиме "PWM input", и иметь контакт на ногу чипа.

_________________
sRtoS


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Вс янв 22, 2023 04:00:44 
Поставщик валерьянки для Кота

Карма: 20
Рейтинг сообщений: 253
Зарегистрирован: Вс июн 19, 2016 09:32:03
Сообщений: 2090
Рейтинг сообщения: 0
Таймер должен уметь работать в режиме "PWM input", и иметь контакт на ногу чипа.

У меня все ограничения в либах прописаны, по старинке обхожуcь без кубов :)
Спойлер
Код:
template<TimCh Channel>
class Remote
{
   using Tim = Channel::Timer;
   static constexpr uint32_t chNum = Channel::number();
   static_assert(chNum <= 3);
   static_assert(Tim::hasFeatures(TimFeature::SlaveCtrl), "TimFeature::SlaveCtrl is Required!");
   static_assert(chNum == 1 || Tim::hasFeatures(TimFeature::Xor), "TimFeature::Xor is Required!");
   .........
};

Remote<Tim3Ch2<PA7>> remote;

Скомпилируется только если подставить подходящий таймер, канал и пин.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 библиотека работы с ИК пультом (NEC)
СообщениеДобавлено: Вс янв 22, 2023 09:58:40 
Сверлит текстолит когтями
Аватар пользователя

Карма: 11
Рейтинг сообщений: 157
Зарегистрирован: Вт окт 23, 2007 10:01:42
Сообщений: 1274
Откуда: Волгоград
Рейтинг сообщения: 0
AVI-crak, да ну его этот куб, у меня от него зуд... лучше покопашусь по-своему, задач каких-то у меня нет, так потихоньку то с одним, то с другим разобраться...
Ноги поменять глянув в даташит вообще труда не составляет.
В общем на TIM1 перекинул, теперь TIM3 освободился для энкодера.
TIM14 вроде умеет PWM Input, но на него не перекинуть.
Спойлер
Код:
void ik_tim_init(void) { 
    RCC->APB2ENR  |= RCC_APB2ENR_TIM1EN; // 1-й таймер
    //  TIM1_CH1 PA8 AF2
    RCC->AHBENR   |= RCC_AHBENR_GPIOAEN;
    GPIOA->MODER  |= _VAL2FLD(GPIO_MODER_MODER8, 2); // Ногу в альтернативную функцию
    GPIOA->AFR[1] |= _VAL2FLD(GPIO_AFRH_AFSEL8, 2);  //
    TIM1->PSC = 480;//340;//950;//400; //950; /// clock frequency of the timer / 50526 (509us = 51L)  // TIM prescaler register

    TIM1->CCMR1 = _VAL2FLD(TIM_CCMR1_CC1S, 1)|
                  _VAL2FLD(TIM_CCMR1_CC2S, 2);
    TIM1->CCER  = _VAL2FLD(TIM_CCER_CC1P, 1)|
                  _VAL2FLD(TIM_CCER_CC2P, 0)|
                  _VAL2FLD(TIM_CCER_CC1E, 1)|
                  _VAL2FLD(TIM_CCER_CC2E, 1);
    TIM1->SMCR  = _VAL2FLD(TIM_SMCR_TS, 5)| // Filtered Timer Input 1 (TI1FP1)
                  _VAL2FLD(TIM_SMCR_SMS, 4); // Reset Mode (TRGI)
    TIM1->CCMR2 = _VAL2FLD(TIM_CCMR2_OC3M,6)|
                  _VAL2FLD(TIM_CCMR2_OC4M,6);
    TIM1->CCR3 = 949;  //949; // 1357 start P
    TIM1->CCR4 = 1764;
    TIM1->DIER = TIM_DIER_CC1IE;
    TIM1->CR1 |= TIM_CR1_CEN;
    NVIC_EnableIRQ(TIM1_CC_IRQn);
}

Код:
void TIM1_CC_IRQHandler(void) { //
  uint32_t tmp;
  static uint8_t status = 0;
  static uint8_t poz;
  static uint32_t stor;
  if ((TIM1->SR & (TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF | TIM_SR_CC4IF))
       != (TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF)) goto uno;
  tmp = TIM1->CCR2;
  if (tmp < range_z[status << 1]) goto uno;
  if (tmp > range_z[(status << 1) + 1]) goto uno;
  switch (status) {
    case 0: status = 1; poz = 32; stor = 0; tmp = 10; break;
    case 1: tmp = stor << 1;
            if (TIM1->CCR1 > 170) tmp |= 1;
            stor = tmp; poz--; tmp = 12;
            if (poz == 0) {
              /// watch raw IR code
              /// stor = (~IK_N<<24)|(IK_N<<16)|(~ik_out<<8)|(ik_out)
              //if ((DECODER == (stor >> 16)) && ((((stor >> 8) ^ stor) & 0xFF) == 0xFF)) {
                stor &= 0xFF; ik_out = stor; tmp = 14; status = 2;
              //} else goto uno;
            }; break;
    case 2: status = 3; tmp = 16; break;
    case 3: status = 2; tmp = 18; ik_out = stor; break;
    default: uno: status = 0; tmp = 20; break;
    };
    TIM1->SR = 0;
    TIM1->CCR3 = range_z[tmp++];
    TIM1->CCR4 = range_z[tmp];
}


Reflector писал(а):
Скомпилируется только если подставить подходящий таймер, канал и пин.

Для TIM14 и TIM16 у меня компилируется норм, даже не ругается не на что, но не заводится... наверное всё-так потому что одноканальные, как сказали выше, только не понял зачем два канала?

_________________
Паялка. БП паялки 1. БП 2.
Бесперебойник.


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 38 ]  1,  

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: kvn234 и гости: 6


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y