Тема: Програмування мікроконтролерів Atmel SAM4S (ARM сумісних)
Доброго часу доби.
Потрошки рухаюсь у напрямку освоюванню мови С та освоювання більш складних 32-бітних мікроконтролерів.
Працюю із популярними нині STM32, але й інших ARM-сумісних не цураюся.
Періодично купую на всіляких барахолках якісь уживані елекронні пристрої із мікроконтролерами усередині, і пишу до них свої Board Support Package.
Нещодавно придбав логер теператури. На платі окрім мікроконтролера Atmel SAM4S розміщені: контролер рідкокристалічного дисплею у корпусі "крапля", EEPROM та SPI Flash пам'ять.
Написав уже бібліотеки для роботи з EEPROM та SPI Flash пам'яттю, але вони без використання переривань та DMA, тому не варті уваги (легко гуглиться купа схожих готових реалізацій).
А от з UART вийшло набагато веселіше - я "вперся рогом", і зробив доволі цікаву реалізацію із використанням DMA.
Взагалі коротко про DMA: це така апаратна фіча, яка дозволяє копіювати з пам'яті/у пам'ять дані, роблячи це незалежно від ходу роботи програми, зашитої у пам'ять МК (не займаючи робочий час основного АЛП мікроконтролера).
Власне через DMA я і вирішив освоювати більш складні мікроконтролери, ця фіча мені дуже сподобалась.
З відправкою через DMA взагалі проблем немає - задав вказівник на буфер, вказав кількість байт які хочеш передати, і пішов у своїх справах, периферія все зробить за тебе.
З прийомом усе трохи складніше. Треба знати коли він закінчився.
Згадані вище STM32 мають цікаве переривання - IDLE, яке спрацьовує при закінченні вхідного потоку байт.
Це дозволє організувати дуже гарну схему прийому - налаштовуємо прийом у буфер через DMA, і одне переривання по закінченні прийому.
Як результат матимемо прийом потоку байт периферією без зайвих відволікань, і одне переривання при закінченні прийому.
У SAM4S такого переривання немає, і щоб не робити переривання по прийому кожного байту, довелося трохи викрутитися, і написати функцію, яка перевіряє кількість прийнятих байт, і вертає їх реальну кількість тільки у разі закінчення прийому.
Під закінченням прийому мається на увазі незмінна кількість прийнятих байт при 2 останніх викликах функції.
Тому викликати її необхідно не частіше періоду прийому 1 байта, який прямо залежить від значення baudrate.
Код функцій у прикріпленому ахіві. Гітхаб після виправлення Ваших зауважень:) Приклад використання: