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

Проект 24. Секундомер 00…99

Секундомер с индикацией и управлением одной кнопкой: нажатие запускает и останавливает счёт. Объединяет индикацию, опрос кнопки и отсчёт времени.

Задача

Считать секунды от 00 до 99, запуская и останавливая счёт кнопкой.

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

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

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

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

ВыводПодключение
PB0…PB6сегменты
PD0 / PD1разряды
PD2кнопка пуск/стоп

Алгоритм

  1. Хранить флаг работы: считаем или стоим.
  2. Непрерывно обновлять индикацию и попутно опрашивать кнопку.
  3. По нажатию инвертировать флаг командой eor.
  4. Если счёт разрешён — раз в секунду увеличивать показания.

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

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

;=======================================================
; Проект 24. Секундомер 00..99 с кнопкой «пуск/стоп»
; ATmega8, 8 МГц. Сегменты PB0..PB6, разряды PD0/PD1, кнопка PD2
;=======================================================
.include "m8def.inc"
.def    temp  = r16
.def    tens  = r17
.def    ones  = r18
.def    loops = r19
.def    run   = r20
.def    d1    = r21
.def    d2    = r22

.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
        out     DDRB, temp
        ldi     temp, 0x03
        out     DDRD, temp              ; PD0,PD1 — разряды; PD2 — вход
        sbi     PORTD, PD2              ; подтяжка кнопки
        clr     tens
        clr     ones
        clr     run

MAIN:
        ldi     loops, 100              ; ~1 секунда
SHOW:
        rcall   DIGITS
        rcall   CHECK_KEY
        dec     loops
        brne    SHOW

        tst     run                     ; счёт разрешён?
        breq    MAIN
        inc     ones
        cpi     ones, 10
        brne    MAIN
        clr     ones
        inc     tens
        cpi     tens, 10
        brne    MAIN
        clr     tens
        rjmp    MAIN

DIGITS:
        cbi     PORTD, PD1
        mov     temp, tens
        rcall   SEG
        out     PORTB, temp
        sbi     PORTD, PD0
        rcall   DELAY5MS
        cbi     PORTD, PD0
        mov     temp, ones
        rcall   SEG
        out     PORTB, temp
        sbi     PORTD, PD1
        rcall   DELAY5MS
        ret

CHECK_KEY:
        sbic    PIND, PD2
        ret
        rcall   DELAY5MS
        sbic    PIND, PD2
        ret
        ldi     temp, 1
        eor     run, temp               ; пуск/стоп
K_REL:  sbis    PIND, PD2
        rjmp    K_REL
        ret

SEG:
        ldi     ZL, low(SEGTAB<<1)
        ldi     ZH, high(SEGTAB<<1)
        add     ZL, temp
        clr     temp
        adc     ZH, temp
        lpm     temp, Z
        ret

DELAY5MS:
        ldi     d2, 52
E2:     ldi     d1, 255
E1:     dec     d1
        brne    E1
        dec     d2
        brne    E2
        ret

Пояснения

  • Опрос кнопки встроен в цикл индикации, поэтому дисплей не гаснет, а реакция остаётся быстрой.
  • Проверка флага делается командой tst с переходом breq — она короче явного сравнения с нулём.
  • Для метрологической точности счёт времени переносят на таймер с прерыванием, как в следующем проекте.

Что дальше

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