Задача
Поддерживать температуру в заданном диапазоне, управляя нагревателем.
Микроконтроллер: ATmega8, кварц 4 МГц. Среда: Atmel Studio / avra (или avra / Atmel Studio). Как настроить среду и прошить контроллер — в статье программирование AVR.
Что понадобится
- ATmega8
- кварц 8 МГц + 2×22 пФ
- датчик LM35
- реле, транзистор, обратный диод
- конденсатор 100 нФ у выхода датчика
Схема подключения
| Вывод | Подключение |
|---|---|
| PC0 / ADC0 | выход датчика LM35 |
| PB0 | через транзистор на реле нагревателя |
| PB1 | светодиод состояния нагрева |
| AREF | конденсатор 100 нФ на GND |
Алгоритм
- Измерить температуру: при опорном 2,56 В код АЦП равен градусам.
- Ниже нижнего порога включить нагреватель.
- Выше верхнего порога выключить его.
- Между порогами состояние не менять.
Листинг на ассемблере
Код проверен ассемблером и собирается без ошибок. Скачать: a45.asm · a45.hex (готовая прошивка).
;=======================================================
; Проект 45. Термостат на LM35 с гистерезисом
; ATmega8, 8 МГц. Датчик LM35 — ADC0 (PC0),
; нагреватель через реле — PB0, индикация — PB1
; Опорное 2,56 В: код АЦП равен градусам Цельсия
;=======================================================
.include "m8def.inc"
.def tmp = r16
.def temp = r17
.equ T_ON = 22 ; включить нагрев ниже 22 C
.equ T_OFF = 25 ; выключить выше 25 C
.cseg
.org 0x0000
rjmp RESET
RESET:
ldi tmp, low(RAMEND)
out SPL, tmp
ldi tmp, high(RAMEND)
out SPH, tmp
ldi tmp, 0b00000011
out DDRB, tmp
cbi DDRC, 0 ; вход датчика
;--- внутреннее опорное 2,56 В, выравнивание влево, канал 0 ---
ldi tmp, (1<<REFS1)|(1<<REFS0)|(1<<ADLAR)
out ADMUX, tmp
ldi tmp, (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)
out ADCSRA, tmp
MAIN:
rcall ReadTemp
out PORTB, r1 ; гасим индикацию перед решением
cpi temp, T_ON
brsh CHECK_OFF ; температура не ниже порога включения
sbi PORTB, 0 ; холодно — включаем нагрев
sbi PORTB, 1
rjmp NEXT
CHECK_OFF:
cpi temp, T_OFF
brlo NEXT ; в зоне гистерезиса — не трогаем
cbi PORTB, 0 ; жарко — выключаем нагрев
cbi PORTB, 1
NEXT:
rcall Delay500ms
rjmp MAIN
ReadTemp:
sbi ADCSRA, ADSC ; запуск преобразования
AD_W:
sbic ADCSRA, ADSC
rjmp AD_W
in temp, ADCH ; старший байт: 1 код = 1 градус
ret
Delay500ms:
ldi r18, 21
S1: ldi r19, 255
S2: ldi r20, 255
S3: dec r20
brne S3
dec r19
brne S2
dec r18
brne S1
ret
Пояснения
- Без гистерезиса на пороге реле щёлкало бы десятки раз в минуту, быстро выходя из строя; разнесённые пороги решают проблему полностью.
- Сравнение беззнаковых чисел делается парой
cpiиbrsh/brlo— проще, чем вычитание с проверкой переноса в PIC. - Ширина гистерезиса подбирается по инерции системы: чем медленнее остывает объект, тем шире можно взять зону.
Что дальше
Разобравшись с этим проектом, переходите к следующему в разделе проекты на PIC. Справочник по архитектуре и периферии контроллеров — на странице микроконтроллеры AVR.