* ПНЯ — Периферия Независимая от Ядра в микроконтроллерах Microchip, известная так же как CIP — Core Independent Peripheral.
Часть 4
Предыдущие статьи [1], [2] и [3] были посвящены Периферии Независимой от Ядра (ПНЯ) микроконтроллеров Microchip: конфигурируемым логическим ячейкам, портам ввода/вывода с функцией ограничения тока и АЦП с вычислителем, были показаны некоторые возможности такой периферии. Напомню, что независимость подразумевается не от типа ядра PIC микроконтроллеров (BaseLine, Mid-Range, Enhanced Mid-Range, PIC18, 16-, 32-bit), а от работы ядра, т.е. независимое выполнение возложенной на периферию задач от состояния ЦПУ. Такая периферия, а в особенности возможность её конфигурирования на совместную работу и синтез аппаратных функций, призвана разгрузить программную часть, снизить энергопотребление.
В этой небольшой статье хочу показать примеры реализации приема «кастомных», нестандартных интерфейсов связи с помощью Периферии Независимой от Ядра.
Весьма часто встречается ШИМ кодирование информации, когда дискретные сигналы, лог.1 и лог.0, закодированы шириной импульса. Рассмотрим вариант приема и декодирования таких сигналов с помощью Периферии Независимой от Ядра PIC контроллеров.
Декодирование ШИМ сигнала датчика AM2302
В DIY проектах часто применяется датчик температуры и влажности DHT22 (AM2302). Датчик имеет 3 вывода, информация передается по одному проводу. В ответ на запрос (низкий уровень длительностью примерно 1ms), датчик отвечает стартовым битом, а затем последовательностью из 40 бит, где информация закодирована в длительности импульсов: лог. «0» – импульс 30мк сек, лог. «1» – 70мк сек (типовые значения). Ответ от датчика содержит 5 байт: 2 байта данных о влажности, 2 байта – температуры и 1 контрольный байт.
Рис.1. Пояснения к принципу формирования сигнала датчика DHT22.
В сети много примеров работы с такими датчиками на Ардуино. Некоторые реализации библиотек используют конструкции типа:
loopCnt = TIMEOUT;
while(PIN) {
if(--loopCount == 0) return ErrorTimeout;
}
if (loopCnt < cntOne) {
// bit =1
…
} else {
// bit =0
…
}
В подобных реализациях мне видятся следующие проблемы:
— программа на все время измерения (>5мс) «висит» в коде измерения;
— возникновение достаточно длинного прерывания порушит чтение данных с датчика;
— потенциальные проблемы с работой на низкой тактовой частоте микроконтроллера;
Алгоритм программы подобных решений имеет примерно такой вид (см. рис.2)
Рис. 2. Алгоритм программного приема и декодирования сигналов датчика.
Ниже рассматривается вариант аппаратного приема/декодирования протокола с минимальными программными издержками.
Идея заключается в выделении синхроимпульсов из битового потока с последующим направлением исходного сигнала и синхроимпульсов на аппаратный модуль SPI. В этом случае программе микроконтроллера остается лишь забирать последовательно 5 байт данных из SPI.
Частью CIP являются таймера с возможностью запуска по событиям (изменению состояния входа или другой периферии). Т.е. изменение состояния входа может запускать таймер, см. сигнал TMR6 на рис.3. Когда таймер достигает заданного значения, его счет останавливается и таймер находится в состоянии TMR6 = PR6 (PR – регистр периода). Состояние таймера может быть входом для Конфигурируемой Логической Ячейки (CLC, см. часть 1).
Таким образом, с помощью таймера и Логических Ячеек мы можем сформировать сигнал, пригодный для подачи на тактовый вход SCK модуля SPI. Для выделения информации длительность такого клока должна иметь среднее значение между длительностью нуля и единицы. Тогда SPI может фиксировать бит по спаду клока (см. рис.3 сигнал SCK).
Сигнал от датчика будет иметь ложные импульсы, формируемые от запросного и стартового импульсов. Для того чтобы эти импульсы не мешали работе, нужно включать SPI только на время информационных импульсов, или отсечь ненужные импульсы. Эту задачу так же можем решить с помощью CIP.
Другой таймер выступает в роли счетчика импульсов с переключением по спаду: в регистр периода записываем число 2, таймер отсчитывает первые 2 импульса (см. сигнал TMR4 на рис.3) и останавливает счет (см. сигнал EN на рис.3), который через блок логических ячеек разрешает выдачу остальных импульсов на вход SPI.
Рис.3. Диаграммы, поясняющие прием сигнала датчика DHT22.
Логическая функция формирования сигнала SCK реализуется на одной логической ячейке (CLC), полная схема в конфигурации И-ИЛИ приведена на рис.4.
Выход логической ячейки подключается ко входу SCK, а сигнал датчика DHT22 подключается к MOSI модуля SPI. Все соединения выполняются внутри микроконтроллера (рис.5). Для контроля и отладки сигналы можно вывести на порты микроконтроллера.
Рис.4. Конфигурация логической ячейки CLC в PIC микроконтроллере.
Рис. 5. Полная структура конфигурации периферии.
Если кажется, что 2-х таймеров на задачу декодирования протокола датчика является расточительством ресурсов, то счетчик до двух можно «собрать» на свободных логических ячейках CLC.
Итого, задача декодирования сводится к очень простому алгоритму: инициализируется микроконтроллер и его периферия, при необходимости измерений включается модуль SPI и формируется запрос на измерение (лог. «0» в течение ~1мсек).
Остается считать данные из буфера при возникновении прерывания от SPI.
Рис.6. Алгоритм работы с датчиком DHT22 при использовании ПНЯ.
Рис.7. Сигналы с портов микроконтроллера. Сигнал SSP1IF – прерывания по приему байта модулем SPI.
На рис.7 приведена диаграммы сигналов, где:
DHT (dat) – сигнал на сигнальной линии датчика – подаем на вход MOSI модуля SPI;
TMR6 != RP6 – выделенный тактовый сигнал – подаем на SCK модуля SPI;
SSP1IF – сигнал прерываний (готовности данных в буфере SPI) – по сути этот сигнал показывает загрузку ядра микроконтроллера – считывание данных результата.
Декодирование других ШИМ протоколов
Подобные «однопроводные» ШИМ протоколы используются в ИК пультах управления бытовой техникой. Часто при ИК передаче используется кодирование положением импульса, когда длительность постоянная, а пауза переменная. Этот вариант еще называют «Кодирование методом переменной паузы». По сути это то же самое ШИМ кодирование, но с инвертированным сигналом. При наличии логических ячеек сделать инверсию – не проблема, к тому же ИК-приемники и так инвертируют полученный сигнал. На рис. 8 показаны сигналы после приемника, принятые с двух разных пультов.
Рис.8. Варианты кодирования ИК пультов управления.
Оба пульта имеют различные протоколы, но эти протоколы легко декодируются описанным выше способом, единственное, это необходимо обеспечить определение начала посылки для синхронизации включения SPI, так как ИК приемник может ловить помехи.
Рис. 9. Сигналы декодированные с помощью SPI.
Не все ИК пульты имеют ШИМ кодирование. Часть протоколов, например RC5, имеют фазовое кодирование (манчестерский код, «0» передается как 10, а «1» как 01) [4]. Декодирование манчестерского кода с помощью периферии независимой от ядра мы уже рассматривали ранее в первой части [1].
Итоги
Вместо практически 100% загрузки ЦПУ микроконтроллера для задачи декодирования ШИМ протокола в варианте Arduino (да-да, я в курсе, задачу можно решить эффективнее с помощью модулей захвата или другой периферии), мы перенесли прием информационной посылки в аппаратную часть. Фронт входного сигнала запускает таймер, состояние таймера определяет выход блока логических ячеек, выход логической ячейки подается на SPI.
Использование независимой от ядра периферии позволяет оптимизировать использование ресурсов, часть задач перенести на «железо», упростить код, снизить потребление.
Литература
1. Конфигурируемые Логические Ячейки в PIC контроллерах.
2. 50 оттенков ПНЯ. Порты ввода/вывода
3. 50 оттенков ПНЯ. АЦП и АЦП с вычислителем микроконтроллеров Microchip
4. sbprojects.com/knowledge/ir/rc5.php
Комментарии (7)
VDG
17.02.2017 18:57Это не ШИМ. Длительность нуля 80 мкс, единицы — 120 мкс.
ariz0na
17.02.2017 19:09Информация в Ширине импульса. Да, при этом меняется период. Если вместе с шириной импульса будет меняться пауза, т.е. период будет постоянным — не существенно для предложенного метода, работать будет точно так же.
VDG
18.02.2017 01:24+1Дело не в том, что будет работать точно так же. Я вас поправил только в терминологии. ШИМ — это модуляция, а не кодирование. У ШИМа изменяется только скважность. Если изменяется период, то это уже не ШИМ. Ну и все десятки систем с двухуровневым кодированием так или иначе работают с шириной импульса, никто их всех ШИМом не зовёт ).
Широтно-импульсная модуляция (ШИМ, англ. pulse-width modulation (PWM)) — процесс управления мощностью, подводимой к нагрузке, путём изменения скважности импульсов, при постоянной частоте.
Система кодирования вашего датчика мне известна, она повально встречается в пультах в разных вариациях, — это RC5.
Сначала всегда передаётся «1» модулированным сигналом, затем «0» — пауза. Временной размер единицы всегда одинаковый, а временной размер 0 — это кодированные передаваемые данные. Длинная пауза — передача единицы, короткая пауза — передача нуля. Отличие от стандарта у вашего датчика в том, что сигнал инвертирован, видимо на выходе стоит схема ОЭ.ariz0na
19.02.2017 16:34-1Наверное, мы из разных вселенных. Мой мир целиком не описывается «википедией» и не такой однозначный. Вот несколько примеров «моего мира»:
ШИМ (Широтно-Импульсная Модуляция) используется не только для управления мощностью, но и для передачи информации, для генерирования звуковых сигналов (в т.ч. полифонических), для управления сервоприводом (сервомашинки радиоуправляемых моделей) и др.
В моем мире существует ШИМ с постоянной и переменной частотой: Constant Frequency PWM (CF PWM) и Variable Frequency PWM (VF PWM).
Да и в вашем мире ШИМ с фиксированной частотой имеет «аномалии» в терминологии (какая частота у ШИМ при скважности 0 или 100%? ;-)
Касательно VF PWM. Он в свою очередь бывает Constant (Fixed) On-time PWM и Constant (Fixed) Off-time PWM, причем не просто «бывает», но и вполне себе используются в импульсных источниках питания, корректорах коэффициента мощности. Больше того, такие полупроводниковые компании как ON Semiconductor, Texas Instruments, Analog Devices, ST Microelectronics и наверное другие, используют Constant On (Off) -time PWM в интегральных микросхемах. Не берусь спорить о терминах, но уважаю вышеупомянутые компании, в даташитах которых встречаются упоминания о «Constant Off Time PWM», «Constant On Time PWM».
Не совсем понял причину упоминания Вами протокола RC5 применительно к «моему датчику» (почему моему??). Если имеется в виду протокол RC-5 в контексте ИК пультов, то не совсем понимаю в чем меня убеждаете/поправляете. В «моей вселенной» RC-5 кодируется манчестером (фазовое кодирование), а вовсе не ШИМ (впрочем в статье об этом написано и даже дана ссылка на описание RC5).
SadAngel
19.02.2017 15:39В Cypress PSoC также есть возможность работать с независимой от ядра переферией.При желании можно написать свой hardware на verilog
AMN848
У Вас на рисунке 2 зацикливание блок схемы =)
ariz0na
спасибо, поправил ))