Приложение: программа на языке Assembler
;************************************************************************* ;* Термостат на базе микроконтроллера AT90S2313 * ;* с использованием микросхемы термодатчика DS1620 * ;************************************************************************* ;************************************************************************* ;* Название: Цифровой регулятор температуры ;* Дата разработки: 20.06.02 ;* Объект: AVR микроконтроллер AT90S2313 и термостат DS1620 ;* Автор: Бендюк Максим Сергеевич ;* ;* ;*************************************************************************
.include "2313DEF.INC"
;***** Константы .equ preset=192 ;T/C0 Preset constant (256-64) .def result=r16 ;Result and intermediate data .def temp=r16 ;временный регистр .def temp1=r17 ;временный регистр .def temp2=r18 ;временный регистр .def temp3=r19 ;временный регистр .def ramsize=r19 ;размер блока .def tmode=r22 ;Регистр режима .def key=r20 ;Регистр нажатой клавиши .def keyc=r21 ;Счетчик для прграммы обработки нажатия клавиши .def TMIN=r22 ;ячейка с содержимым минимальной температуры термостата .def TMINL=r22 ;младший .def TMINH=r23 ;старший .def TMAX=r24 ;ячейка с содержимым максимальной температуры термостата .def TMAXL=r24 ;младший .def TMAXH=r25 ;старший .def TNORM=r26 ;ячейка с содержимым текущей температуры термостата .def TNORML=r26 ;младший .def TNORMH=r27 ;старший .equ DLCD=$66 ;стартовый адрес SRAM для буфера индикатора ;маладшая ячейка соответствует левому символу ;на дисплее .def fbinL =r16;двоичное значение, младший байт .def fbinH =r17;двоичное значение, старший байт ;биты портов .equ K1 =3 ;бит первой кнопки .equ K2 =4 ;бит второй кнопки .equ K3 =5 ;бит третьей кнопки .equ WR1 =5 ;бит WR1 .equ WR2 =6 ;бит WR2 .equ A0 =7 ;бит A0 .equ DQ =0 ;бит DQ канал данных термостата .equ CLK =1 ;бит CLK канал синхронизации данных
;************************************************************************* ;* ;* PROGRAM START - программа начинает выполняться с этого места ;* ;************************************************************************* .cseg .org $0000 rjmp RESET;Reset handle .org $0020 RETI RETI RETI RETI RETI RETI RETI RETI RETI RETI
;************************************************************************* ; настройка констант SETCONST: ldi temp,20 mov TMINL,temp ldi temp,0 mov TMINH,temp ldi temp,25 mov TMAXL,temp ldi temp,0 mov TMAXH,temp ret ;************************************************************************* ; передача констант OUTCONST: mov temp,TMINl mov temp1,TMINH ldi temp2,2 ;запись нижней температуры rcall TERMOUT2 mov temp,TMAXL mov temp1,TMAXH ldi temp2,1 ;запись нижней температуры rcall TERMOUT2 ldi temp1,0xee ; инициализация термостата rcall TERMOUT1 ret ;************************************************************************* ; Натройка портов ввода вывода 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 out PORTB,temp sbi PORTB,WR1 cbi PORTB,WR1
mov temp,temp1 swap temp andi temp,0b00001111 ;получить старшую тетраду sbrs temp,A0 out PORTB,temp sbi PORTB,WR1 cbi PORTB,WR1 dec ramsize ; brne LCDOUT1 ;если не закончили повторить ret ;************************************************************************* ;* вывод готовой строки в буфер и вывод буфера на ЖКИ ;* temp - номер строки ;* ramsize - количество выводимых символов STRLCDD: ldi YH,high(tcstr) ldi YL,low(tcstr) add temp,temp add temp,temp add YL,temp ldi ramsize,4 ;************************************************************************* ;* вывод готовой строки в буфер и вывод буфера на ЖКИ ;* Y - указатель на строку temp - положение ;* ramsize - количество выводимых символов STRLCD: ldi ZH,high(DLCD) ldi ZL,low(DLCD) strtolcdloop: ld temp,Y+ st Z+,temp dec ramsize brne strtolcdloop ;если не закончили повторить rjmp LCDOUT ;************************************************************************* ;* получение данных из термостата ;* 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 dec ramsize brne terminloop ;если не закончили повторить ldi ramsize,0x8 sbi DDRD,DQ termindloop: sbi PIND,DQ sbrc temp,0 cbi PIND,DQ sbi PIND,CLK cbi PIND,CLK ror temp2 dec ramsize brne termindloop ;если не закончили повторить sbi PIND,DQ sbrc temp1,0 cbi PIND,DQ sbi PIND,CLK cbi PIND,CLK cbi DDRD,DQ ret
;************************************************************************* ;* передача одного байта данных на термостат ;* temp2 - команда TERMOUT1: ldi ramsize,8 termout1loop: sbi PIND,DQ sbrc temp2,0 cbi PIND,DQ sbi PIND,CLK cbi PIND,CLK ror temp2 dec ramsize brne termout1loop ;если не закончили повторить ldi ramsize,0x8 ret ;************************************************************************* ;* передача одного байта данных на термостат и 9 бит ;* temp2 - команда temp - первые 8 бит temp1 - 9-ый бит TERMOUT2: ldi ramsize,8 termout2loop: sbi PIND,DQ sbrc temp2,0 cbi PIND,DQ sbi PIND,CLK cbi PIND,CLK ror temp2 dec ramsize brne termout2loop ;если не закончили повторить ldi ramsize,0x8 termout2loopdat: clc sbi PIND,CLK sbic PIND,DQ sec cbi PIND,CLK ror temp2 dec ramsize brne termout2loopdat ;если не закончили повторить ldi temp1,0 sbi PIND,CLK sbic PIND,DQ ldi temp1,1 cbi PIND,CLK cbi DDRD,DQ ret ;************************************************************************* ;* получение кода нажатой клавиши если она нажата более 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 ret
;************************************************************************* ;* ожидание отпускания клавиши KEYUP: ldi temp1,20 ;количество попыток для гашения ;дребезга контактов keyuloop: in temp,PIND andi temp,0b001110000 breq unpress dec temp1 brne KEYUP ;если не закончили повторить unpress: and key,key ret
;************************************************************************* ; программа переводит температуру в зависимости от режима ; и выводит на индикатор для индикации ; calckterm outTmax: mov fbinL,TMAXL mov fbinH,TMAXH rjmp outterm outTmin: mov fbinL,TMAXL mov fbinH,TMAXH rjmp outterm 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 inc ZL ldi temp2,5 sbrs fbinL,0 ldi temp2,0 st Z+,temp2 ldi fbinH,0 clc 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 rcall getcod mov temp2,temp mov temp,temp3 rcall getcod mov temp3,temp ldi ZH,high(DLCD+6) ldi ZL,low(DLCD+6) st Z+,temp3 st Z+,temp2 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 ret ;************************************************************************* ; данные для отображения на индикаторе 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: ldi temp1,250 mov r5,temp1 cpi temp,1 rcall key1press cpi temp,2 rcall key2press cpi temp,3 rcall key3press returnin: ldi temp1,0xaa ; чтениее текущей температуры термостата rcall TERMIN ldi temp2,0xaa ; инициализация термостата rcall TERMIN 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: cpi tmode,1 brne key2min cpi tmode,2 brne key2max rjmp keyret key2min: sbrs TMINH,0 rjmp key2minm inc TMINL brmi key2mins rjmp keyret key2mins: ldi TMINH,0 rjmp keyret key2minm: cpi TMINL,0xfa brmi keyret inc TMINL rjmp keyret key2max: sbrs TMAXH,0 rjmp key2maxm inc TMINL brmi key2maxs rjmp keyret key2maxs: ldi TMAXH,0 rjmp keyret key2maxm: cpi TMAXL,0xfa brmi keyret inc TMAXL rjmp keyret
;************************************************************************* ;* обработка клавиши изменения значения вниз key3press: cpi tmode,1 brne key3min cpi tmode,2 brne key3max rjmp keyret key3min: sbrc TMINH,0 rjmp key3minm dec TMINL brmi key3mins rjmp keyret key3mins: ldi TMINH,1 rjmp keyret key3minm: cpi TMINL,0x92 brmi keyret dec TMINL rjmp keyret key3max: sbrc TMAXH,0 rjmp key3maxm dec TMAXL brmi key3maxs rjmp keyret key3maxs: ldi TMAXH,1 rjmp keyret key3maxm: cpi TMAXL,0x92 brmi keyret dec TMAXL rjmp keyret
;************************************************************************* ;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 ret ;*************************************************************************
Популярное: Личность ребенка как объект и субъект в образовательной технологии: В настоящее время в России идет становление новой системы образования, ориентированного на вхождение... ![]() ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (174)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |