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

Проект 15. Вывод строк на LCD

Текст хранится в памяти программ и печатается посимвольно с автоинкрементом указателя. Проект показывает удобную работу со строками на AVR.

Задача

Вывести две текстовые строки — по одной на каждую строку дисплея.

Микроконтроллер: ATmega8, кварц 4 МГц. Среда: Atmel Studio / avra (или avra / Atmel Studio). Как настроить среду и прошить контроллер — в статье программирование AVR.

Что понадобится

  • ATmega8
  • кварц 8 МГц + 2×22 пФ
  • дисплей 16×2 на HD44780
  • подстроечник 10 кОм

Схема подключения

ВыводПодключение
PD4…PD7данные D4…D7
PD2RS
PD3E
RWна GND

Алгоритм

  1. Разместить строки в памяти программ директивой .db с нулевым байтом в конце.
  2. Установить курсор в начало строки командой 0x80.
  3. Читать символы командой lpm chr, Z+ до нулевого байта.
  4. Перевести курсор командой 0xC0 и повторить для второй строки.

Листинг на ассемблере

Код проверен ассемблером и собирается без ошибок. Скачать: a15.asm · a15.hex (готовая прошивка).

;=======================================================
; Проект 15. Вывод строк на LCD из памяти программ
; ATmega8, 8 МГц. PD4..PD7 — D4..D7, PD2 — RS, PD3 — E
;=======================================================
.include "m8def.inc"
.equ    LCD_RS = PD2
.equ    LCD_E  = PD3
.def    temp = r16
.def    chr  = r17
.def    d1   = r18
.def    d2   = r19

.cseg
.org    0x0000
        rjmp    RESET

STR1:   .db "AFON radio", 0, 0
STR2:   .db "ATmega8 asm", 0

RESET:
        ldi     temp, low(RAMEND)
        out     SPL, temp
        ldi     temp, high(RAMEND)
        out     SPH, temp
        ldi     temp, 0xFC
        out     DDRD, temp
        clr     temp
        out     PORTD, temp
        rcall   DELAY20MS
        rcall   LCD_INIT

        ldi     chr, 0x80               ; начало первой строки
        rcall   LCD_CMD
        ldi     ZL, low(STR1<<1)
        ldi     ZH, high(STR1<<1)
        rcall   PRINT

        ldi     chr, 0xC0               ; начало второй строки
        rcall   LCD_CMD
        ldi     ZL, low(STR2<<1)
        ldi     ZH, high(STR2<<1)
        rcall   PRINT
STOP:   rjmp    STOP

;--- печать строки из flash, адрес в Z, конец — нулевой байт ---
PRINT:
        lpm     chr, Z+
        tst     chr
        breq    PR_END
        rcall   LCD_DATA
        rjmp    PRINT
PR_END: ret

LCD_INIT:
        ldi     temp, 0x30
        rcall   SEND_NIBBLE
        rcall   DELAY5MS
        ldi     temp, 0x30
        rcall   SEND_NIBBLE
        rcall   DELAY5MS
        ldi     temp, 0x30
        rcall   SEND_NIBBLE
        rcall   DELAY5MS
        ldi     temp, 0x20
        rcall   SEND_NIBBLE
        rcall   DELAY5MS
        ldi     chr, 0x28
        rcall   LCD_CMD
        ldi     chr, 0x0C
        rcall   LCD_CMD
        ldi     chr, 0x06
        rcall   LCD_CMD
        ldi     chr, 0x01
        rcall   LCD_CMD
        rcall   DELAY5MS
        ret

LCD_CMD:
        cbi     PORTD, LCD_RS
        rjmp    SEND_BYTE
LCD_DATA:
        sbi     PORTD, LCD_RS
SEND_BYTE:
        mov     temp, chr
        andi    temp, 0xF0
        rcall   SEND_NIBBLE
        mov     temp, chr
        swap    temp
        andi    temp, 0xF0
        rcall   SEND_NIBBLE
        rcall   DELAY5MS
        ret

SEND_NIBBLE:
        push    r20
        in      r20, PORTD
        andi    r20, 0x0F
        or      temp, r20
        out     PORTD, temp
        sbi     PORTD, LCD_E
        nop
        nop
        cbi     PORTD, LCD_E
        pop     r20
        ret

DELAY5MS:
        ldi     d2, 52
X2:     ldi     d1, 255
X1:     dec     d1
        brne    X1
        dec     d2
        brne    X2
        ret

DELAY20MS:
        rcall   DELAY5MS
        rcall   DELAY5MS
        rcall   DELAY5MS
        rcall   DELAY5MS
        ret

Пояснения

  • Автоинкремент Z+ сам продвигает указатель — цикл печати получается на три команды короче, чем на PIC.
  • Адреса строк HD44780 не идут подряд: первая начинается с 0x00, вторая — с 0x40, отсюда команды 0x80 и 0xC0.
  • Строка в .db должна содержать чётное число байт, иначе ассемблер добавит выравнивающий ноль — это учтено дополнительным нулём.

Что дальше

Разобравшись с этим проектом, переходите к следующему в разделе проекты на PIC. Справочник по архитектуре и периферии контроллеров — на странице микроконтроллеры AVR.