ИК-пульт на stm32

в 9:26, , рубрики: stm32, программирование микроконтроллеров

ИК-пульт на stm32 - 1

Описание библиотеки для считывания, декодирования и последующей отправки инфракрасных сигналов от различных бытовых пультов, с помощью микроконтроллера stm32. За основу взята билиотека IRremote для ардуино, и адаптирована под stm32.

Библиотека использует один таймер, и для приёма, и для отправки сигнала. Приёмник подключается к любому пину (GPIO_Input), а передатчик к одному из каналов таймера работающего в режиме PWM Generation (ШИМ). В примере используется первый канал таймера №4 — PB6 (передатчик) и пин PB5 (приёмник).

Для приёма сигнала таймер работает в режиме прерывания — каждые 50 мкс проверяет состояние входного пина, а при передаче переключается в режим PWM Generation, посылает сигнал, и снова переходит в режим прерывания.

Настройки находятся в файле IRremote.h

extern TIM_HandleTypeDef htim4;

// настройка таймера для приема - переполнение каждые 50 мкс (в данном случае системная частота 72Мгц)
#define MYPRESCALER 71 // получаем частоту 1МГц
#define MYPERIOD 49    // 50 мкс

// настройка таймера для отправки - указать системную частоту таймера
#define MYSYSCLOCK 72000000

// настройка пина для приёма recive_IR
#define RECIV_PIN (HAL_GPIO_ReadPin(recive_IR_GPIO_Port, recive_IR_Pin))

Если будете настраивать другой таймер, то нужно указать соответствующее имя структуры — htim4, и то же самое проделать в файлах IRremote.с и irSend.с. Я поленился дефайнить всё это хозяйство. При выборе другого таймера в Кубе, нужно указать только канал и внутренний источник тактирования…

ИК-пульт на stm32 - 2

Всё остальное программа настроит сама. Если выбрать другой номер канала, то его тоже нужно переименовать в файле irSend.с.

С остальными настройками думаю всё ясно — исходя из системной частоты (в примере 72МГц) подставляются значения предделителя и переполнения для прерывания каждые 50 мкс. Далее указывается частота и чтение пина.

Ниже есть дефайны, которые определяют задействованные протоколы…

//////////////////////////////////// активированные протоколы ////////////////////////////////////////
#define DECODE_RC5           1 // чтоб отключить декодирование протокола RC5 нужно указать 0
#define SEND_RC5             1 // чтоб отключить отправку сигнала по протоколу RC5 нужно указать 0

#define DECODE_RC6           1
#define SEND_RC6             1
...

Отключение ненужных протоколов уменьшает размер программы. В принципе можно вообще выпилить функции неиспользуемых протоколов и соответствующие файлы (файлы имеют характерные имена).

Программа предельно простая, функция my_decode(&results) декодирует полученный сигнал и выводит код кнопки, тип протокола и длину пакета…

ИК-пульт на stm32 - 3

Других пультов у меня нет.

Для отправки раскодированного сигнала используется функция с соответствующим названием…

sendSAMSUNG(0x707048b7, 32); 
my_enableIRIn();

Функция my_enableIRIn() нужна обязательно, она отключает ШИМ и переводит таймер в режим приёма. Эта же функция используется для инициализации (перед бесконечным циклом). Из-за этой функции не удастся поймать свой собственный сигнал — это можно решить, но смысла в этом не вижу.

Если не удаётся определить тип протокола…

ИК-пульт на stm32 - 4
… то в этом нет ничего страшного, код кнопки в любом случае получен.

Если нужно не только принимать неизвестный сигнал, но и отправлять его, тогда нужно раскомментировать строчки для «вывода данных в сыром виде»…

ИК-пульт на stm32 - 5

… и отправлять прочитанные данные с помощью функции sendRaw()…

uint8_t khz = 38; // частоту указать экспериментальным путём, основные используемые от 36 до 40 кГц
unsigned int raw_signal[] = {1300, 400, 1300, 400, 450, 1200, 1300, 400, 1300, 400, 450, 1200, 500, 1200, 450, 1250, 450, 1200, 500, 1200, 450, 1250, 1300};

sendRaw(raw_signal, sizeof(raw_signal) / sizeof(raw_signal[0]), khz); 
my_enableIRIn(); // переинициализирование приёма (нужна обязательно)

У меня отправка в «сыром виде» работает плохо.

В библиотеке используется счётчик DWT для микросекундных задержек. На сколько я знаю он есть не у всех stm32, и возможно что не везде одинаково настраивается. Если у вашего камня нет DWT, то надо что-то придумать на замену в функции custom_delay_usec(unsigned long us) в конце файла irSend.с, настройка в начале.

Библиотека

Автор: im_stD

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js