1_avr8_interfaces_USART
.pdfІнтерфейси мікроконтролерів AVR |
(test) |
23.03.2011 |
USART |
|
П.Штогрин |
Рисунок 1.10 – Вікно програми Terminal V1.9
Тепер розглянемо приклад приймання даних через інтерфейс USART. Після приймання байту даних він виводиться в порт B:
// Fclk = 4 MHz |
|
.include "m8def.inc" |
Приклад №2 |
.equ |
FCLK |
= 4000000 |
.equ |
BAUD |
= 9600 |
.equ |
_UBRR = FCLK/(16*BAUD)-1 |
;тактова частота
;швидкість передачі даних ч-з USART
;константа для завантаження UBRR
.def buffer = r16 |
; буферний регістр |
;================================ |
|
init: |
|
ldi r16, low(RAMEND) |
; ініціалізація стеку |
ldi r17, high(RAMEND) |
|
out SPH, r17 |
|
out SPL, r16 |
|
ldi r16, 0xFF |
|
out DDRB, r16 |
|
;ініціалізація USART
;встановлення швидкості передачі ldi r17, high(_UBRR)
ldi r16, low(_UBRR) out UBRRH, r17
out UBRRL, r16
;дозвіл приймання
ldi r16, 1<<RXEN out UCSRB, r16
11
Інтерфейси мікроконтролерів AVR |
(test) |
23.03.2011 |
USART |
|
П.Штогрин |
;режим передавання
;8 біт даних, 1 стоп-біт, без біту паритету ldi r16, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0) out UCSRC, r16
;================================
main: |
sbis UCSRA, RXC |
|
|
rjmp main |
|
|
in buffer, |
UDR |
|
out PORTB, |
buffer |
|
rjmp main |
|
;================================
Для приймання даних по USART необхідно встановити прапорець RXEN в регістрі UCSRB. В усьому іншому ініціалізація USART точно така сама, як і в попередньому прикладі.
В головному циклі програма постійно опитує прапорець RXC в регістрі UCSRA, який встановлюється кожного разу, коли в буфері приймача з’являється новий байт. Після зчитування буферного регістру прапорець RXC автоматично скидається, якщо в буфері приймача немає більше непрочитаних кадрів. Для контролю прийнятих байтів вони виводяться в порт B.
Якщо постійне опитування прапорця RXC є недоцільним, для зчитування прийнятих даних можна використовувати переривання приймача. Якщо встановити в одиницю прапорець RXCIE дозволу переривання приймача, встановлення прапорця RXC викличе генерацію переривання, в підпрограмі обробки якого прийняті дані зчитуються з буферу приймача.
// Fclk = 4 MHz |
|
|
.include "m8def.inc" |
Приклад №3 |
|
.equ |
FCLK = 4000000 |
; тактова частота |
.equ |
BAUD = 9600 |
; швидкість передачі даних ч-з USART |
.equ |
_UBRR = FCLK/(16*BAUD)-1 |
; константа для завантаження UBRR |
.def |
buffer = r16 |
; буферний регістр |
;================================ |
|
|
|
.org 0 |
|
|
rjmp init |
|
|
.org 0x00B |
|
|
rjmp USART_RXC |
; вектор перивання приймача |
;================================ |
|
|
init: |
|
|
|
ldi r16, low(RAMEND) |
; ініціалізація стеку |
|
ldi r17, high(RAMEND) |
|
|
out SPH, r17 |
|
|
out SPL, r16 |
|
|
ldi r16, 0xFF |
; ініціалізаця порту В |
|
out DDRB, r16 |
|
|
|
|
|
ldi r17, high(_UBRR) |
; ініціалізація USART |
|
ldi r16, low(_UBRR) |
|
|
out UBRRH, r17 |
|
|
out UBRRL, r16 |
|
|
ldi r16, (1<<RXEN)|(1<<RXCIE) |
|
|
out UCSRB, r16 |
|
|
ldi r16, (1<<URSEL)|(3<<UCSZ0) |
|
|
out UCSRC, r16 |
|
|
sei |
|
;================================ |
|
|
main: |
rjmp main |
|
|
|
|
|
|
12 |
Інтерфейси мікроконтролерів AVR |
(test) |
23.03.2011 |
USART |
|
П.Штогрин |
|
|
|
;================================ |
|
|
USART_RXC: |
; обробка переривання приймача |
|
in buffer, UDR |
|
|
out PORTB, buffer |
|
|
reti |
|
|
;================================ |
|
|
Усі вищенаведені приклади є ознайомчими і показують, як необхідно ініціалізовувати USART, а також ілюструють найпростіші процедури передавання та приймання байтів даних. Тепер давайте використаємо USART для більш конкретного завдання – керування роботою МК. Для того, щоб приклад був простий, а код невеликий, візьмемо програму генератора секундних імпульсів (приклад 12, розділ 1, гл. 4) і доопрацюємо її так, що пуском-зупинкою таймера можна було б керувати з комп’ютера натисканням кнопки на клавіатурі, наприклад, кнопки "0":
// Fclk = 4 MHz |
|
||
.include "m8def.inc" |
Приклад №4 |
||
.equ |
FCLK = 4000000 |
; тактова частота |
|
.equ |
BAUD = 9600 |
; швидкість передачі даних ч-з USART |
|
.equ |
_UBRR = FCLK/(16*BAUD)-1 |
; константа для завантаження UBRR |
|
.equ |
K1 = 1952 |
; константа для завантаження регістру порівнння |
|
.def |
buffer = r16 |
; буферний регістр |
|
.MACRO |
outi |
; макрос для запису числ. значень в регістри В/В |
|
|
ldi |
r16,@1 |
|
|
out |
@0,r16 |
|
.ENDMACRO |
|
|
;================================
.org 0 rjmp init
.org 0x00B rjmp USART_RXC
init:
outi SPH, high(RAMEND) outi SPL, low(RAMEND)
|
outi DDRB, 0xFF |
|
|
|
|
|
; ініціалізація USART |
|
|
; 8 біт даних, 1 стопбіт, без паритету |
|
|
outi UBRRH, high(_UBRR) |
|
|
outi UBRRL, low(_UBRR) |
|
|
outi UCSRB, (1<<RXEN)|(1<<RXCIE) |
|
|
outi UCSRC, (1<<URSEL)|(3<<UCSZ0) |
|
|
; ініціалізація ТЛ1 |
|
|
; CTC, автоматичне переключення OC1A при події збігу |
|
|
outi OCR1AH, high(K1) |
|
|
outi OCR1AL, low(K1) |
|
|
outi TCCR1B, 1<<CS12|1<<CS10|1<<WGM12 |
|
|
outi TCCR1A, 1<<COM1A0 |
|
|
|
|
|
sei |
|
main: |
rjmp main |
|
|
|
|
;================================ |
|
|
USART_RXC: |
|
|
|
in buffer, UDR |
; читаємо байт прийнятий по USART |
|
cpi buffer, 0x30 |
; порівнюємо з кодом цифри "0" |
|
|
13 |
Інтерфейси мікроконтролерів AVR |
(test) |
23.03.2011 |
USART |
|
П.Штогрин |
|
|
|
brne exit |
; ігноруємо усі інші символи |
|
in buffer, TCCR1A |
|
|
ldi r17, 1<<COM1A0 |
|
|
eor buffer, r17 |
; інвертуємо біт COM1A0 в регістрі TCCR1A |
|
out TCCR1A, buffer |
; який відповідає за переключення виводу OC1A |
|
exit: |
|
|
reti |
|
|
;================================ |
|
|
|
|
|
В розділі ініціалізації для ініціалізації усіх регістрів (стеку, портів, USART та таймера) використовується макрос outi, який завантажує число в регістр В/В через регістр R16. Таймер-лічильник 1 налаштований на режим СТС з автоматичним переключенням виводу OC1A при події збігу значень в лічильному регістрі TCNT1 та регістрі порівняння OCR1A.
Обробка прийнятих через USART байтів здійснюється по перериванню приймача. Спочатку отриманий байт порівнюється із значенням 0x30 (ASCII-код цифри "0"). Якщо значення не співпадає, припиняємо подальшу обробку і виходимо з підпрограми обробки переривання. Якщо код прийнятого символу дорівнює 0х30, змінюємо на протилежний стан генератора імпульсів: якщо він зупинений – запускаємо його, якщо працював – зупиняємо. Для цього необхідно лише інвертувати біт COM1A0 в регістрі TCCR1A, який керує переключенням виводу OC1A: завантажуємо вміст TCCR1A в тимчасовий регістр buffer, в другому тимчасовому регістрі (R17) формуємо маску: встановлений в одиницю біт, номер якого відповідає номеру біту COM1A0 в регістрі TCCR1A і здійснюємо операцію "виключне АБО" між вмістом регістру, в якому є копія вмісту TCCR1A, та вмістом регістру маски. Оскільки в регістрі маски встановлений в одиницю лише один біт, який відповідає за позицією біту COM1A0, тільки він і буде інвертований. Вміст регістру buffer після виконання операції "виключне АБО" записуємо назад в регістр TCCR1А. В такий спосіб в регістрі TCCR1A ми модифікували лише необхідний нам біт, залишаючи незмінними усі решта.
Якщо після інверсії біт COM1A0 буде дорівнювати нулю, переключення виводу OC1A припиниться, а після приймання по USART наступного символу "0", коли біт COM1A0 буде знов інвертований, і вже буде дорівнювати одиниці, переключення виводу OC1A відновиться.
Використання USART для відлагодження програм
Інтерфейс USART, окрім передачі даних, можна також використовувати при відлагодженні програм. В будякому місці програми (автоматично, при натисканні кнопки, чи за командою, переданою по тому ж USART), можна видати на екран LCD чи передати в ПК вміст будь яких регістрів або комірок пам’яті. Після закінчення відлагодження програми команди видачі вмісту регістрів чи комірок пам’яті через USART видаляються (або закоментовуються в тексті програми на випадок, якщо в майбутньому виникне потреба ще раз доопрацювати програму).
Практичні завдання
Практичне завдання №1: Переробити програму з прикладу 2, встановивши іншу швидкість передачі даних при іншій тактовій частоті роботи МК, наприклад 4800 біт/с при тактовій частоті 8 МГц.
Практичне завдання №2: Скласти програму, яка виводить текст, набраний на клавіатурі ПК, на LCDіндикатор, підключений до мікроконтролера. Передбачити команду очищення екрану LCD.
Практичне завдання №3: Доопрацювати програму з прикладу 4 так, щоб за допомогою команд з ПК можна було б не тільки запускати-зупиняти генератор імпульсів, але й керувати частотою імпульсів в певних межах при натисканні на клавіатурі ПК клавіш "+" та "–" (кількість кроків регулювання та дискретність вибрати самостійно). Якщо досягнуто нижню чи верхню межу регулювання, команди повинні ігноруватись.
Практичне завдання №4: Організувати з’єднання через USART двох мікроконтролерів ATmega8. До першого МК підключити кілька кнопок, до одного з портів другого МК підключити лінійку світлодіодів. При натисканні однієї з кнопок, підключених до першого МК, він повинен через USART відіслати до другого МК код натиснутої кнопки, а другий МК повинен вивести прийнятий код на світлодіодну лінійку.
14