Задача
Отправить текстовую строку в терминал компьютера.
Микроконтроллер: ATmega8, кварц 4 МГц. Среда: Atmel Studio / avra (или avra / Atmel Studio). Как настроить среду и прошить контроллер — в статье программирование AVR.
Что понадобится
- ATmega8
- кварц 8 МГц + 2×22 пФ
- преобразователь USB-UART (CP2102, CH340) или MAX232
- резистор 10 кОм
Схема подключения
| Вывод | Подключение |
|---|---|
| PD1 / TXD | вход RXD преобразователя USB-UART |
| PD0 / RXD | выход TXD преобразователя |
| GND | общий с преобразователем |
| RESET | через 10 кОм на +5 В |
Алгоритм
- Рассчитать значение UBRR по формуле F_CPU/(16·скорость) − 1.
- Включить передатчик битом TXEN и задать формат кадра в UCSRC.
- Дождаться освобождения буфера по флагу UDRE.
- Записать байт в регистр UDR — передача пойдёт аппаратно.
Листинг на ассемблере
Код проверен ассемблером и собирается без ошибок. Скачать: a31.asm · a31.hex (готовая прошивка).
;=======================================================
; Проект 31. Передача по USART
; ATmega8, 8 МГц. Скорость 9600 бод, вывод строки в терминал
; TXD (PD1) через преобразователь уровней на COM или USB-UART
;=======================================================
.include "m8def.inc"
.def tmp = r16
.def chr = r17
.cseg
.org 0x0000
rjmp RESET
RESET:
ldi tmp, low(RAMEND) ; инициализация стека — обязательна
out SPL, tmp
ldi tmp, high(RAMEND)
out SPH, tmp
rcall UsartInit
MAIN:
ldi ZL, low(TEXT<<1) ; адрес строки во flash
ldi ZH, high(TEXT<<1)
SEND_LOOP:
lpm chr, Z+ ; читаем байт из памяти программ
cpi chr, 0 ; конец строки?
breq PAUSE
mov tmp, chr
rcall UsartSend
rjmp SEND_LOOP
PAUSE:
rcall Delay1s
rjmp MAIN
;--- настройка USART: 9600 бод при 8 МГц ---
UsartInit:
ldi tmp, 0
out UBRRH, tmp
ldi tmp, 51 ; UBRR = F_CPU/(16*9600) - 1
out UBRRL, tmp
ldi tmp, (1<<TXEN)|(1<<RXEN)
out UCSRB, tmp
ldi tmp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0) ; 8 бит, 1 стоп
out UCSRC, tmp
ret
;--- передача байта из tmp ---
UsartSend:
sbis UCSRA, UDRE ; буфер передатчика свободен?
rjmp UsartSend
out UDR, tmp
ret
Delay1s:
ldi r18, 41
D1: ldi r19, 255
D2: ldi r20, 255
D3: dec r20
brne D3
dec r19
brne D2
dec r18
brne D1
ret
TEXT: .db "AFON radio - ATmega8", 13, 10, 0
Пояснения
- Запись в UCSRC требует установленного бита URSEL: этот регистр делит адрес с UBRRH, и бит указывает, в какой из них идёт запись.
- Строка хранится во flash и читается командой
lpmс автоинкрементом Z — в ОЗУ ATmega8 всего килобайт, тексты там держать расточительно. - При 8 МГц и 9600 бод погрешность скорости около 0,2 % — связь устойчивая. Для 115200 бод ошибка вырастет, и лучше взять кварц 7,3728 МГц.
Что дальше
Разобравшись с этим проектом, переходите к следующему в разделе проекты на PIC. Справочник по архитектуре и периферии контроллеров — на странице микроконтроллеры AVR.