Мікроконтролери AVR
Продовжуємо працювати змікроконтролерами AVR і сьогодні, як обіцяв, передаватимемо і прийматимемо дані по інтерфейсу UART з використанням відповіднихпереривань. Теорію ми вже всю обговорили у попередній статті (ось), там же ми писали невеликий приклад передачі даних без переривань. Тому зараз маємо повне право одразу перейти до справи, тобто до написання програми.
Навіть не знаю, яке б придумати завдання. А давайте так – будемо приймати дані по UART, а потім відразу ж висилати їх назад. Якщо все буде правильно реалізовано, то дані, що передаються і приймаються повинні повністю збігатися.
Спочатку, мабуть, наведу повний код програми, а потім все детально обговоримо.
Отже, що ми тут бачимо? 😉
Спочатку підключаємо всі необхідні файли. В даному випадку їх лише два.
Для налаштування UART'у нам знадобиться значення, яке необхідно записати в регістр UBRR0. Нехай швидкість буде у нас 9600 кБ/с. Дивимося в датасіті потрібне значення і дефайном визначаємо змінну:
Тепер нам необхідно оголосити всі змінні, які нам знадобляться. Крім того, визначимо тип даних bool:
На цьому приготування можна вважати закінченими.
Для надсилання даних ми будемо використовувати UART_SendData():
Прапор readyToExchange сигналізує про закінчення прийому/передачі. Тобто, передавши всі наші байти, ми виставляємо цей прапор у одиницю. І, звичайно ж, ми повинні дозволити, власне, передачу та необхідне переривання:
Пишемо обробник переривання:
Тут ми суємо дані в регістр UDR0, звідки вони вилітають у світ. Звичайно, інкрементуємо покажчик на дані, щоб передавати наступні байти. Також інкрементуємо змінну-лічильник для кількостінадісланих байт. Потім перевіряємо, чи дорівнює кількість відправлених байт кількості байт, які необхідно відправити. Якщо рівно, то значить наша робота закінчена, ми всі відправили, можна прикривати лавочку, тобто забороняти переривання:
При прийомі даних ситуація приблизно така сама, програма побудована таким чином:
Залишилося лише все це якось запустити. Ідемо у функцію main() і дивимося, що там у нас є:
Для початку тут у нас глобальна роздільна здатність переривань і налаштування швидкості передачі даних. Вся движуха у нас у циклі while(1). Викликаємо команду на прийом восьми байт даних і чекаємо, поки цей процес завершиться і злетить прапор readyToExchange. Після цього ще трохи тупим у затримці, щоб прийом остаточно завершився і запускаємо передачу того масиву даних, який ми щойно прийняли. От і все )
Залишилося переконатися, що все працює як слід. Відкриваємо термінал (я, до речі, використовуюAdvanced Serial Port Monitor ). Передаємо контролеру 8 байт даних і він нам повинен у відповідь надіслати ті самі байти.

А наскільки вона правильно відпрацює, якщо я пошлю слідом другий рядок. Виходить, що поки я не встановлю прапор readyToExchange в 1, друге повідомлення не піде.
Наприклад, будуть два повідомлення void main(void) sei(); UBRR0 = AVR_USART_9600_VALUE;
UART_SendData("Start systems", 8); // Це піде
UART_SendData(“initialization TWI”, 8); - А це вже ні.

Так все вірно. При такому варіанті відправки слід після виклику UART_SendData аналізувати прапор готовності і лише потім розпочинати нове відправлення.
Добрийдень! На старості років поліз в авр-ки ... Чорт мене смикнув))) Ніяк з цими уартами не подружуся))) Поясніть безглуздому, як приймати рядки різної довжини? Максимально 38 символів, мінімально-3. Останній завжди “;” Власне, перші два- команда, потім параметр від 1 до 35 символів, останній символ “;”. "Типу ID;" - запит, відповідь на нього, наприклад, "ID090;" Всю обробку вже написав з горем навпіл))) А ось UARTи ці ніяк перемогти не виходить. Повне завдання по уартам така: є вбудований- у нього використовується і прийом, і передача. І один програмний-тільки на прийом. контролер повинен постійно слухати обидва приймальні. З програмного-тупо відправляти, без жодного аналізу, дані на передачу. З вбудованого- тут йде обробка вже. Але якщо на прийомних якийсь час (близько секунди) нічого немає, то треба відправити запит-чотири символи. Типу "IF;" Або іноді, при необхідності- щось типу “PCxxx;” Як це можна реалізувати?

Приймати просто по одному байти, а при прийомі завершального символу відключати передачу.
Щиро кажучи, вже пробував. Нічого в мене до ладу не вийшло. Справа в тому, що, скажімо, на запит типу “IF;” мені має прилетіти IF і ще 35 значень, потім; і з цього потоку мені треба в різних місцях висмикувати спочатку 5-ти значне десяткове значення, а потім ще 2-3 однозначних або односимвольних, з пакета з індефікаторами FA або FB-5-ти значне, використовується там же, де і з ”. тобто. з FAxxxXXXXXxxx; тільки які Х.))) І вони мені потрібні як ціле десяткове число))) Добре, хоч обробляти треба тільки те, що йде з вбудованого UART). А тут ще й цей програмний))) Просто, сам уже зациклився, напевно) Ази програмування проходив ще більше 30 років тому) FORTRAN іPL/1)))) А з контролерами працював у середині 90-х)))) Тоді за ніч освоював якийсь 580ВЕ31 або 8035))) Мабуть, мізки вже іржавіти почали, працюють зі скрипом))))

Ну там головне все прийняти, а потім вже окремо обробити, поза перериванням)
Я розумію, що треба зробити якось типу
оголосити масив uint8 rx_str[];
ну і потім щось на кшталт
< uint8 i=0; while (UDR!=”;”) rx_str[i]= UDR; i++;> rx_str[i]= UDR; // щоб не втратити “;”- фактично rx_str[i]=”;” return i; >
тобто. заповнити масив і отримати кількість символів, Хоча, воно мені особливо не потрібно. Оброблятиметься лише у випадку, якщо їх або 14 (перші 2 FA або FB) або 38 (перші два IF), причому третій "0", а останній ";" А ось як правильно все оформити не в'їду))) Добре, не буду мучити Вас, краще на вихідні зганяю на рибалку))))

Як пройшла рибалка? =)
Добрий вечір! А рибалка була в дельті Волги)))) А там завжди чудова!))) Магічна рибка вобла)))) Навіть калмицькі дороги до кінця всього позитиву не зіпсували. Але диски доведеться купити інші-одне колесо можна просто викинути-диск розбитий, скат порваний. Але рибалка була чудовою!))) Нас мій астраханський товариш у такі місця завез- диво! Зараз на берегах Волги та її "супутників" - камінь кинь і в рибалки потрапиш, а ми три доби і людей особливо не бачили)))