Налаштування uart avr, mainloop

UART - це Universal Asynchronius Receiver Transmitter, універсальний асинхронний приймач-передавач. Але якщо говорити простіше, це звичайний послідовний порт (він же COM-порт, він же RS-232), які раніше часто використовувалися в персональних комп'ютерах для підключення миші, модему і інших периферійних пристроїв. З повсюдним поширенням USB послідовний порт втратив свою популярність, але в мікроконтролерах він все ще досить часто використовується, так як це один з найпростіших способів зв'язати два пристрої. За допомогою uart до мікроконтролеру можна підключити GSM модем, GPS приймач, або інший мікроконтролер. Залежно від використовуваних перетворювачів рівня можна отримати rs232 або rs485. Так само існують конвертери rs232-USB, rs232-ethernet, rs232-bluetooth які дозволяють підключити пристрій на мікроконтролері з rs232 використовуючи більш сучасні інтерфейси.

В UART використовуються дві лінії (виведення мікроконтролера): rx - для прийому і tx - для передачі. У USART додана додаткова лінія clk для синхронізації приймача і передавача, що дозволяє збільшити швидкість обміну.

Дані по uart передаються в наступному форматі:

Старт-біт - служить для визначення початку посилки
Біти даних - може бути від 5 до 9 біт, але найбільш часто використовується 8 біт - один байт.
Біт контролю парності - дозволяє перевірити чи не відбулося при передачі збій.
Стоп біти - 1 або 2 біта, служать для визначення закінчення посилки.

Для uart в avr atmega налаштовується кілька параметрів:

  1. швидкість обміну
  2. кількість біт даних
  3. контроль парності
  4. кількість стоп-біт

Розглянемо налаштування uart / usart для avr atmega8.

Налаштування швидкості обміну по uart в avr

Щоб встановити інтервал між використовується регістр UBRR (Usart Boud Rate Register)

Для установки швидкості в цей регістр треба записати значення розраховане за формулою:

  • F - тактова частота, на якій працює мікроконтролер avr, наприклад 11059200 для кварцу 11.0592 МГц
  • B - необхідна швидкість, наприклад 115200 (біт / с)

Приклад розрахунку для кварцу 11.0592 МГц і швидкості 115200 біт / с:

Отриманий результат записуємо в UBRR, тому що цей регістр 16-бітний то доступ організований через два 8-ми бітних регістра

UBRRH = 0; // старший байт UBRRL = 5; // молодший байт

Якщо в результаті обчислення UBRR виходило не ціле число, то в регістр записується округлене значення, частота обміну при цьому буде відрізнятися від тієї, що була задана при розрахунку. Розбіжність в частоті може призводити до збоїв при обміні даними, з цього треба вибирати такий кварц, при якому для заданої швидкості обміну UBRR буде цілим числом.

Також в регістрі UCSRA є біт U2X, що дозволяє подвоїти швидкість обміну. У разі коли цей біт виставлений, для розрахунку значення UBBR використовується наступна формула:

Налаштовуємо кількість біт даних для uart в avr

Залежність кількості біт даних від стану біт UCSZx регістра UCSRC для uart / usart в atmega8

Дякую за статтю. Все гранично зрозуміло.
Спочатку написав свою програму, видає нісенітницю.
Думаю можливо я Криворук, забив вашу ... Теж не зрозумілі символи.
Річ ясна швидкість обміну не збігається. Природно я перещітал спираючись на свою МЕГУ. Варто кварц на 5МГц, але фьюз стоять за замовчуванням, значить мега працює від внутрішнього генератора з частотою 1 МГц.
значить (1000 000 / (9600 * 16)) -1 = 5,5 брав 5 і 6 для UBRRL / Жодне не підходить. Схема справна, так як вже забивав прогу для UART, працювала норм. У коді розрахунок UBRRL був «автоматичний» під 9600, а що замість частоти МК там бралося не розібрався, прогу знайти не можу ...
Підкажіть в чому справа може бути? (Може бути частота МК все ж НЕ 1МГц. Можноли както з'ясувати?)

Артем Двинин каже:

foton6, який у вас мікроконтролер?
Що б перевірити частоту можна через заданий проміжок часу змінювати стан якогось висновку і осцилографом подивитися. Ну або в крайньому випадку светодиодом блимати раз в секунду і подивитися скільки разів він блимне за хвилину.

Артем Двинин каже:

Доброго времени суток, Vital.
Ви все правильно зрозуміли, при обміні по мережі є один майстер і кілька ведених.
Тактова частота у них може бути різна, але частота обміну повинна бути однакова, при цьому якщо використовується внутрішній RC генератор, то його краще відкалібрувати, що б було менше помилок.

При цьому зазвичай використовується RS485. Додатковою синхронізації немає. Збої і втрати відслідковуються за допомогою таймаутів (timeout) і контрольної суми.

Можна взяти за основу modbus.

Якщо є ще питання - пишіть, постараюся відповісти.

P / S Якщо не секрет, що за мережу з пристроїв?

Так все прозаїчніше Артем, поки всі пристрої у мене в голові) не було не жодної практики роботи в живу лише читання і фантазії, тому стільки питань. Що стосується протоколу в голові теж є уявлення так як сам програміст чистої води різні структури даних складні алгоритми це для мене легко, працював з мережами впритул і свої протоколи використовував і чужі слухав) а ось досвіду з схемотехнікою не було, і варто було задуматися на рівні пристрою і з огляду на практику з дискретизацією задумався про те як же залізяка працює то, в голові логіка начебто працює і без всяких читань але дуже хочеться побачити якісь готові проекти зі схемами різних устрій і кодами кодів, може є такий і цом який послужив би мені хорошим матеріалом?) спасибо

