AFON // радиотехник affonya@mail.ru
← Проекты на AVR

Проект 31. Передача данных по USART

Микроконтроллер отправляет текст в терминал компьютера. Проект вводит расчёт скорости, регистры USART и работу со строками, хранящимися в памяти программ.

Задача

Отправить текстовую строку в терминал компьютера.

Микроконтроллер: 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 В

Алгоритм

  1. Рассчитать значение UBRR по формуле F_CPU/(16·скорость) − 1.
  2. Включить передатчик битом TXEN и задать формат кадра в UCSRC.
  3. Дождаться освобождения буфера по флагу UDRE.
  4. Записать байт в регистр 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.