======Работа с инфракрасным портом (IrDA, SIR) на отладочной плате 1986ВЕ1Т======
Для начала разъясним, что такое инфракрасный порт. //InfraRed Data Association — IrDA, ИК‑порт, инфракрасный порт// — группа стандартов, описывающая протоколы физического и логического уровня передачи данных с использованием инфракрасного диапазона световых волн в качестве среды передачи. Является разновидностью оптической линии связи ближнего радиуса действия.
Технология была особо популярна в конце 1990-х начале 2000-х годов. В данное время практически вытеснена более современными аналогами, такими как //WiFi// и //Bluetooth//.
Основные причины отказа от //IrDA// были:
* Усложнение сборки корпусов устройств, в которых монтировалось ИК-прозрачное окно.
* Ограниченная дальность действия и требования прямой видимости пары приёмник-передатчик.
* Относительно низкая скорость передачи данных первых реализаций стандарта. В последующих ревизиях стандарта этот недостаток исправили: скоростные возможности немного превышают, например, возможности самой распространённой на сегодняшний момент версии протокола //Bluetooth// (спецификация 4.0). Однако широкого распространения скоростные варианты //IrDA// получить уже не успели.
//IrDA// спецификации включают в себя:
* Спецификацию физического уровня //IrPHY// (с разновидностями //**SIR**, MIR, FIR, VFIR, UFIR//)
* Протокольные спецификации //IrLAP, IrLMP, IrCOMM, Tiny TP, IrOBEX, IrLAN, IrSimple и IrFM// (находится в разработке).
//IrDA// устройства способны передавать информацию с различной скоростью:
* //**SIR (HPSIR)**// - Serial InfraRed - до скорости 115200 бит/с
* //MIR// - Medium InfraRed - до скорости 1.152 Мбит/с
* //FIR// - Fast InfraRed - до скорости 4 Мбит/с
* //VFIR// - Very Fast InfraRed - до скорости 16 Мбит/с
* //UFIR// - Ultra Fast InfraRed - до скорости 96 Мбит/с
* //Giga-IR// - до скорости 1 Гбит/с
Микроконтроллер **1986ВЕ1Т** имеет на борту в составе контроллера //UART// кодек (//ENDEC – Encoder/Decoder//) последовательного интерфейса инфракрасной (ИК) передачи данных в соответствии с протоколом **//SIR (SIR – Serial InfraRed)//** ассоциации //Infrared Data Association (IrDA)//.
Связь между //UART// и //IrDA// следующая:
**//Serial InfraRed (SIR)//** использует те же скорости передачи данных, что и //RS232 (COM-порт)//, а именно, 9.6 кбит/с, 19.2 кбит/с, 38.4 кбит/с, 57.6 кбит/с, 115.2 кбит/с. Совпадение поддерживаемых скоростей не случайно, и позволяет довольно легко реализовать //COM// //IrDA// адаптеры.
На реальных же изделиях //ИК-порт// выглядит следующим образом:
{{ prog:uart:irda_1.jpg }}
Смартфон изображен не случайно. Раньше с помощью //ИК-порта// передавались данные между телефонами, а сегодня //ИК-порт// не потерял актуальность и используется для управления современной техникой (телевизоры, кондиционеры, проекторы и др.).
Для того, чтобы в полной мере показать работоспособность //ИК-порта// в микроконтроллере **1986ВЕ1Т**, было принято решение взять две отладочных платы с установленным модулем //IrDA//. Организовали обмен, в котором одна плата управляет другой при помощи кнопок: по кнопке //Select// первой отладочной платы зажигаются светодиоды на второй плате, а по кнопке //Back// на второй плате светодиоды гаснут. Если будут нажаты другие кнопки на первой отладочной плате, на второй светодиоды начнут моргать, что фактически указывает в рамках нашего проекта на ошибку.
В самом начале необходимо выставить нужны перемычки на отладочной плате для работы с //IrDA//. Это можно сделать согласно паспорту на плату. Необходимые настройки на примере отладочной платы шестой ревизии:
* выставить две перемычки на разъеме //XP8// в верхнее и среднее положение (**//SIR//**);
* выставить две перемычки на разъеме //XP6// в верхнее и среднее положение (//UART1//);
* убедиться, что перемычка возле //ИК-порта// не стоит (//SHDN SIR//).
**Проект, рассматриваемый в статье, доступен на [[ https://github.com/StartMilandr/Examples/tree/master/IrDA_1986VE1T|GitHub]]**
Посмотрим видеоролик, чтобы увидеть принцип работы проекта и сразу же приступим к его рассмотрению:
{{youtube>BPV0stxrJSU?medium}}
Опустим настройки тактирования, конфигурацию портов для светодиодов, кнопок и //UART// - отметим лишь самое важное:
* В функции //void ClkConfig()// частоте ядра присваивается значение //8 MHz// от //HSE//. Эта же частота идёт на тактирование блока //UART//.
* В функции void //UARTConfig()// скорость //UART// устанавливается в //115200 bit/s//, исходя из делителей и поступающей частоты в //8 MHz// на блок //UART//. Здесь же становится активен **//SIR//**, что настраивается одним из битов в поле //CR// регистра управления //UART//.
* Не забываем разрешить прерывания блока //UART//. В программе это делается в основном теле //main()// после конфигурации //UART// командой //NVIC_EnableIRQ(UART1_IRQn);//. Также обратите внимание, что прерывания в блоке //UART// будут возникать при приёме данных.
Рассмотрим обвязку программы, которая обеспечивает работоспособность, представленную на видеоролике. Сделано всё максимально тривиально.
Для начала разберем вечный цикл //while(1)// из основного тела //main()//:
#define codeON 0xAA
#define codeOFF 0xBB
#define codeERROR 0xEE
...
while(1)
{
if (PORT_ReadInputDataBit(MDR_PORTE, PORT_Pin_9) == Bit_RESET) // Если нажата кнопка Select
{
PORT_SetBits(MDR_PORTD, LED_ALL);
Delay(500000);
PORT_ResetBits(MDR_PORTD, LED_ALL);
MDR_UART1->DR=codeON; // Code on diods. Отправка кода 0xAA по ИК-порту
}
else
{
if (PORT_ReadInputDataBit(MDR_PORTE, PORT_Pin_11) == Bit_RESET) // Если нажата кнопка Back
{
PORT_SetBits(MDR_PORTD, LED_ALL);
Delay(500000);
PORT_ResetBits(MDR_PORTD, LED_ALL);
MDR_UART1->DR=codeOFF; // Code off diods. Отправка кода 0xBB по ИК-порту
}
else
{
if ((PORT_ReadInputDataBit(MDR_PORTE, PORT_Pin_5) == Bit_RESET) // Если нажата кнопка Right или
|| (PORT_ReadInputDataBit(MDR_PORTE, PORT_Pin_8) == Bit_RESET) // если нажата кнопка Up или
|| (PORT_ReadInputDataBit(MDR_PORTE, PORT_Pin_10) == Bit_RESET) // если нажата кнопка Left
|| (PORT_ReadInputDataBit(MDR_PORTE, PORT_Pin_15) == Bit_RESET)) // если нажата кнопка Down
{
PORT_SetBits(MDR_PORTD, LED_ALL);
Delay(500000);
PORT_ResetBits(MDR_PORTD, LED_ALL);
MDR_UART1->DR=codeERROR; // Code off diods. Отправка кода 0xFF по ИК-порту
}
}
}
};
По коду выше видно, что при нажатии любой кнопки будет отправлена какая-то информация по //ИК-порту//. Прерывания же возникают при приёме данных, соответственно, если направить //ИК-порт// одной платы на //ИК-порт// другой и нажать на кнопку, то плата, принимающая сигнал, будет отправлена в обработчик прерываний //UART//, который описан следующим образом:
void UART1_Handler()
{
MDR_UART1->ICR = 0x10; // сбросили прерывание
uint32_t i;
// конструкция switch - case основного управления //
switch (MDR_UART1->DR)
{
case codeON: // если пришел код 0xAA
PORT_SetBits(MDR_PORTD, LED_ALL); // LEDs ON
Delay(50000);
break;
case codeOFF: // если пришел код 0xBB
PORT_ResetBits(MDR_PORTD, LED_ALL); // LEDs OFF
Delay(50000);
break;
default: // если пришел любой другой код, который не зажигает и не гасит светодиоды
for (i=0;i<8; i++)
{
PORT_SetBits(MDR_PORTD, LED_ALL); // Моргание LEDs
Delay(50000);
PORT_ResetBits(MDR_PORTD, LED_ALL);
Delay(50000);
}
break;
}
}
При попытке отправить на //ИК-порт// отладочной платы случайную команду с //ИК-порта// смартфона, микроконтроллер ожидаемо попал в обработчике в //case default//, о чем свидетельствовали моргающие светодиоды. Реализовать взаимодействие смартфона и //ИК-порта// микроконтроллера оказалось невозможно из-за неизвестной скорости инфракрасного датчика в смартфоне.