як тільки пізнаю майстерність хоч по мінімуму почну практику, і обов'язково поділюся усіма маячними ідеями) насправді питання різних багато і з різних тематик, якщо цікаво передати навички або допомогти знайти рішення можу мучити питаннями)

Артем Двинин каже:

Поясніть будь ласка рядок
uart_puts ( «Hello uart \ r \ n"); я принципі розумію що ми тут відправляємо значення Hello uart і переносимо курсор на наступний рядок. Тут знову ж умова if ((c == '\ n') || (c == '\ r')) підкажіть чому \ n і чому \ r є ще такі позначення. і як правильно прийняти рядок з С #

Артем Двинин каже:

Сергій,
ви маєте рацію, uart_puts ( «Hello uart \ r \ n") передає у UART рядок «Hello uart» а потім символ перекладу Коретко '\ r' і символ перекладу рядка '\ n'.
Якщо приймати цей рядок в терміналі, то при прийомі символу '\ r' поточна позиція переміститься на початок рядка, а при прийомі символу '\ n' перейдемо на новий рядок.
Крім цих символів ще часто використовуються '\ t' - символ табуляції, '\ 0' - нульовий символ (кінець рядка).

При введенні рядка з терміналу введення закінчується натисканням на ENTER, і в залежності від налаштувань терміналу він відправляє або '\ r \ n' або '\ n \ r' або '\ n'. За цією ознакою і закінчуємо приймати рядок і переходимо до її обробці.

Я не фахівець з C # але можу підказати що в середовищі Net2.0 для роботи з COM портом можна використовувати клас SerialPort і для читання рядка викликати метод ReadLine.

// Вимірювання постійного струму за допомогою AVR #include #include #include unsigned int voltage, current, adc_counter; volatile unsigned long voltage_value, current_value; // Функції роботи з LCD #define RS PD0 #define EN PD2 // Функція передачі команди void lcd_com (unsigned char p)

(1 lt; lt; RS); // RS = 0 (запис команд) PORTD | = (1 lt; lt; EN); // EN = 1 (початок запису команди в LCD) PORTD - = 0x0F; PORTD | = (p - 0xF0); // старший Нібл _delay_us (100); PORTD - =

(1 lt; lt; EN); // EN = 0 (кінець запису команди в LCD) _delay_us (100); PORTD | = (1 lt; lt; EN); // EN = 1 (початок запису команди в LCD) PORTD - = 0x0F; PORTD | = (p lt; lt; 4); // молодший Нібл _delay_us (100); PORTD - =

(1 lt; lt; EN); // EN = 0 (кінець запису команди в LCD) _delay_us (100);> // Функція передачі даних void lcd_data (unsigned char p)

(1 lt; lt; EN); // EN = 0 (кінець запису команди в LCD) _delay_us (100); PORTD | = (1 lt; lt; EN); // EN = 1 (початок запису команди в LCD) PORTD - = 0x0F; PORTD | = (p lt; lt; 4); // молодший Нібл _delay_us (100); PORTD - =

(1 lt; lt; EN); // EN = 0 (кінець запису команди в LCD) _delay_us (100);> // Функція виведення рядка на LCD void lcd_string (unsigned char command, char * string)

© Copyright 2016 - 2024 | Всі права захищен


Privacy Policy