roboforum.ru

Технический форум по робототехнике.

Термостат на Attiny 2313

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

Термостат на Attiny 2313

Сообщение MAZBELAZ » 09 дек 2014, 20:59

Собираю термостат в Протеусе на Attiny 2313.
Имеется код на ассемблере
5.txt
(14.43 КиБ) Скачиваний: 311

Код: Выделить всёРазвернуть
;====================================================================
; Main.asm file generated by New Project wizard
;
; Created:   Чт дек 4 2014
; Processor: ATtiny2313
; Compiler:  AVRASM (Proteus)
;====================================================================

;====================================================================
; DEFINITIONS
;====================================================================

;====================================================================
; VARIABLES
;====================================================================

;====================================================================
; RESET and INTERRUPT VECTORS
;====================================================================

      ; Reset Vector
     

;====================================================================
; CODE SEGMENT
;====================================================================

;Start:
      ;*************************************************************************
;* Термостат на базе микроконтроллера AT90S2313 *
;* с использованием микросхемы термодатчика DS1620 *
;*************************************************************************
;*************************************************************************
;* Название:      Цифровой регулятор температуры
;* Объект:       AVR микроконтроллер AT90S2313 и термостат DS1620
;*
;*
;*************************************************************************

.include "2313def.inc"

;***** Константы
.equ preset=192   ;T/C0 Preset constant (256-64)
.def result=r10   ;Result and intermediate data
.def temp=r11   ;временный регистр
.def temp1=r2   ;временный регистр
.def temp2=r3   ;временный регистр
.def temp3=r4   ;временный регистр
.def ramsize=r5   ;размер блока
.def tmode=r6   ;Регистр режима
.def key=r20      ;Регистр нажатой клавиши
.def keyc=r21   ;Счетчик для прграммы обработки нажатия клавиши
.def   TMIN=r22   ;ячейка с содержимым минимальной температуры термостата
.def   TMINL=r23   ;младший
.def   TMINH=r24   ;старший
.def   TMAX=r25   ;ячейка с содержимым максимальной температуры термостата
.def   TMAXL=r7   ;младший
.def   TMAXH=r8   ;старший
.def   TNORM=r9   ;ячейка с содержимым текущей температуры термостата
.def   TNORML=r12   ;младший
.def   TNORMH=r13   ;старший
.equ   DLCD=$66   ;стартовый адрес SRAM для буфера индикатора
;маладшая ячейка соответствует левому символу
;на дисплее
.def fbinL =r15;двоичное значение, младший байт
.def fbinH =r16;двоичное значение, старший байт
;биты портов
.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  Start
rjmp hhh

RETI
RETI
RETI
RETI
RETI
RETI
RETI
RETI
RETI
RETI
.org $0020
;*************************************************************************
; настройка констант
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 - главная программа
;*
;*************************************************************************

hhh:
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 =r15;двоичное значение, младший байт
;.def fbinH =r16;двоичное значение, старший байт
.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
;*************************************************************************

Loop:
      rjmp  Loop

;====================================================================

но компилятор ругается
Код: Выделить всёРазвернуть
avrasm2.exe -fO -i"C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\Tools\AVRASM\appnotes\tn2313def.inc" -o "Debug.obj" -l Debug.lst "..\main.asm"
AVRASM: AVR macro assembler 2.1.42 (build 1796 Sep 15 2009 10:48:36)
Copyright (C) 1995-2009 ATMEL Corporation

