Приложение: программа на языке 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 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-10-17 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: