DShot receiver on STM32
Приймання сигналу DShot 150/300/600 з використання DMA. Приклад для STM32.
Якщо в мікроконтролері є DMA, який можна використати, його обов'язково треба використати, навіть, коли здається, що в конкретному випадку можна обійтися без DMA. Використання DMA звільнює ядро мікроконтролера від рутинних операцій.
Що таке DShot?
DShot - це простий протокол передачі цифрової інформації по одному дроту. Використовується для керування ESC. Передача інформації пакетна. Тобто передається певна кількість біт, після чого витримується пауза, яка розділяє пакети. Детекція бітів, нуль або один, відбувається за шириною імпульсів. Якщо імпульс коротший за певне значення - це "0", якщо довший за певне значення - то це "1".
Приблизний вигляд протоколу DShot:
Як видно передаються 16 біт.
Протоколи DShot150, DShot300, DShot600 мають однакову структуру і відрізняються лише швидкістю. DShot150 - передає 150 пакетів за секунду, DShot300 - триста, DShot600 - відповідно 600 пакетів за секунду.
Приймання DShot
Нам треба прийняти 16 біт, які передаються по одному входу, а потім обробити їх. Якщо конкретизувати задачу - нам потрібно вимірювати довжину кожного з 16 імпульсів і вирішувати це 0 чи 1. По завершенню приймання 16 біт, обробити весь пакет - перевірити контрольну суму, витягти дані тощо.
1. Рішення #1. Таймер + переривання
Найпростіше, але не найкраще рішення - використовувати для вимірювання ширини імпульсів звичайний таймер, а показання його знімати по перериванню від входу GPIO. Коли переривання спрацьовує при наростанні сигналу запам'ятовувати показник лічильника таймера, коли переривання спрацьовує на спад сигналу запам'ятовувати показник лічильника таймера, вираховувати різницю між запам'ятованими показниками таймера і якщо різниця менша за порогове - це був 0, якщо більша, тоді це 1.
Та у цьому підході є одна вада - це переривання. На справді переривання не виконуються негайно. Спочатку виставляється прапорець переривання, який означає, що трапилась певна подія, яку треба обробити. І коли мікроконтролер перевірить цей прапорець, тоді він почне підготовку до обробки переривання. Коли мікроконтролер обробляє більш пріоритетне переривання, він не буде перериватися на обробку вашого переривання, а завершить поточне, а потім перейде до наступного. Сам перехід до обробки переривання теж потребує "підготовки". Мікроконтролер запам'ятає те місце, на якому його перервали, збереже всю необхідну інформацію, яка потрібна буде при поверненні до виконання поточної задачі. Весь цей час таймер продовжує працювати, тому похибка вимірювань неминуча. Коли сигнал достатньо розтягнутий у часі - це не критично. В нашому випадку довжина імпульсів така мала, що може статися так, що наступне переривання відбудеться ще до того, як контролер встигне обробити поточне переривання. З таким підходом реально обробити хіба що DShot150. При роботі зі швидшими протоколами будуть виникати проблеми.
2. Рішення #2. Захоплення сигналу таймером + переривання
Трохи ліпше ситуація при використанні таймера у режимі захоплення сигналу. Коли таймер сам вимірює довжину сигналу. Нам залишається лише скопіювати значення у буфер кожного разу коли завершився імпульс. Це теж доводиться робити по перериванню таймера, пов'язаному з захопленням сигналу. Це краще ніж перший варіант, але не достатньо швидко через занадто коротку тривалість імпульсів DShot, яка вимірюється десятками імпульсів тактування мікроконтролера. Мікроконтролер так само не встигає обробляти переривання і трапляються пропуски бітів, які ведуть до втрати цілого пакета.
3. Рішення #3. Захоплення сигналу таймером + DMA
Найефективнішим рішенням є використання режиму захоплення таймером + відправляти результати у масив за допомогою DMA. А переривання від DMA обробляти, коли буде прийнято всі 16 біт. Часу між пакетами достатньо, щоб обробити прийняті дані.
Таким чином всі 16 біт будуть залітати у масив і при цьому мікроконтролер не буде відволікатися на ці операції. А після приймання всіх 16 біт виникне переривання від DMA і можна спокійно обробляти прийняті дані.
В прикладі реалізовано захоплення DShot150, DShot300, DShot600. Можливе автоматичне визначення швидкості протоколу DShot. Також в прикладі реалізовано захоплення PWM сигналу.
Завантажити приклад для STM32F030 можна тут: https://git.avislab.com/andre/STM32G030_Dshot
використання HAL - це дань моді? Якось StdPeriph звичніше....
З HAL дещо простіше перетаскувати проєкти на інші серії мікроконтролерів. Це, мабуть, єдина причина, чому я зі скрипом перейшов на HAL.
Недавні записи
- DShot receiver on STM32
- CRSF to PWM
- U-FOC PC Monitor для Chrome browser
- Фільтрація Back-EMF. Безсенсорні BLDC мотори
- Text to speech. Українська мова
- LCD Display ST7567S (IIC)
- Розпізнавання мови (Speech recognition)
- Selenium
- Комп'ютерний зір (Computer Vision)
- Деякі думки про точність вимірювань в електроприводі
Tags
bldc timer eeprom dht11 soldering stm32 html meteo avr rtc battery hih-4000 foc gps sensors dma mpu-6050 flask nodemcu st-link docker git esp8266 tim bkp eb-500 motor mongodb ssd1306 bluetooth pwm adc sms smd brushless css java-script pmsm rfid displays mpx4115a atmega barometer remap capture servo led web programmator uart 3d-printer encoder examples gpio books websocket wifi i2c watchdog solar usart piezo ngnix ssd1331 options nvic raspberry-pi bme280 usb lcd flash max1674 exti python mpu-9250 dc-dc ethernet bmp280 rs-232
Архіви