[builtin](2): Including file 'C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\Tools\AVRASM\appnotes\tn2313def.inc'
..\main.asm(40): Including file 'C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\Tools\AVRASM\appnotes\tn2313def.inc'
..\main.asm(102): error: Invalid register
..\main.asm(104): error: Invalid register
..\main.asm(106): error: Invalid register
..\main.asm(108): error: Invalid register
..\main.asm(116): error: Invalid register
..\main.asm(120): error: Invalid register
..\main.asm(122): error: Invalid register
..\main.asm(128): error: Invalid register
..\main.asm(130): error: Invalid register
..\main.asm(132): error: Invalid register
..\main.asm(134): error: Invalid register
..\main.asm(140): error: Invalid register
..\main.asm(141): error: Invalid register
..\main.asm(152): error: Invalid register
..\main.asm(154): error: Invalid register
..\main.asm(156): error: Invalid register
..\main.asm(159): error: Invalid register
..\main.asm(167): error: Invalid register
..\main.asm(175): error: Invalid register
..\main.asm(193): error: Invalid register
..\main.asm(211): error: Invalid register
..\main.asm(221): error: Invalid register
..\main.asm(244): error: Invalid register
..\main.asm(254): error: Invalid register
..\main.asm(260): error: Invalid register
..\main.asm(270): error: Invalid register
..\main.asm(280): error: Invalid register
..\main.asm(283): error: Invalid register
..\main.asm(291): error: Invalid register
..\main.asm(295): error: Invalid register
..\main.asm(312): error: Invalid register
..\main.asm(316): error: Invalid register
..\main.asm(341): error: Invalid register
..\main.asm(343): error: Invalid register
..\main.asm(345): error: Invalid register
..\main.asm(349): error: Invalid register
..\main.asm(351): error: Invalid register
..\main.asm(358): error: Invalid register
..\main.asm(360): error: Invalid register
..\main.asm(369): error: Invalid register
..\main.asm(370): error: Invalid register
..\main.asm(371): error: Invalid register
..\main.asm(402): warning: .cseg .db misalignment - padding zero byte
..\main.asm(403): warning: .cseg .db misalignment - padding zero byte
..\main.asm(404): warning: .cseg .db misalignment - padding zero byte
..\main.asm(405): warning: .cseg .db misalignment - padding zero byte
..\main.asm(406): warning: .cseg .db misalignment - padding zero byte
..\main.asm(407): warning: .cseg .db misalignment - padding zero byte
..\main.asm(408): warning: .cseg .db misalignment - padding zero byte
..\main.asm(409): warning: .cseg .db misalignment - padding zero byte
..\main.asm(410): warning: .cseg .db misalignment - padding zero byte
..\main.asm(411): warning: .cseg .db misalignment - padding zero byte
..\main.asm(412): warning: .cseg .db misalignment - padding zero byte
..\main.asm(413): warning: .cseg .db misalignment - padding zero byte
..\main.asm(414): warning: .cseg .db misalignment - padding zero byte
..\main.asm(415): warning: .cseg .db misalignment - padding zero byte
..\main.asm(416): warning: .cseg .db misalignment - padding zero byte
..\main.asm(417): warning: .cseg .db misalignment - padding zero byte
..\main.asm(418): warning: .cseg .db misalignment - padding zero byte
..\main.asm(435): error: Invalid register
..\main.asm(445): error: Invalid register
..\main.asm(452): error: Invalid register
..\main.asm(454): error: Invalid register
..\main.asm(456): error: Invalid register
..\main.asm(458): error: Invalid register
..\main.asm(461): error: Invalid register
..\main.asm(463): error: Invalid register
..\main.asm(470): error: Invalid register
..\main.asm(480): error: Invalid register
..\main.asm(488): error: Invalid register
..\main.asm(490): error: Invalid register
..\main.asm(514): error: Invalid register
..\main.asm(517): error: Invalid register
..\main.asm(525): error: Invalid register
..\main.asm(527): error: Invalid register
..\main.asm(551): error: Invalid register
..\main.asm(554): error: Invalid register
..\main.asm(583): error: Invalid register
..\main.asm(586): error: Invalid register
..\main.asm(591): error: Invalid register
..\main.asm(594): error: Invalid register
..\main.asm(598): error: Invalid register
..\main.asm(601): error: Invalid register
..\main.asm(605): error: Invalid register
..\main.asm(607): error: Invalid register

Assembly failed, 68 errors, 17 warnings
make: *** [Debug.obj] Error 1

Error code 2

разбирались сидели с преподавателем, он тоже не может понять, почему компилятор ругается на регистры.
Может кто-то увидит ошибку свежим глазом?)
сам проект термостата в архиве, проект под файлом 4. (сохранял в нескольких копиях ввиду нестабильности работы программы.)
Вложения
Новаяпапка(2).rar
(274.43 КиБ) Скачиваний: 0
Последний раз редактировалось MAZBELAZ 09 дек 2014, 22:54, всего редактировалось 1 раз.
MAZBELAZ
 
Сообщения: 2
Зарегистрирован: 09 дек 2014, 20:51

Re: Термостат на Attiny 2313

Сообщение Myp » 09 дек 2014, 22:49

оформи нормально сообщение, используй тег "Code"
<telepathmode>На вопросы отвечает Бригадир Телепатов!</telepathmode>
Всё уже придумано до нас!
Аватара пользователя
Myp
скрытый хозяин вселенной :)
 
Сообщения: 18018
Зарегистрирован: 18 сен 2006, 12:26
Откуда: Тверь по прозвищу Дверь
прог. языки: псевдокод =) сила в алгоритме!
ФИО: глубокоуважаемый Фёдор Анатольевич

Re: Термостат на Attiny 2313

Сообщение MAZBELAZ » 09 дек 2014, 22:56

была найдена частичная проблема, компилятор ругался на команду ldi, которая работает с регистрами 16-31, а у меня команда пыталась работать не с данным диапазоном.
Но теперь проблема в нехватке регистров для переменных)
MAZBELAZ
 
Сообщения: 2
Зарегистрирован: 09 дек 2014, 20:51


Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 19