1 Востаннє редагувалося MCS-51 (25.02.2021 17:59:44)

Тема: Програмування мікроконтролерів 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.
Код функцій у прикріпленому ахіві. Гітхаб після виправлення Ваших зауважень:) Приклад використання:

Прихований текст
// ініціалізація
if (sam4s_uart_init(UART_0,UART_RECEIVE_AND_TRANSMIT,57600) != DT_STATUS_OK){
    return -1;
}

// десь у основному циклі/потоці/тасці вертаємо назад усе, що прийняли (традиційне echo)
uint16_t receive_len = sam4s_uart_get_avaliable_data(UART_0,uart0_tx_buff);
if (receive_len > 0){
    sam4s_uart_put_data(UART_0,uart0_tx_buff,receive_len);
}
Post's attachments

sam4s_uart_dma.zip 3.34 kb, 24 downloads since 2021-02-25 

Подякували: 0xDADA11C7, Arete2

2

Re: Програмування мікроконтролерів Atmel SAM4S (ARM сумісних)

пиши зараз на гіт! нікому воно не потрібне. або вже існує. тож цнота тут ні до чого.
а якщо не існує і потрібно, отримаєш коміти.
і взагалі, в тебе повинна бути мета. яке корисне використання ти бачиш?
без мети це лише сміття

3

Re: Програмування мікроконтролерів Atmel SAM4S (ARM сумісних)

MCS-51 написав:

Код функцій у прикріпленому ахіві. Гітхаб після виправлення Ваших зауважень:)

  • У файлах sam4s_uart_lib.* є таби і пробіли. В sam4s_uart_lib.h це не критично, а в sam4s_uart_lib.c так не можна.

  • У файлі sam4s_uart_lib.c зпочатку давайте include'и стандартних бібліотек, потім своїх. (крім файлів налаштувань, або прекомпільованих заголовків)

  • У sam4s_uart_lib.h такі коментарі

    /* Define to prevent recursive inclusion -------------------------------------*/
    /* Includes ------------------------------------------------------------------*/
    /* Macros --------------------------------------------------------------------*/
    /* Types ---------------------------------------------------------------------*/
    /* Extern variables ----------------------------------------------------------*/
    /* Functions -----------------------------------------------------------------*/

    краще відділяти від коду (після них) додатковим <Enter>, щоб IDE не інтерпретував це як опис для { функції | структури }.

  • Опис { функції | структури } має бути безпосередньо над { функцією | структурою }, не після неї.

На приклад (з вашого коду):

Не

/* Functions -----------------------------------------------------------------*/
dt_status_t sam4s_uart_init(uart_num_t uart_num, uart_mode_t uart_mode, uint16_t uart_baudrate);  // max baudrate for 18432 kHz = 57600

А

/* Functions -----------------------------------------------------------------*/

// max baudrate for 18432 kHz = 57600
dt_status_t sam4s_uart_init(uart_num_t uart_num, uart_mode_t uart_mode, uint16_t uart_baudrate);
Подякували: tchort, MCS-512

4

Re: Програмування мікроконтролерів Atmel SAM4S (ARM сумісних)

leofun01 написав:

...так не можна...

Дуже вдячний за конструктивну критику.