port_set:
ldi result,$ff ;PORTB настраивается на вывод
out DDRB,result ;для работы с индикатором
ldi result,$00 ;все биты устанавливаются в ноль
out PORTB,result;PORTD настраивается для работы
ldi result,0b01000011 ; с клавиатурой и
out DDRD,result ;микросхемой термометра
ldi result,0b11111001 ; с клавиатурой и
out PORTD,result ;микросхемой термометра
ret
;*************************************************************************
;* очистка буфера ЖКИ
CLRLCD:
ldi ramsize,10 ;очистка буфера индикатора
ldi temp,0
ldi ZH,high(DLCD)
ldi ZL,low(DLCD)
clrlcdloop:
st Z+,temp
dec ramsize
brne clrlcdloop ;если не закончили повторить
rjmp LCDOUT
; Вывод содержимого буфера на индикатор
LCDOUT:
ldi temp,low(DLCD) ;установить Z как указатель на буфер
mov ZL,temp ;индикатора
ldi temp,high(DLCD)
mov ZH,temp
ldi ramsize,10
LCDOUT1:
mov temp,ramsize ;запись в индикатор адреса символа
andi temp,0b00001111
out PORTB,temp
cbi PORTB,A0
sbi PORTB,WR1
cbi PORTB,WR1
ld temp1,Z+ ; получить байт из DLCD
mov temp,temp1
andi temp,0b00001111 ;получить младшую тетраду
sbrs temp,A0
swap temp
andi temp,0b00001111 ;получить старшую тетраду
dec ramsize ;
brne LCDOUT1 ;если не закончили повторить
;* вывод готовой строки в буфер и вывод буфера на ЖКИ
;* temp - номер строки
;* ramsize - количество выводимых символов
STRLCDD:
ldi YH,high(tcstr)
ldi YL,low(tcstr)
add temp,temp
add YL,temp
ldi ramsize,4
;* Y - указатель на строку temp - положение
STRLCD:
strtolcdloop:
ld temp,Y+
brne strtolcdloop ;если не закончили повторить
;* получение данных из термостата
;* temp2 - команда temp - первые 8 бит temp1 - 9-ый бит
TERMIN:
ldi ramsize,8
terminloop:
sbi PIND,DQ
sbrc temp2,0
cbi PIND,DQ
sbi PIND,CLK
cbi PIND,CLK
ror temp2
brne terminloop ;если не закончили повторить
ldi ramsize,0x8
sbi DDRD,DQ
termindloop:
sbrc temp,0
brne termindloop ;если не закончили повторить
sbrc temp1,0
cbi DDRD,DQ
;* передача одного байта данных на термостат
;* temp2 - команда
TERMOUT1:
termout1loop:
brne termout1loop ;если не закончили повторить
;* передача одного байта данных на термостат и 9 бит
TERMOUT2:
termout2loop:
brne termout2loop ;если не закончили повторить
termout2loopdat:
clc
sbic PIND,DQ
sec
brne termout2loopdat ;если не закончили повторить
ldi temp1,0
ldi temp1,1
;* получение кода нажатой клавиши если она нажата более 20 мс
;* код кнопки находится в регистре key если сброшен бит Z
KEYPRESS:
ldi temp1,20 ;количество попыток для гашения
;дребезга контактов
keyloop:
in temp,PIND
andi temp,0b00111000
breq keynopress
sbic PIND,K1
ldi key,1
sbic PIND,K2
ldi key,2
sbic PIND,K3
ldi key,3
dec temp1
brne keyloop ;если не закончили повторить
keynopress:
and key,key
;* ожидание отпускания клавиши
KEYUP:
keyuloop:
andi temp,0b001110000
breq unpress
brne KEYUP ;если не закончили повторить
unpress:
; программа переводит температуру в зависимости от режима
; и выводит на индикатор для индикации
; calckterm
outTmax:
mov fbinL,TMAXL
mov fbinH,TMAXH
rjmp outterm
outTmin:
calckterm:
mov temp,tmode
rcall STRLCD
mov fbinL,TNORML
mov fbinH,TNORMH
cpi tmode,1
breq outTmin
cpi tmode,2
breq outTmax
ldi temp,0xb
outterm:
ldi ZH,high(DLCD+5)
ldi ZL,low(DLCD+5)
ldi temp2,0xb
sbrs fbinH,0
ldi temp2,0x10
; ldi temp3,0
; sub temp3,temp2
; ror temp3
st Z+,temp2
inc ZL
ldi temp2,5
sbrs fbinL,0
ldi temp2,0
ldi fbinH,0
ror fbinL
rcall bin16BCD5
mov temp3,fbinH
mov temp2,fbinL
swap temp2
andi temp3,0xf
andi temp2,0xf
andi temp,0xf
rcall getcod
mov temp1,temp
set
bst temp1,4
mov temp,temp2
mov temp2,temp
mov temp,temp3
mov temp3,temp
ldi ZH,high(DLCD+6)
ldi ZL,low(DLCD+6)
st Z+,temp3
st Z+,temp1
rcall LCDOUT
; программа возвращает код символа для индикатора
; значение temp заменяется на значение необходимое для отображения на
; индикаторе и оно помещается назад в ячейку temp
getcod:
ldi ZH,high(LCDCG*2)
ldi ZL,low(LCDCG*2);init Z-pointer
add ZL,temp
lpm ;get constant
mov temp,r0
; данные для отображения на индикаторе
LCDCG: ;тип код
.DB 0xEE ;число 0
.DB 0x60 ;число 1
.DB 0x2F ;число 2
.DB 0x6D ;число 3
.DB 0xE1 ;число 4
.DB 0xCD ;число 5
.DB 0xCF ;число 6
.DB 0x68 ;число 7
.DB 0xEF ;число 8
.DB 0xED ;число 9
.DB 0x10 ;символ. a
.DB 0x01 ;символ - b
.DB 0x87 ;символ t c
.DB 0x46 ;символ u d
.DB 0x67 ;символ d e
.DB 0x07 ;символ c f
.DB 0x00 ;символ blanck 10 пустой символ
;строка tc-
tcstr:
.DB 0x0c,0x0f,0x0b,0x10
;строка tu-
tustr:
.DB 0x0c,0x0d,0x0b,0x10
;cтрока td-
tdstr:
.DB 0x0c,0x0e,0x0b,0x10
;*
;* PROGRAM RESET - главная программа
RESET:
ldi temp,low(RAMEND)
out SPL,temp ; настройка стека на верх памяти данных
rcall port_set ; настроить порты
rcall CLRLCD
;* mainloop - главный цикл программы
mainloop:
ldi temp1,250
mov r5,temp1
mainloop1:
rcall KEYPRESS ;определения нажатия кнопки
brne keyis ; переход если хотябы одна кнопка нажата
rjmp returnin ;возврат к основному цыклу
keyis:
cpi temp,1
rcall key1press
cpi temp,2
rcall key2press
cpi temp,3
rcall key3press
returnin:
ldi temp1,0xaa ; чтениее текущей температуры термостата
rcall TERMIN
ldi temp2,0xaa ; инициализация термостата
mov TNORML,temp
mov TNORMH,temp1
rcall calckterm ; расчет температуры
dec r5
brne mainloop1 ; после ожиданжжия в течении минуты
ldi tmode,0 ; возвратиться в основной режим
rjmp mainloop
;* обработка клавиши режима
key1press:
and tmode,tmode
brne k1setmax
dec tmode
rjmp keyret
k1setmax:
ldi temp,2
mov tmode,temp
keyret:
rcall calckterm
rjmp KEYUP
;* обработка клавиши изменения значения вверх
key2press:
brne key2min
brne key2max
key2min:
sbrs TMINH,0
rjmp key2minm
inc TMINL
brmi key2mins
key2mins:
ldi TMINH,0
key2minm:
cpi TMINL,0xfa
brmi keyret
key2max:
sbrs TMAXH,0
rjmp key2maxm
brmi key2maxs
key2maxs:
ldi TMAXH,0
key2maxm:
cpi TMAXL,0xfa
inc TMAXL
;* обработка клавиши изменения значения вниз
key3press:
brne key3min
brne key3max
key3min:
sbrc TMINH,0
rjmp key3minm
dec TMINL
brmi key3mins
key3mins:
ldi TMINH,1
key3minm:
cpi TMINL,0x92
key3max:
sbrc TMAXH,0
rjmp key3maxm
dec TMAXL
brmi key3maxs
key3maxs:
ldi TMAXH,1
key3maxm:
cpi TMAXL,0x92
;1. Текст программы "bin16BCD5"- преобразование 16-битного двоичного
;значения в упакованный BCD формат
;* Количество слов кода:25 + возврат
;* Количество циклов:25/176 (Мин/Макс) + возврат
;* Использованные младшие регистры:нет
;* Использованные старшие регистры:4(fbinL,fbinH/tBCD0,tBCD1,tBCD2)
;* Использованные указатели:нет
;***** Регистровые переменные подпрограммы
.def fbinL =r16;двоичное значение, младший байт
.def fbinH =r17;двоичное значение, старший байт
.def tBCD0 =r17;BCD значение, цифры 1 и 0
.def tBCD1 =r18;BCD значение, цифры 3 и 2
.def tBCD2 =r19;BCD значение, цифра 4
;Примечание: Переменные fbinH и tBCD0 должны размещаться в одном
;регистре.
;***** Код
bin16BCD5:
ldi tBCD2, -1
bin16BCD5_loop_1:
inc tBCD2
subi fbinL, low(10000)
sbci fbinH, high(10000)
brsh bin16BCD5_loop_1
subi fbinL, low(-10000)
sbci fbinH, high(-10000)
ldi tBCD1, -0x11
bin16BCD5_loop_2:
subi tBCD1, -0x10
subi fbinL, low(1000)
sbci fbinH, high(1000)
brsh bin16BCD5_loop_2
subi fbinL, low(-1000)
sbci fbinH, high(-1000)
bin16BCD5_loop_3:
inc tBCD1
subi fbinL, low(100)
sbci fbinH, high(100)
brsh bin16BCD5_loop_3
subi fbinL, -100
ldi tBCD0, -0x10
bin16BCD5_loop_4:
subi tBCD0, -0x10
subi fbinL, 10
brsh bin16BCD5_loop_4
subi fbinL, -10
add tBCD0, fbinL
Страницы: 1, 2, 3