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

Проект 11. Семисегментный индикатор

Вывод цифр через таблицу знакогенератора, которая лежит в памяти программ и читается командой lpm. Приём используется во всех задачах индикации на AVR.

Задача

Последовательно выводить цифры от 0 до 9 на семисегментный индикатор.

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

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

  • ATmega8
  • кварц 8 МГц + 2×22 пФ
  • индикатор с общим катодом
  • 7 резисторов 330 Ом

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

ВыводПодключение
PB0…PB6сегменты a…g, каждый через резистор 330 Ом
Общий катодна GND
RESETчерез 10 кОм на +5 В

Алгоритм

  1. Разместить коды сегментов в памяти программ директивой .db.
  2. Загрузить в указатель Z адрес таблицы и прибавить номер цифры.
  3. Прочитать байт командой lpm.
  4. Вывести код в порт и повторить для следующей цифры.

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

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

;=======================================================
; Проект 11. Статический 7-сегментный индикатор
; ATmega8, 8 МГц. Индикатор с ОБЩИМ КАТОДОМ на PB0..PB6
; Таблица сегментов хранится во flash, читается командой lpm
;=======================================================
.include "m8def.inc"
.def    temp = r16
.def    digit= r17
.def    d1   = r18
.def    d2   = r19
.def    d3   = r20

.cseg
.org    0x0000
        rjmp    RESET

SEGTAB: .db 0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110
        .db 0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111

RESET:
        ldi     temp, low(RAMEND)
        out     SPL, temp
        ldi     temp, high(RAMEND)
        out     SPH, temp
        ldi     temp, 0x7F              ; PB0..PB6 — сегменты
        out     DDRB, temp
        clr     digit

MAIN:
        ldi     ZL, low(SEGTAB<<1)      ; адрес таблицы в байтах
        ldi     ZH, high(SEGTAB<<1)
        add     ZL, digit               ; смещение на нужную цифру
        clr     temp
        adc     ZH, temp
        lpm     temp, Z                 ; читаем код сегментов
        out     PORTB, temp
        rcall   DELAY1S
        inc     digit
        cpi     digit, 10
        brne    MAIN
        clr     digit
        rjmp    MAIN

DELAY1S:
        ldi     d3, 40
T3:     ldi     d2, 255
T2:     ldi     d1, 255
T1:     dec     d1
        brne    T1
        dec     d2
        brne    T2
        dec     d3
        brne    T3
        ret

Пояснения

  • Память программ адресуется словами, а команда lpm работает с байтами, поэтому адрес таблицы сдвигают влево: low(SEGTAB<<1).
  • Сложение адреса делают с учётом переноса: add ZL, затем adc ZH — иначе таблица за границей 256 байт будет читаться неверно.
  • Для индикатора с общим анодом коды инвертируют командой com — сегмент зажигается нулём.

Что дальше

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