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

Проект 28. Цифровой вольтметр 0…5 В

Настоящий измерительный прибор: код АЦП переводится в вольты и выводится с десятичной точкой. Проект решает главную задачу — масштабирование результата.

Задача

Измерять напряжение 0…5 В и показывать его с точностью до десятых.

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

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

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

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

ВыводПодключение
PC0 / ADC0измеряемое напряжение (не выше 5 В)
PB0…PB6сегменты, PB7 — десятичная точка
PD0 / PD1разряды

Алгоритм

  1. Измерить напряжение и получить код 0…255.
  2. Вычитать по 51 единице — столько приходится на один вольт.
  3. Остаток разложить на десятые доли шагами по 5 единиц.
  4. Вывести оба разряда, зажигая точку у целых.

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

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

;=======================================================
; Проект 28. Цифровой вольтметр 0..5 В
; ATmega8, 8 МГц. Вход ADC0 (PC0)
; Индикация: целые вольты и десятые на двух разрядах
; Сегменты PB0..PB6 (PB7 — точка), разряды PD0/PD1
;=======================================================
.include "m8def.inc"
.def    temp  = r16
.def    volts = r17
.def    tenth = r18
.def    acc   = r19
.def    loops = 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, 0xFF
        out     DDRB, temp
        ldi     temp, 0x03
        out     DDRD, temp
        cbi     DDRC, PC0
        ldi     temp, (1<<REFS0)|(1<<ADLAR)
        out     ADMUX, temp
        ldi     temp, (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)
        out     ADCSRA, temp

MAIN:
        rcall   ADC_READ
        mov     acc, temp
        rcall   CONVERT
        ldi     loops, 50
SHOW:
        cbi     PORTD, PD1
        mov     temp, volts
        rcall   SEG
        ori     temp, 0b10000000        ; точка после целых вольт
        out     PORTB, temp
        sbi     PORTD, PD0
        rcall   DELAY5MS
        cbi     PORTD, PD0
        mov     temp, tenth
        rcall   SEG
        out     PORTB, temp
        sbi     PORTD, PD1
        rcall   DELAY5MS
        dec     loops
        brne    SHOW
        rjmp    MAIN

;--- код 0..255 -> вольты и десятые (51 единица на вольт) ---
CONVERT:
        clr     volts
        mov     temp, acc
V_LOOP: cpi     temp, 51
        brlo    T_PART
        subi    temp, 51
        inc     volts
        rjmp    V_LOOP
T_PART:
        clr     tenth
T_LOOP: cpi     temp, 5
        brlo    C_END
        subi    temp, 5
        inc     tenth
        cpi     tenth, 10
        brne    T_LOOP
        clr     tenth
        rjmp    T_LOOP
C_END:  ret

ADC_READ:
        in      temp, ADCSRA
        ori     temp, (1<<ADSC)
        out     ADCSRA, temp
AD_W:   in      temp, ADCSRA
        sbrc    temp, ADSC
        rjmp    AD_W
        in      temp, ADCH
        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
I2:     ldi     d1, 255
I1:     dec     d1
        brne    I1
        dec     d2
        brne    I2
        ret

Пояснения

  • Перевод сделан циклом вычитания командой subi — приём универсален для любого масштабирования при отсутствии деления.
  • Точность ограничена восемью битами: шаг составляет около 20 мВ. Для большей точности читают все десять бит и стабилизируют опорное напряжение.
  • Для напряжений выше 5 В ставят резистивный делитель, а коэффициент учитывают в пересчёте.

Что дальше

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