dynamic indication

This commit is contained in:
Sergey Yarkov 2023-04-20 00:26:54 +03:00
parent a02fb3bcd3
commit 2b1f5bb754
No known key found for this signature in database
GPG Key ID: E91CE1FABC619B6F
9 changed files with 959 additions and 718 deletions

28
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,28 @@
{
"tasks": [
{
"label": "Compile",
"type": "shell",
"group": "build",
"command": "make",
"problemMatcher": []
},
{
"label": "Clean",
"type": "shell",
"group": "build",
"command": "make",
"args": ["clean"],
"problemMatcher": []
},
{
"label": "Flash",
"type": "shell",
"group": "build",
"command": "make",
"args": ["flash"],
"problemMatcher": []
}
],
"version": "2.0.0"
}

50
div16u.asm Normal file
View File

@ -0,0 +1,50 @@
;***************************************************************************
;*
;* "div16u" - 16/16 Bit Unsigned Division
;*
;* This subroutine divides the two 16-bit numbers
;* "dd8uH:dd8uL" (dividend) and "dv16uH:dv16uL" (divisor).
;* The result is placed in "dres16uH:dres16uL" and the remainder in
;* "drem16uH:drem16uL".
;*
;* Number of words :19
;* Number of cycles :235/251 (Min/Max)
;* Low registers used :2 (drem16uL,drem16uH)
;* High registers used :5 (dres16uL/dd16uL,dres16uH/dd16uH,dv16uL,dv16uH,
;* dcnt16u)
;*
;***************************************************************************
;***** Subroutine Register Variables
.def drem16uL=r14
.def drem16uH=r15
.def dres16uL=r16
.def dres16uH=r17
.def dd16uL =r16
.def dd16uH =r17
.def dv16uL =r18
.def dv16uH =r19
.def dcnt16u =r20
;***** Code
div16u: clr drem16uL ;clear remainder Low byte
sub drem16uH,drem16uH;clear remainder High byte and carry
ldi dcnt16u,17 ;init loop counter
d16u_1: rol dd16uL ;shift left dividend
rol dd16uH
dec dcnt16u ;decrement counter
brne d16u_2 ;if done
ret ; return
d16u_2: rol drem16uL ;shift dividend into remainder
rol drem16uH
sub drem16uL,dv16uL ;remainder = remainder - divisor
sbc drem16uH,dv16uH ;
brcc d16u_3 ;if result negative
add drem16uL,dv16uL ; restore remainder
adc drem16uH,dv16uH
clc ; clear carry to be shifted into result
rjmp d16u_1 ;else
d16u_3: sec ; set carry to be shifted into result
rjmp d16u_1

View File

@ -17,10 +17,6 @@
.DEF TEMP_REG_A = r16 .DEF TEMP_REG_A = r16
.DEF TEMP_REG_B = r17 .DEF TEMP_REG_B = r17
;========================================;
; LABELS ;
;========================================;
.EQU DIGIT_1_PIN = PD2 .EQU DIGIT_1_PIN = PD2
.EQU DIGIT_2_PIN = PD3 .EQU DIGIT_2_PIN = PD3
.EQU DIGIT_3_PIN = PD4 .EQU DIGIT_3_PIN = PD4
@ -32,201 +28,182 @@
.EQU USI_DO_PIN = PB6 ; DS on 74HC595 .EQU USI_DO_PIN = PB6 ; DS on 74HC595
.EQU USI_CLK_PIN = PB7 ; SH_CP on 74HC595 .EQU USI_CLK_PIN = PB7 ; SH_CP on 74HC595
.EQU MCU_STATE_DEFAULT = 0x01 ; Temperature measurement and threshold comparison .EQU MCU_STATE_DEFAULT = 0x01 ; Режим измерения температуры и сравнения с заданными параметрами
.EQU MCU_STATE_PROGRAM = 0x02 ; Write settings of hysteresis into EEPROM .EQU MCU_STATE_PROGRAM = 0x02 ; Режим настройки параметров в EEPROM
.EQU MCU_STATE_ERROR = 0x03 ; Cannot read data from temp sensor or something else .EQU MCU_STATE_ERROR = 0x03 ; Режим ошибки, например когда не подключен датчик
;========================================; ; **** СЕГМЕНТ ДАННЫХ ********************************************
; DATA SEGMENT ;
;========================================;
.DSEG .DSEG
.ORG SRAM_START .ORG SRAM_START
MCU_STATE: .BYTE 1 MCU_STATE: .BYTE 1 ; Текущее состояние МК
DISPLAY_DIGIT: .BYTE 4 NUMBER: .BYTE 2
DIGITS: .BYTE 4 ; Ячейки, где хранятся символы, для вывода на индикатор
;========================================; CURRENT_DIGIT: .BYTE 1 ; Номер разряда индикатора, который сейчас горит
; CODE SEGMENT ;
;========================================;
; **** СЕГМЕНТ КОДА **********************************************
.CSEG .CSEG
.ORG 0x00 .ORG 0x00
rjmp RESET_vect
;========================================; .ORG 0x000D
; VECTORS ; rjmp TIMER0_COMPA_vect
;========================================;
rjmp RESET_vect ; Program start at RESET vector ; **** ДИНАМИЧЕСКАЯ ИНДИКАЦИЯ ************************************
;reti ; External Interrupt Request 0 / inactive TIMER0_COMPA_vect:
;reti ; External Interrupt Request 1 / inactive lds r20, CURRENT_DIGIT
;reti ; Timer/Counter1 Capture Event / inactive cpi r20, 5
;reti ; Timer/Counter1 Compare Match A / inactive brge reset_digit_idx
;reti ; Timer/Counter1 Overflow / inactive rjmp _indicate_1
;reti ; Timer/Counter0 Overflow / inactive
;reti ; USART0, Rx Complete / inactive reset_digit_idx:
;reti ; USART0 Data Register Empty / inactive clr r20
;reti ; USART0, Tx Complete / inactive sts CURRENT_DIGIT, r20
;reti ; Analog Comparator / inactive
;reti ; Pin Change Interrupt Request 0/ inactive _indicate_1:
;reti ; Timer/Counter1 Compare Match B / inactive cpi r20, 0
;reti ; Timer/Counter0 Compare Match A / inactive brne _indicate_2
;reti ; Timer/Counter0 Compare Match B / inactive
;reti ; USI Start Condition/ inactive cbi PORTD, DIGIT_2_PIN
;reti ; USI Overflow / inactive cbi PORTD, DIGIT_3_PIN
;reti ; EEPROM Ready/ inactive cbi PORTD, DIGIT_4_PIN
;reti ; Watchdog Timer Overflow / inactive sbi PORTD, DIGIT_1_PIN
;reti ; Pin Change Interrupt Request 1 / inactive lds TEMP_REG_A, DIGITS+3
;reti ; Pin Change Interrupt Request 2 / inactive rcall DISPLAY_DECODER
rcall USI_TRANSMIT
_indicate_2:
cpi r20, 1
brne _indicate_3
cbi PORTD, DIGIT_1_PIN
cbi PORTD, DIGIT_3_PIN
cbi PORTD, DIGIT_4_PIN
sbi PORTD, DIGIT_2_PIN
lds TEMP_REG_A, DIGITS+2
rcall DISPLAY_DECODER
rcall USI_TRANSMIT
_indicate_3:
cpi r20, 2
brne _indicate_4
cbi PORTD, DIGIT_1_PIN
cbi PORTD, DIGIT_2_PIN
cbi PORTD, DIGIT_4_PIN
sbi PORTD, DIGIT_3_PIN
lds TEMP_REG_A, DIGITS+1
rcall DISPLAY_DECODER
rcall USI_TRANSMIT
_indicate_4:
cpi r20, 3
brne _indicate_exit
cbi PORTD, DIGIT_1_PIN
cbi PORTD, DIGIT_2_PIN
cbi PORTD, DIGIT_3_PIN
sbi PORTD, DIGIT_4_PIN
lds TEMP_REG_A, DIGITS
rcall DISPLAY_DECODER
rcall USI_TRANSMIT
_indicate_exit:
inc r20
sts CURRENT_DIGIT, r20
reti
RESET_vect: RESET_vect:
;========================================;
; INITIALIZE STACK POINTER ;
;========================================;
ldi TEMP_REG_A, LOW(RAMEND) ldi TEMP_REG_A, LOW(RAMEND)
out SPL, TEMP_REG_A out SPL, TEMP_REG_A
MCU_INIT: MCU_INIT:
;=======================================================; ; **** ИНИЦИАЛИЗАЦИЯ ПОРТОВ ************************************
; INITIALIZE PORTS ;
; ;
; POWER LED <-------------> OUT PD6 ;
; - This LED is used to indicate that device ;
; is working correctly ;
; 7SEG DIGIT 1 <-------------> OUT PD2 ;
; 7SEG DIGIT 2 <-------------> OUT PD3 ;
; 7SEG DIGIT 3 <-------------> OUT PD4 ;
; 7SEG DIGIT 4 <-------------> OUT PD5 ;
; ;
; USI CLOCK PIN <-------------> OUT PB0 ;
; USI DATA OUT PIN <-------------> OUT PB6 ;
; USI LATCH PIN <-------------> OUT PB7 ;
;=======================================================;
ldi r16, (1<<LED_POWER_PIN) | (1<<DIGIT_1_PIN) | (1<<DIGIT_2_PIN) | (1<<DIGIT_3_PIN) | (1<<DIGIT_4_PIN) ldi r16, (1<<LED_POWER_PIN) | (1<<DIGIT_1_PIN) | (1<<DIGIT_2_PIN) | (1<<DIGIT_3_PIN) | (1<<DIGIT_4_PIN)
out DDRD, r16 out DDRD, r16
ldi r16, (1<<USI_CLK_PIN) | (1<<USI_DO_PIN) | (1<<USI_LATCH_PIN) ldi r16, (1<<USI_CLK_PIN) | (1<<USI_DO_PIN) | (1<<USI_LATCH_PIN) | (1<<PB2)
out DDRB, r16 out DDRB, r16
; sbi PORTD, PD2
; sbi PORTD, PD3
; sbi PORTD, PD4
; sbi PORTD, PD5
ldi TEMP_REG_A, 1 ; **** ИНИЦИАЛИЗАЦИЯ ТАЙМЕРОВ **********************************
sts DISPLAY_DIGIT, TEMP_REG_A ldi r16, (1<<COM0A0) | (1<<WGM01)
out TCCR0A, r16
ldi TEMP_REG_A, 1 ldi r16, (1<<CS02) | (1<<CS00)
sts DISPLAY_DIGIT+1, TEMP_REG_A out TCCR0B, r16
ldi TEMP_REG_A, 9 ldi r16, 40
sts DISPLAY_DIGIT+2, TEMP_REG_A out OCR0A, r16
ldi TEMP_REG_A, 1 ldi r16, (1<<OCIE0A)
sts DISPLAY_DIGIT+3, TEMP_REG_A out TIMSK, r16
clr r1 clr r1
ldi ZL,LOW(2*DISPLAY_SYMBOLS) ldi ZL,LOW(2*DISPLAY_SYMBOLS)
ldi ZH,HIGH(2*DISPLAY_SYMBOLS) ldi ZH,HIGH(2*DISPLAY_SYMBOLS)
; загружаем число, которое нужно показать на индикатор
.EQU DISPLAY_NUMBER = 279
ldi r22, LOW(DISPLAY_NUMBER)
ldi r23, HIGH(DISPLAY_NUMBER)
sts CURRENT_DIGIT, r1
sei
rjmp LOOP rjmp LOOP
;=START================================================================================================; ; **** ПОДПРОГРАММЫ **********************************************
; Transmit byte into 74HC595 using USI .INCLUDE "div16u.asm"
;======================================================================================================; .INCLUDE "usi.asm"
USI_TRANSMIT:
out USIDR, r0 ; Move byte from temp register to USI Data Register
; Enable USI Overflow Interrupt Flag (will be 0 if transfer is not compeleted)
ldi TEMP_REG_A, (1<<USIOIF)
out USISR, TEMP_REG_A
; Load settings of USI into temp register
; This will setup USI to Three-wire mode, Software clock strobe (USITC)
; with External, positive edge and toggle USCK
;
; USIWM0 <--------------> USI Wire Mode
; USICS1 <--------------> USI Clock Source Select
; USICLK <--------------> USI Clock Strobe
; USITC <--------------> USI Toggle Clock (Enable clock generation)
ldi TEMP_REG_A, (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC)
_USI_TRANSMIT_LOOP: ; Execute loop when USIOIF is 0
out USICR, TEMP_REG_A ; Load settings from temp register into USI Control Register
sbis USISR, USIOIF ; If transfer is comleted then move out of loop
rjmp _USI_TRANSMIT_LOOP
; Send pulse into LATCH pin.
; This will copy byte from 74hc595 shift register into 74hc595 storage register
sbi PORTB, USI_LATCH_PIN
cbi PORTB, USI_LATCH_PIN
ret
;=END==================================================================================================;
; .MACRO DISPLAY_SEND
; ldi TEMP_REG_A, @0
; mov r0, TEMP_REG_A
; rcall USI_TRANSMIT
; .ENDMACRO
;========================================;
; MAIN PROGRAM LOOP ;
;========================================;
; **** ГЛАВНЫЙ ЦИКЛ **********************************************
LOOP: LOOP:
; **** ПОЛУЧЕНИЕ ЦИФР ИЗ 16-ТИ БИТНОГО ЧИСЛА *******************
; Описание: Перемещает цифры числа в соответствующие ячейки памяти в SRAM
; путем деления этого числа несколько раз
GET_DIGITS:
cli
ldi r24, 4 ; максимум 4 цифры, т.к индикатор четырех разрядный
ldi XL, LOW(DIGITS)
ldi XH, HIGH(DIGITS)
.equ dividend_addr = $0060
.equ divisor = 10
; загружаем делимое в адрес SRAM делимого
sts dividend_addr, r22
sts dividend_addr+1, r23
; четыре раза производим деление для получения остатков
DIV_LOOP:
; заполняем нужные регистры
lds dd16uL, dividend_addr
lds dd16uH, dividend_addr+1
ldi dv16uL, LOW(divisor)
ldi dv16uH, HIGH(divisor)
rcall div16u ; делим
st X+, drem16uL ; сохраняем остаток в ячейку по указателю
; обновляем делимое
sts dividend_addr, dres16uL
sts dividend_addr+1, dres16uH
dec r24 ; декрементируем счетчик цикла
brne DIV_LOOP ; делим еще раз если не 0
sei
rcall TOGGLE_POWER_LED rcall TOGGLE_POWER_LED
rcall DISPLAY_INDICATE rcall DELAY
rcall DELAY
; ldi TEMP_REG_B, 10 rcall DELAY
; cp r1, TEMP_REG_B rcall DELAY
; brge RESET_POINTER rcall DELAY
; rjmp DISPLAY_SEND
; RESET_POINTER:
; clr r1
; ldi ZL,LOW(2*DISPLAY_SYMBOLS)
; ldi ZH,HIGH(2*DISPLAY_SYMBOLS)
; DISPLAY_SEND:
; lpm
; adiw Z, 1
; inc r1
; rcall USI_TRANSMIT
; rcall DELAY
; rcall DELAY
; rcall DELAY
; rcall DELAY
rjmp LOOP rjmp LOOP
DISPLAY_INDICATE:
sbi PORTD, DIGIT_1_PIN
lds TEMP_REG_A, DISPLAY_DIGIT+3
rcall DISPLAY_DECODER
rcall USI_TRANSMIT
rcall DELAY
cbi PORTD, DIGIT_1_PIN
sbi PORTD, DIGIT_2_PIN
lds TEMP_REG_A, DISPLAY_DIGIT+2
rcall DISPLAY_DECODER
rcall USI_TRANSMIT
rcall DELAY
cbi PORTD, DIGIT_2_PIN
sbi PORTD, DIGIT_3_PIN
lds TEMP_REG_A, DISPLAY_DIGIT+1
rcall DISPLAY_DECODER
rcall USI_TRANSMIT
rcall DELAY
cbi PORTD, DIGIT_3_PIN
sbi PORTD, DIGIT_4_PIN
lds TEMP_REG_A, DISPLAY_DIGIT
rcall DISPLAY_DECODER
rcall USI_TRANSMIT
rcall DELAY
cbi PORTD, DIGIT_4_PIN
ret
DISPLAY_DECODER: DISPLAY_DECODER:
ldi ZL, LOW(2*DISPLAY_SYMBOLS) ldi ZL, LOW(2*DISPLAY_SYMBOLS)
ldi ZH, HIGH(2*DISPLAY_SYMBOLS) ldi ZH, HIGH(2*DISPLAY_SYMBOLS)
@ -241,8 +218,7 @@ ret
DELAY: DELAY:
push r16 push r16
push r17 push r17
cli ldi r16, 255
ldi r16, 50
_DELAY_1: _DELAY_1:
ldi r17, 255 ldi r17, 255
_DELAY_2: _DELAY_2:
@ -254,17 +230,20 @@ DELAY:
dec r16 dec r16
brne _DELAY_1 brne _DELAY_1
sei
pop r17 pop r17
pop r16 pop r16
ret ret
TOGGLE_POWER_LED: TOGGLE_POWER_LED:
push r16
push r17
ldi r16, (1<<LED_POWER_PIN) ldi r16, (1<<LED_POWER_PIN)
in r17, PORTD in r17, PORTD
eor r17, r16 eor r17, r16
out PORTD, r17 out PORTD, r17
pop r17
pop r16
ret ret
DISPLAY_SYMBOLS: DISPLAY_SYMBOLS:
@ -275,9 +254,6 @@ DISPLAY_SYMBOLS:
.DB 0b10000010, 0b11111000 ; 6, 7 .DB 0b10000010, 0b11111000 ; 6, 7
.DB 0b10000000, 0b10010000 ; 8, 9 .DB 0b10000000, 0b10010000 ; 8, 9
;========================================; ; **** СЕГМЕНТ EEPROM ********************************************
; EEPROM SEGMENT ; ; .ESEG
;========================================; ; INFO: .DB "AVR Thermostat. Written by Sergey Yarkov 22.01.2023"
.ESEG
INFO: .DB "AVR Thermostat. Written by Sergey Yarkov 22.01.2023"

View File

@ -1,5 +0,0 @@
:1000000041565220544845524D4F535441542E208E
:100010005752495454454E20425920534552474562
:1000200059205941524B4F562032322E30312E3208
:0300300030323338
:00000001FF

View File

@ -1,15 +1,25 @@
:020000020000FC :020000020000FC
:1000000000C00FED0DBF0CE701BB01EC07BB01E029 :0200000041C0FD
:100010000093610001E00093620009E00093630037 :10001A0000C04091670045300CF403C04427409368
:1000200001E0009364001124EAEBF0E00AC00FB88D :10002A006700403041F4939894989598929A009179
:1000300000E40EB90BE10DB9769BFDCFC09AC098D4 :10003A00660075D04CD0413041F4929894989598C6
:10004000089536D001D0FDCF929A0091640019D066 :10004A00939A009165006BD042D0423041F4929865
:10005000EEDF1ED09298939A0091630012D0E7DFF2 :10005A0093989598949A0091640061D038D043306F
:1000600017D09398949A009162000BD0E0DF10D0E3 :10006A0041F4929893989498959A0091630057D086
:100070009498959A0091610004D0D9DF09D09598A1 :10007A002ED043954093670018950FED0DBF0CE7FE
:100080000895EAEBF0E010E0E00FF11FC895089545 :10008A0001BB05EC07BB02E400BF05E003BF08E2C1
:100090000F931F93F89402E31FEF1A9500000000DE :10009A0006BF01E009BF1124E4E6F1E067E171E07F
:1000A0000000D9F70A95C1F778941F910F91089530 :1000AA001092670078941DC0EE24FF1841E1001FEA
:1000B00000E412B3102712BB0895C0F9A4B09992BE :1000BA00111F4A9509F40895EE1CFF1CE21AF30A6F
:0400C00082F88090B2 :1000CA0020F4E20EF31E8894F2CF0894F0CF0FB812
:1000DA0000E40EB90BE10DB9769BFDCFC09AC0982A
:1000EA000895F89484E0A3E6B0E06093600070930A
:1000FA00610000916000109161002AE030E0D4DFD5
:10010A00ED9200936000109361008A9591F77894BC
:10011A001BD00CD00BD00AD009D008D0E2CFE4E62D
:10012A00F1E010E0E00FF11FC89508950F931F93B7
:10013A000FEF1FEF1A95000000000000D9F70A958B
:10014A00C1F71F910F9108950F931F9300E412B303
:10015A00102712BB1F910F910895C0F9A4B099926C
:04016A0082F8809007
:00000001FF :00000001FF

View File

@ -1,8 +1,20 @@
AVRASM ver. 2.2.7 firmware.asm Thu Apr 06 18:29:19 2023 AVRASM ver. 2.2.7 firmware.asm Thu Apr 20 00:26:30 2023
firmware.asm(14): Including file 'tn2313Adef.inc' firmware.asm(14): Including file 'tn2313Adef.inc'
firmware.asm(157): Including file 'div16u.asm'
div16u.asm(22): warning: Register r16 already defined by the .DEF directive
firmware.asm(157): 'div16u.asm' included form here
div16u.asm(23): warning: Register r17 already defined by the .DEF directive
firmware.asm(157): 'div16u.asm' included form here
div16u.asm(24): warning: Register r16 already defined by the .DEF directive
firmware.asm(157): 'div16u.asm' included form here
div16u.asm(25): warning: Register r17 already defined by the .DEF directive
firmware.asm(157): 'div16u.asm' included form here
firmware.asm(158): Including file 'usi.asm'
firmware.asm(14): Including file 'tn2313Adef.inc' firmware.asm(14): Including file 'tn2313Adef.inc'
firmware.asm(157): Including file 'div16u.asm'
firmware.asm(158): Including file 'usi.asm'
; Project name: thermostat ; Project name: thermostat
@ -721,10 +733,6 @@ firmware.asm(14): Including file 'tn2313Adef.inc'
.DEF TEMP_REG_A = r16 .DEF TEMP_REG_A = r16
.DEF TEMP_REG_B = r17 .DEF TEMP_REG_B = r17
;========================================;
; LABELS ;
;========================================;
.EQU DIGIT_1_PIN = PD2 .EQU DIGIT_1_PIN = PD2
.EQU DIGIT_2_PIN = PD3 .EQU DIGIT_2_PIN = PD3
.EQU DIGIT_3_PIN = PD4 .EQU DIGIT_3_PIN = PD4
@ -736,111 +744,190 @@ firmware.asm(14): Including file 'tn2313Adef.inc'
.EQU USI_DO_PIN = PB6 ; DS on 74HC595 .EQU USI_DO_PIN = PB6 ; DS on 74HC595
.EQU USI_CLK_PIN = PB7 ; SH_CP on 74HC595 .EQU USI_CLK_PIN = PB7 ; SH_CP on 74HC595
.EQU MCU_STATE_DEFAULT = 0x01 ; Temperature measurement and threshold comparison .EQU MCU_STATE_DEFAULT = 0x01 ; Режим измерения температуры и сравнения с заданными параметрами
.EQU MCU_STATE_PROGRAM = 0x02 ; Write settings of hysteresis into EEPROM .EQU MCU_STATE_PROGRAM = 0x02 ; Режим настройки параметров в EEPROM
.EQU MCU_STATE_ERROR = 0x03 ; Cannot read data from temp sensor or something else .EQU MCU_STATE_ERROR = 0x03 ; Режим ошибки, например когда не подключен датчик
;========================================; ; **** СЕГМЕНТ ДАННЫХ ********************************************
; DATA SEGMENT ;
;========================================;
.DSEG .DSEG
.ORG SRAM_START .ORG SRAM_START
000060 MCU_STATE: .BYTE 1 000060 MCU_STATE: .BYTE 1 ; Текущее состояние МК
000061 DISPLAY_DIGIT: .BYTE 4 000061 NUMBER: .BYTE 2
000063 DIGITS: .BYTE 4 ; Ячейки, где хранятся символы, для вывода на индикатор
;========================================; 000067 CURRENT_DIGIT: .BYTE 1 ; Номер разряда индикатора, который сейчас горит
; CODE SEGMENT ;
;========================================;
; **** СЕГМЕНТ КОДА **********************************************
.CSEG .CSEG
.ORG 0x00 .ORG 0x00
000000 c041 rjmp RESET_vect
;========================================; .ORG 0x000D
; VECTORS ; 00000d c000 rjmp TIMER0_COMPA_vect
;========================================;
000000 c000 rjmp RESET_vect ; Program start at RESET vector ; **** ДИНАМИЧЕСКАЯ ИНДИКАЦИЯ ************************************
;reti ; External Interrupt Request 0 / inactive TIMER0_COMPA_vect:
;reti ; External Interrupt Request 1 / inactive 00000e 9140 0067 lds r20, CURRENT_DIGIT
;reti ; Timer/Counter1 Capture Event / inactive 000010 3045 cpi r20, 5
;reti ; Timer/Counter1 Compare Match A / inactive 000011 f40c brge reset_digit_idx
;reti ; Timer/Counter1 Overflow / inactive 000012 c003 rjmp _indicate_1
;reti ; Timer/Counter0 Overflow / inactive
;reti ; USART0, Rx Complete / inactive reset_digit_idx:
;reti ; USART0 Data Register Empty / inactive 000013 2744 clr r20
;reti ; USART0, Tx Complete / inactive 000014 9340 0067 sts CURRENT_DIGIT, r20
;reti ; Analog Comparator / inactive
;reti ; Pin Change Interrupt Request 0/ inactive _indicate_1:
;reti ; Timer/Counter1 Compare Match B / inactive 000016 3040 cpi r20, 0
;reti ; Timer/Counter0 Compare Match A / inactive 000017 f441 brne _indicate_2
;reti ; Timer/Counter0 Compare Match B / inactive
;reti ; USI Start Condition/ inactive 000018 9893 cbi PORTD, DIGIT_2_PIN
;reti ; USI Overflow / inactive 000019 9894 cbi PORTD, DIGIT_3_PIN
;reti ; EEPROM Ready/ inactive 00001a 9895 cbi PORTD, DIGIT_4_PIN
;reti ; Watchdog Timer Overflow / inactive 00001b 9a92 sbi PORTD, DIGIT_1_PIN
;reti ; Pin Change Interrupt Request 1 / inactive 00001c 9100 0066 lds TEMP_REG_A, DIGITS+3
;reti ; Pin Change Interrupt Request 2 / inactive 00001e d075 rcall DISPLAY_DECODER
00001f d04c rcall USI_TRANSMIT
_indicate_2:
000020 3041 cpi r20, 1
000021 f441 brne _indicate_3
000022 9892 cbi PORTD, DIGIT_1_PIN
000023 9894 cbi PORTD, DIGIT_3_PIN
000024 9895 cbi PORTD, DIGIT_4_PIN
000025 9a93 sbi PORTD, DIGIT_2_PIN
000026 9100 0065 lds TEMP_REG_A, DIGITS+2
000028 d06b rcall DISPLAY_DECODER
000029 d042 rcall USI_TRANSMIT
_indicate_3:
00002a 3042 cpi r20, 2
00002b f441 brne _indicate_4
00002c 9892 cbi PORTD, DIGIT_1_PIN
00002d 9893 cbi PORTD, DIGIT_2_PIN
00002e 9895 cbi PORTD, DIGIT_4_PIN
00002f 9a94 sbi PORTD, DIGIT_3_PIN
000030 9100 0064 lds TEMP_REG_A, DIGITS+1
000032 d061 rcall DISPLAY_DECODER
000033 d038 rcall USI_TRANSMIT
_indicate_4:
000034 3043 cpi r20, 3
000035 f441 brne _indicate_exit
000036 9892 cbi PORTD, DIGIT_1_PIN
000037 9893 cbi PORTD, DIGIT_2_PIN
000038 9894 cbi PORTD, DIGIT_3_PIN
000039 9a95 sbi PORTD, DIGIT_4_PIN
00003a 9100 0063 lds TEMP_REG_A, DIGITS
00003c d057 rcall DISPLAY_DECODER
00003d d02e rcall USI_TRANSMIT
_indicate_exit:
00003e 9543 inc r20
00003f 9340 0067 sts CURRENT_DIGIT, r20
000041 9518 reti
RESET_vect: RESET_vect:
;========================================; 000042 ed0f ldi TEMP_REG_A, LOW(RAMEND)
; INITIALIZE STACK POINTER ; 000043 bf0d out SPL, TEMP_REG_A
;========================================;
000001 ed0f ldi TEMP_REG_A, LOW(RAMEND)
000002 bf0d out SPL, TEMP_REG_A
MCU_INIT: MCU_INIT:
;=======================================================; ; **** ИНИЦИАЛИЗАЦИЯ ПОРТОВ ************************************
; INITIALIZE PORTS ; 000044 e70c ldi r16, (1<<LED_POWER_PIN) | (1<<DIGIT_1_PIN) | (1<<DIGIT_2_PIN) | (1<<DIGIT_3_PIN) | (1<<DIGIT_4_PIN)
; ; 000045 bb01 out DDRD, r16
; POWER LED <-------------> OUT PD6 ; 000046 ec05 ldi r16, (1<<USI_CLK_PIN) | (1<<USI_DO_PIN) | (1<<USI_LATCH_PIN) | (1<<PB2)
; - This LED is used to indicate that device ; 000047 bb07 out DDRB, r16
; is working correctly ;
; 7SEG DIGIT 1 <-------------> OUT PD2 ;
; 7SEG DIGIT 2 <-------------> OUT PD3 ;
; 7SEG DIGIT 3 <-------------> OUT PD4 ;
; 7SEG DIGIT 4 <-------------> OUT PD5 ;
; ;
; USI CLOCK PIN <-------------> OUT PB0 ;
; USI DATA OUT PIN <-------------> OUT PB6 ;
; USI LATCH PIN <-------------> OUT PB7 ;
;=======================================================;
000003 e70c ldi r16, (1<<LED_POWER_PIN) | (1<<DIGIT_1_PIN) | (1<<DIGIT_2_PIN) | (1<<DIGIT_3_PIN) | (1<<DIGIT_4_PIN)
000004 bb01 out DDRD, r16
000005 ec01 ldi r16, (1<<USI_CLK_PIN) | (1<<USI_DO_PIN) | (1<<USI_LATCH_PIN)
000006 bb07 out DDRB, r16
; sbi PORTD, PD2
; sbi PORTD, PD3
; sbi PORTD, PD4
; sbi PORTD, PD5
000007 e001 ldi TEMP_REG_A, 1 ; **** ИНИЦИАЛИЗАЦИЯ ТАЙМЕРОВ **********************************
000008 9300 0061 sts DISPLAY_DIGIT, TEMP_REG_A 000048 e402 ldi r16, (1<<COM0A0) | (1<<WGM01)
000049 bf00 out TCCR0A, r16
00000a e001 ldi TEMP_REG_A, 1 00004a e005 ldi r16, (1<<CS02) | (1<<CS00)
00000b 9300 0062 sts DISPLAY_DIGIT+1, TEMP_REG_A 00004b bf03 out TCCR0B, r16
00000d e009 ldi TEMP_REG_A, 9 00004c e208 ldi r16, 40
00000e 9300 0063 sts DISPLAY_DIGIT+2, TEMP_REG_A 00004d bf06 out OCR0A, r16
000010 e001 ldi TEMP_REG_A, 1 00004e e001 ldi r16, (1<<OCIE0A)
000011 9300 0064 sts DISPLAY_DIGIT+3, TEMP_REG_A 00004f bf09 out TIMSK, r16
000013 2411 clr r1 000050 2411 clr r1
000014 ebea ldi ZL,LOW(2*DISPLAY_SYMBOLS) 000051 e6e4 ldi ZL,LOW(2*DISPLAY_SYMBOLS)
000015 e0f0 ldi ZH,HIGH(2*DISPLAY_SYMBOLS) 000052 e0f1 ldi ZH,HIGH(2*DISPLAY_SYMBOLS)
000016 c00a rjmp LOOP ; загружаем число, которое нужно показать на индикатор
.EQU DISPLAY_NUMBER = 279
000053 e167 ldi r22, LOW(DISPLAY_NUMBER)
000054 e071 ldi r23, HIGH(DISPLAY_NUMBER)
;=START================================================================================================; 000055 9210 0067 sts CURRENT_DIGIT, r1
; Transmit byte into 74HC595 using USI
;======================================================================================================; 000057 9478 sei
000058 c01d rjmp LOOP
; **** ПОДПРОГРАММЫ **********************************************
.INCLUDE "div16u.asm"
;*
;* "div16u" - 16/16 Bit Unsigned Division
;*
;* This subroutine divides the two 16-bit numbers
;* "dd8uH:dd8uL" (dividend) and "dv16uH:dv16uL" (divisor).
;* The result is placed in "dres16uH:dres16uL" and the remainder in
;* "drem16uH:drem16uL".
;*
;* Number of words :19
;* Number of cycles :235/251 (Min/Max)
;* Low registers used :2 (drem16uL,drem16uH)
;* High registers used :5 (dres16uL/dd16uL,dres16uH/dd16uH,dv16uL,dv16uH,
;* dcnt16u)
;*
;***************************************************************************
;***** Subroutine Register Variables
.def drem16uL=r14
.def drem16uH=r15
.def dres16uL=r16
.def dres16uH=r17
.def dd16uL =r16
.def dd16uH =r17
.def dv16uL =r18
.def dv16uH =r19
.def dcnt16u =r20
;***** Code
000059 24ee div16u: clr drem16uL ;clear remainder Low byte
00005a 18ff sub drem16uH,drem16uH;clear remainder High byte and carry
00005b e141 ldi dcnt16u,17 ;init loop counter
00005c 1f00 d16u_1: rol dd16uL ;shift left dividend
00005d 1f11 rol dd16uH
00005e 954a dec dcnt16u ;decrement counter
00005f f409 brne d16u_2 ;if done
000060 9508 ret ; return
000061 1cee d16u_2: rol drem16uL ;shift dividend into remainder
000062 1cff rol drem16uH
000063 1ae2 sub drem16uL,dv16uL ;remainder = remainder - divisor
000064 0af3 sbc drem16uH,dv16uH ;
000065 f420 brcc d16u_3 ;if result negative
000066 0ee2 add drem16uL,dv16uL ; restore remainder
000067 1ef3 adc drem16uH,dv16uH
000068 9488 clc ; clear carry to be shifted into result
000069 cff2 rjmp d16u_1 ;else
00006a 9408 d16u_3: sec ; set carry to be shifted into result
.INCLUDE "usi.asm"
00006b cff0
USI_TRANSMIT: USI_TRANSMIT:
000017 b80f out USIDR, r0 ; Move byte from temp register to USI Data Register 00006c b80f out USIDR, r0 ; Move byte from temp register to USI Data Register
; Enable USI Overflow Interrupt Flag (will be 0 if transfer is not compeleted) ; Enable USI Overflow Interrupt Flag (will be 0 if transfer is not compeleted)
000018 e400 ldi TEMP_REG_A, (1<<USIOIF) 00006d e400 ldi TEMP_REG_A, (1<<USIOIF)
000019 b90e out USISR, TEMP_REG_A 00006e b90e out USISR, TEMP_REG_A
; Load settings of USI into temp register ; Load settings of USI into temp register
; This will setup USI to Three-wire mode, Software clock strobe (USITC) ; This will setup USI to Three-wire mode, Software clock strobe (USITC)
@ -850,190 +937,117 @@ firmware.asm(14): Including file 'tn2313Adef.inc'
; USICS1 <--------------> USI Clock Source Select ; USICS1 <--------------> USI Clock Source Select
; USICLK <--------------> USI Clock Strobe ; USICLK <--------------> USI Clock Strobe
; USITC <--------------> USI Toggle Clock (Enable clock generation) ; USITC <--------------> USI Toggle Clock (Enable clock generation)
00001a e10b ldi TEMP_REG_A, (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC) 00006f e10b ldi TEMP_REG_A, (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC)
_USI_TRANSMIT_LOOP: ; Execute loop when USIOIF is 0 _USI_TRANSMIT_LOOP: ; Execute loop when USIOIF is 0
00001b b90d out USICR, TEMP_REG_A ; Load settings from temp register into USI Control Register 000070 b90d out USICR, TEMP_REG_A ; Load settings from temp register into USI Control Register
00001c 9b76 sbis USISR, USIOIF ; If transfer is comleted then move out of loop 000071 9b76 sbis USISR, USIOIF ; If transfer is comleted then move out of loop
00001d cffd rjmp _USI_TRANSMIT_LOOP 000072 cffd rjmp _USI_TRANSMIT_LOOP
; Send pulse into LATCH pin. ; Send pulse into LATCH pin.
; This will copy byte from 74hc595 shift register into 74hc595 storage register ; This will copy byte from 74hc595 shift register into 74hc595 storage register
00001e 9ac0 sbi PORTB, USI_LATCH_PIN 000073 9ac0 sbi PORTB, USI_LATCH_PIN
00001f 98c0 cbi PORTB, USI_LATCH_PIN 000074 98c0 cbi PORTB, USI_LATCH_PIN
000020 9508 ret 000075 9508
;=END==================================================================================================; ; **** ГЛАВНЫЙ ЦИКЛ **********************************************
; .MACRO DISPLAY_SEND
; ldi TEMP_REG_A, @0
; mov r0, TEMP_REG_A
; rcall USI_TRANSMIT
; .ENDMACRO
;========================================;
; MAIN PROGRAM LOOP ;
;========================================;
LOOP: LOOP:
000021 d036 rcall TOGGLE_POWER_LED ; **** ПОЛУЧЕНИЕ ЦИФР ИЗ 16-ТИ БИТНОГО ЧИСЛА *******************
000022 d001 rcall DISPLAY_INDICATE ; Описание: Перемещает цифры числа в соответствующие ячейки памяти в SRAM
; путем деления этого числа несколько раз
GET_DIGITS:
000076 94f8 cli
000077 e084 ldi r24, 4 ; максимум 4 цифры, т.к индикатор четырех разрядный
000078 e6a3 ldi XL, LOW(DIGITS)
000079 e0b0 ldi XH, HIGH(DIGITS)
; ldi TEMP_REG_B, 10 .equ dividend_addr = $0060
; cp r1, TEMP_REG_B .equ divisor = 10
; brge RESET_POINTER
; rjmp DISPLAY_SEND
; RESET_POINTER: ; загружаем делимое в адрес SRAM делимого
; clr r1 00007a 9360 0060 sts dividend_addr, r22
; ldi ZL,LOW(2*DISPLAY_SYMBOLS) 00007c 9370 0061 sts dividend_addr+1, r23
; ldi ZH,HIGH(2*DISPLAY_SYMBOLS)
; DISPLAY_SEND: ; четыре раза производим деление для получения остатков
; lpm DIV_LOOP:
; adiw Z, 1 ; заполняем нужные регистры
; inc r1 00007e 9100 0060 lds dd16uL, dividend_addr
; rcall USI_TRANSMIT 000080 9110 0061 lds dd16uH, dividend_addr+1
000082 e02a ldi dv16uL, LOW(divisor)
000083 e030 ldi dv16uH, HIGH(divisor)
; rcall DELAY 000084 dfd4 rcall div16u ; делим
; rcall DELAY
; rcall DELAY
; rcall DELAY
000023 cffd rjmp LOOP 000085 92ed st X+, drem16uL ; сохраняем остаток в ячейку по указателю
DISPLAY_INDICATE: ; обновляем делимое
000024 9a92 sbi PORTD, DIGIT_1_PIN 000086 9300 0060 sts dividend_addr, dres16uL
000025 9100 0064 lds TEMP_REG_A, DISPLAY_DIGIT+3 000088 9310 0061 sts dividend_addr+1, dres16uH
000027 d019 rcall DISPLAY_DECODER
000028 dfee rcall USI_TRANSMIT
000029 d01e rcall DELAY
00002a 9892 cbi PORTD, DIGIT_1_PIN
00002b 9a93 sbi PORTD, DIGIT_2_PIN 00008a 958a dec r24 ; декрементируем счетчик цикла
00002c 9100 0063 lds TEMP_REG_A, DISPLAY_DIGIT+2 00008b f791 brne DIV_LOOP ; делим еще раз если не 0
00002e d012 rcall DISPLAY_DECODER 00008c 9478 sei
00002f dfe7 rcall USI_TRANSMIT
000030 d017 rcall DELAY
000031 9893 cbi PORTD, DIGIT_2_PIN
000032 9a94 sbi PORTD, DIGIT_3_PIN 00008d d01b rcall TOGGLE_POWER_LED
000033 9100 0062 lds TEMP_REG_A, DISPLAY_DIGIT+1 00008e d00c rcall DELAY
000035 d00b rcall DISPLAY_DECODER 00008f d00b rcall DELAY
000036 dfe0 rcall USI_TRANSMIT 000090 d00a rcall DELAY
000037 d010 rcall DELAY 000091 d009 rcall DELAY
000038 9894 cbi PORTD, DIGIT_3_PIN 000092 d008 rcall DELAY
000039 9a95 sbi PORTD, DIGIT_4_PIN 000093 cfe2 rjmp LOOP
00003a 9100 0061 lds TEMP_REG_A, DISPLAY_DIGIT
00003c d004 rcall DISPLAY_DECODER
00003d dfd9 rcall USI_TRANSMIT
00003e d009 rcall DELAY
00003f 9895 cbi PORTD, DIGIT_4_PIN
000040 9508 ret
DISPLAY_DECODER: DISPLAY_DECODER:
000041 ebea ldi ZL, LOW(2*DISPLAY_SYMBOLS) 000094 e6e4 ldi ZL, LOW(2*DISPLAY_SYMBOLS)
000042 e0f0 ldi ZH, HIGH(2*DISPLAY_SYMBOLS) 000095 e0f1 ldi ZH, HIGH(2*DISPLAY_SYMBOLS)
000043 e010 ldi TEMP_REG_B, 0 000096 e010 ldi TEMP_REG_B, 0
000044 0fe0 add ZL, TEMP_REG_A 000097 0fe0 add ZL, TEMP_REG_A
000045 1ff1 adc ZH, TEMP_REG_B 000098 1ff1 adc ZH, TEMP_REG_B
000046 95c8 lpm 000099 95c8 lpm
000047 9508 ret 00009a 9508 ret
DELAY: DELAY:
000048 930f push r16 00009b 930f push r16
000049 931f push r17 00009c 931f push r17
00004a 94f8 cli 00009d ef0f ldi r16, 255
00004b e302 ldi r16, 50
_DELAY_1: _DELAY_1:
00004c ef1f ldi r17, 255 00009e ef1f ldi r17, 255
_DELAY_2: _DELAY_2:
00004d 951a dec r17 00009f 951a dec r17
00004e 0000 nop 0000a0 0000 nop
00004f 0000 nop 0000a1 0000 nop
000050 0000 nop 0000a2 0000 nop
000051 f7d9 brne _DELAY_2 0000a3 f7d9 brne _DELAY_2
000052 950a dec r16 0000a4 950a dec r16
000053 f7c1 brne _DELAY_1 0000a5 f7c1 brne _DELAY_1
000054 9478 sei
000055 911f pop r17 0000a6 911f pop r17
000056 910f pop r16 0000a7 910f pop r16
000057 9508 ret 0000a8 9508 ret
TOGGLE_POWER_LED: TOGGLE_POWER_LED:
000058 e400 ldi r16, (1<<LED_POWER_PIN) 0000a9 930f push r16
000059 b312 in r17, PORTD 0000aa 931f push r17
00005a 2710 eor r17, r16 0000ab e400 ldi r16, (1<<LED_POWER_PIN)
00005b bb12 out PORTD, r17 0000ac b312 in r17, PORTD
00005c 9508 ret 0000ad 2710 eor r17, r16
0000ae bb12 out PORTD, r17
0000af 911f pop r17
0000b0 910f pop r16
0000b1 9508 ret
DISPLAY_SYMBOLS: DISPLAY_SYMBOLS:
; HGFEDCBA HGFEDCBA ; HGFEDCBA HGFEDCBA
00005d f9c0 .DB 0b11000000, 0b11111001 ; 0, 1 0000b2 f9c0 .DB 0b11000000, 0b11111001 ; 0, 1
00005e b0a4 .DB 0b10100100, 0b10110000 ; 2, 3 0000b3 b0a4 .DB 0b10100100, 0b10110000 ; 2, 3
00005f 9299 .DB 0b10011001, 0b10010010 ; 4, 5 0000b4 9299 .DB 0b10011001, 0b10010010 ; 4, 5
000060 f882 .DB 0b10000010, 0b11111000 ; 6, 7 0000b5 f882 .DB 0b10000010, 0b11111000 ; 6, 7
000061 9080 .DB 0b10000000, 0b10010000 ; 8, 9 0000b6 9080 .DB 0b10000000, 0b10010000 ; 8, 9
;========================================; ; **** СЕГМЕНТ EEPROM ********************************************
; EEPROM SEGMENT ; ; .ESEG
;========================================;
.ESEG
000000 41
000001 56
000002 52
000003 20
000004 54
000005 68
000006 65
000007 72
000008 6d
000009 6f
00000a 73
00000b 74
00000c 61
00000d 74
00000e 2e
00000f 20
000010 57
000011 72
000012 69
000013 74
000014 74
000015 65
000016 6e
000017 20
000018 62
000019 79
00001a 20
00001b 53
00001c 65
00001d 72
00001e 67
00001f 65
000020 79
000021 20
000022 59
000023 61
000024 72
000025 6b
000026 6f
000027 76
000028 20
000029 32
00002a 32
00002b 2e
00002c 30
00002d 31
00002e 2e
00002f 32
000030 30
000031 32
RESOURCE USE INFORMATION RESOURCE USE INFORMATION
@ -1051,39 +1065,39 @@ counted separately from r26..r31 here.
.dseg memory usage only counts static data declared with .byte .dseg memory usage only counts static data declared with .byte
"ATtiny2313A" register use summary: "ATtiny2313A" register use summary:
x : 0 y : 0 z : 0 r0 : 1 r1 : 1 r2 : 0 r3 : 0 r4 : 0 x : 1 y : 0 z : 0 r0 : 1 r1 : 2 r2 : 0 r3 : 0 r4 : 0
r5 : 0 r6 : 0 r7 : 0 r8 : 0 r9 : 0 r10: 0 r11: 0 r12: 0 r5 : 0 r6 : 0 r7 : 0 r8 : 0 r9 : 0 r10: 0 r11: 0 r12: 0
r13: 0 r14: 0 r15: 0 r16: 29 r17: 9 r18: 0 r19: 0 r20: 0 r13: 0 r14: 5 r15: 5 r16: 34 r17: 14 r18: 3 r19: 3 r20: 12
r21: 0 r22: 0 r23: 0 r24: 0 r25: 0 r26: 0 r27: 0 r28: 0 r21: 0 r22: 2 r23: 2 r24: 2 r25: 0 r26: 1 r27: 1 r28: 0
r29: 0 r30: 3 r31: 3 r29: 0 r30: 3 r31: 3
Registers used: 6 out of 35 (17.1%) Registers used: 17 out of 35 (48.6%)
"ATtiny2313A" instruction use summary: "ATtiny2313A" instruction use summary:
.lds : 0 .sts : 0 adc : 1 add : 1 adiw : 0 and : 0 .lds : 0 .sts : 0 adc : 2 add : 2 adiw : 0 and : 0
andi : 0 asr : 0 bclr : 0 bld : 0 brbc : 0 brbs : 0 andi : 0 asr : 0 bclr : 0 bld : 0 brbc : 0 brbs : 0
brcc : 0 brcs : 0 break : 0 breq : 0 brge : 0 brhc : 0 brcc : 1 brcs : 0 break : 0 breq : 0 brge : 1 brhc : 0
brhs : 0 brid : 0 brie : 0 brlo : 0 brlt : 0 brmi : 0 brhs : 0 brid : 0 brie : 0 brlo : 0 brlt : 0 brmi : 0
brne : 2 brpl : 0 brsh : 0 brtc : 0 brts : 0 brvc : 0 brne : 8 brpl : 0 brsh : 0 brtc : 0 brts : 0 brvc : 0
brvs : 0 bset : 0 bst : 0 cbi : 5 cbr : 0 clc : 0 brvs : 0 bset : 0 bst : 0 cbi : 13 cbr : 0 clc : 1
clh : 0 cli : 1 cln : 0 clr : 1 cls : 0 clt : 0 clh : 0 cli : 1 cln : 0 clr : 3 cls : 0 clt : 0
clv : 0 clz : 0 com : 0 cp : 0 cpc : 0 cpi : 0 clv : 0 clz : 0 com : 0 cp : 0 cpc : 0 cpi : 5
cpse : 0 dec : 2 eor : 1 icall : 0 ijmp : 0 in : 1 cpse : 0 dec : 4 eor : 1 icall : 0 ijmp : 0 in : 1
inc : 0 ld : 0 ldd : 0 ldi : 17 lds : 4 lpm : 3 inc : 1 ld : 0 ldd : 0 ldi : 25 lds : 7 lpm : 3
lsl : 0 lsr : 0 mov : 0 movw : 0 neg : 0 nop : 3 lsl : 0 lsr : 0 mov : 0 movw : 0 neg : 0 nop : 3
or : 0 ori : 0 out : 7 pop : 2 push : 2 rcall : 14 or : 0 ori : 0 out : 11 pop : 4 push : 4 rcall : 15
ret : 5 reti : 0 rjmp : 4 rol : 0 ror : 0 sbc : 0 ret : 5 reti : 1 rjmp : 8 rol : 4 ror : 0 sbc : 1
sbci : 0 sbi : 5 sbic : 0 sbis : 1 sbiw : 0 sbr : 0 sbci : 0 sbi : 5 sbic : 0 sbis : 1 sbiw : 0 sbr : 0
sbrc : 0 sbrs : 0 sec : 0 seh : 0 sei : 1 sen : 0 sbrc : 0 sbrs : 0 sec : 1 seh : 0 sei : 2 sen : 0
ser : 0 ses : 0 set : 0 sev : 0 sez : 0 sleep : 0 ser : 0 ses : 0 set : 0 sev : 0 sez : 0 sleep : 0
spm : 0 st : 0 std : 0 sts : 4 sub : 0 subi : 0 spm : 0 st : 1 std : 0 sts : 7 sub : 2 subi : 0
swap : 0 tst : 0 wdr : 0 swap : 0 tst : 0 wdr : 0
Instructions used: 23 out of 105 (21.9%) Instructions used: 34 out of 105 (32.4%)
"ATtiny2313A" memory use summary [bytes]: "ATtiny2313A" memory use summary [bytes]:
Segment Begin End Code Data Used Size Use% Segment Begin End Code Data Used Size Use%
--------------------------------------------------------------- ---------------------------------------------------------------
[.cseg] 0x000000 0x0000c4 186 10 196 2048 9.6% [.cseg] 0x000000 0x00016e 332 10 342 2048 16.7%
[.dseg] 0x000060 0x000065 0 5 5 128 3.9% [.dseg] 0x000060 0x000068 0 8 8 128 6.3%
[.eseg] 0x000000 0x000033 0 51 51 128 39.8% [.eseg] 0x000000 0x000000 0 0 0 128 0.0%
Assembly complete, 0 errors, 0 warnings Assembly complete, 0 errors, 4 warnings

View File

@ -1,11 +1,11 @@
gavrasm Gerd's AVR assembler version 5.4 (C)2022 by DG4FAC gavrasm Gerd's AVR assembler version 5.4 (C)2022 by DG4FAC
---------------------------------------------------------- ----------------------------------------------------------
Path: /home/sergeyyarkov/Documents/Applications/attiny2313a_thermostat/ Path: /home/sergeyyarkov/Documents/Projects/Firmwares/AVR/attiny2313a_thermostat/
Source file: firmware.asm Source file: firmware.asm
Hex file: firmware.hex Hex file: firmware.hex
Eeprom file: firmware.eep Eeprom file: firmware.eep
Compiled: 25.02.2023, 10:41:03 Compiled: 20.04.2023, 00:25:25
Pass: 2 Pass: 2
1: ; 1: ;
@ -23,284 +23,422 @@ Pass: 2
13: 13:
14: .INCLUDE "tn2313Adef.inc" 14: .INCLUDE "tn2313Adef.inc"
-> Warning 009: Include defs not necessary, using internal values! -> Warning 009: Include defs not necessary, using internal values!
File: /home/sergeyyarkov/Documents/Applications/attiny2313a_thermostat/firmware.asm, Line: 14 File: /home/sergeyyarkov/Documents/Projects/Firmwares/AVR/attiny2313a_thermostat/firmware.asm, Line: 14
Source line: .INCLUDE "tn2313Adef.inc" Source line: .INCLUDE "tn2313Adef.inc"
15: .LIST 15: .LIST
16: 16:
17: .DEF TEMP_REG_A = r16 17: .DEF TEMP_REG_A = r16
18: .DEF TEMP_REG_B = r17 18: .DEF TEMP_REG_B = r17
19: 19:
20: ;========================================; 20: .EQU DIGIT_1_PIN = PD2
21: ; LABELS ; 21: .EQU DIGIT_2_PIN = PD3
22: ;========================================; 22: .EQU DIGIT_3_PIN = PD4
23: 23: .EQU DIGIT_4_PIN = PD5
24: .EQU DISPLAY_1_PIN = PD2 24:
25: .EQU DISPLAY_2_PIN = PD3 25: .EQU LED_POWER_PIN = PD6
26: .EQU DISPLAY_3_PIN = PD4 26:
27: .EQU DISPLAY_4_PIN = PD5 27: .EQU USI_LATCH_PIN = PB0 ; ST_CP on 74HC595
28: 28: .EQU USI_DO_PIN = PB6 ; DS on 74HC595
29: .EQU LED_POWER_PIN = PD6 29: .EQU USI_CLK_PIN = PB7 ; SH_CP on 74HC595
30: 30:
31: .EQU USI_LATCH_PIN = PB0 ; ST_CP on 74HC595 31: .EQU MCU_STATE_DEFAULT = 0x01 ; Режим измерения температуры и сравнения с заданными параметрами
32: .EQU USI_DO_PIN = PB6 ; DS on 74HC595 32: .EQU MCU_STATE_PROGRAM = 0x02 ; Режим настройки параметров в EEPROM
33: .EQU USI_CLK_PIN = PB7 ; SH_CP on 74HC595 33: .EQU MCU_STATE_ERROR = 0x03 ; Режим ошибки, например когда не подключен датчик
34: 34:
35: ;========================================; 35: ; **** СЕГМЕНТ ДАННЫХ ********************************************
36: ; DATA SEGMENT ; 36: .DSEG
37: ;========================================; 37: .ORG SRAM_START
38: .DSEG 38:
39: .ORG SRAM_START 39: MCU_STATE: .BYTE 1 ; Текущее состояние МК
40: 40: NUMBER: .BYTE 2
41: DISPLAY_DIGIT: .BYTE 4 41: DIGITS: .BYTE 4 ; Ячейки, где хранятся символы, для вывода на индикатор
42: 42: CURRENT_DIGIT: .BYTE 1 ; Номер разряда индикатора, который сейчас горит
43: ;========================================; 43:
44: ; CODE SEGMENT ; 44: ; **** СЕГМЕНТ КОДА **********************************************
45: ;========================================; 45: .CSEG
46: 46:
47: .CSEG 47: .ORG 0x00
48: .ORG 0x00 48: 000000 C040 rjmp RESET_vect
49: 49:
50: ;========================================; 50: .ORG 0x000D
51: ; VECTORS ; 51: 00000D C000 rjmp TIMER0_COMPA_vect
52: ;========================================; 52:
53: 53: ; **** ДИНАМИЧЕСКАЯ ИНДИКАЦИЯ ************************************
54: 000000 C000 rjmp RESET_vect ; Program start at RESET vector 54: TIMER0_COMPA_vect:
55: ;reti ; External Interrupt Request 0 / inactive 55: 00000E 9140 lds r20, CURRENT_DIGIT
56: ;reti ; External Interrupt Request 1 / inactive 00000F 0067
57: ;reti ; Timer/Counter1 Capture Event / inactive 56: 000010 3045 cpi r20, 5
58: ;reti ; Timer/Counter1 Compare Match A / inactive 57: 000011 F40C brge reset_digit_idx
59: ;reti ; Timer/Counter1 Overflow / inactive 58: 000012 C003 rjmp _indicate_1
60: ;reti ; Timer/Counter0 Overflow / inactive 59:
61: ;reti ; USART0, Rx Complete / inactive 60: reset_digit_idx:
62: ;reti ; USART0 Data Register Empty / inactive 61: 000013 2744 clr r20
63: ;reti ; USART0, Tx Complete / inactive 62: 000014 9340 sts CURRENT_DIGIT, r20
64: ;reti ; Analog Comparator / inactive 000015 0067
65: ;reti ; Pin Change Interrupt Request 0/ inactive 63:
66: ;reti ; Timer/Counter1 Compare Match B / inactive 64: _indicate_1:
67: ;reti ; Timer/Counter0 Compare Match A / inactive 65: 000016 3040 cpi r20, 0
68: ;reti ; Timer/Counter0 Compare Match B / inactive 66: 000017 F439 brne _indicate_2
69: ;reti ; USI Start Condition/ inactive 67:
70: ;reti ; USI Overflow / inactive 68: 000018 EF0B ldi r16, ~(1<<DIGIT_1_PIN)
71: ;reti ; EEPROM Ready/ inactive 69: 000019 7102 andi r16, PORTD
72: ;reti ; Watchdog Timer Overflow / inactive 70: 00001A BB02 out PORTD, r16
73: ;reti ; Pin Change Interrupt Request 1 / inactive 71: 00001B 9100 lds TEMP_REG_A, DIGITS+3
74: ;reti ; Pin Change Interrupt Request 2 / inactive 00001C 0066
75: 72: 00001D D075 rcall DISPLAY_DECODER
76: RESET_vect: 73: 00001E D04C rcall USI_TRANSMIT
77: ;========================================; 74:
78: ; INITIALIZE STACK POINTER ; 75: _indicate_2:
79: ;========================================; 76: 00001F 3041 cpi r20, 1
80: 000001 ED0F ldi TEMP_REG_A, LOW(RAMEND) 77: 000020 F441 brne _indicate_3
81: 000002 BF0D out SPL, TEMP_REG_A 78:
82: 79: 000021 9892 cbi PORTD, DIGIT_1_PIN
83: MCU_INIT: 80: 000022 9894 cbi PORTD, DIGIT_3_PIN
84: ;=======================================================; 81: 000023 9895 cbi PORTD, DIGIT_4_PIN
85: ; INITIALIZE PORTS ; 82: 000024 9A93 sbi PORTD, DIGIT_2_PIN
86: ; ; 83: 000025 9100 lds TEMP_REG_A, DIGITS+2
87: ; POWER LED <-------------> OUT PD6 ; 000026 0065
88: ; - This LED is used to indicate that device ; 84: 000027 D06B rcall DISPLAY_DECODER
89: ; is working correctly ; 85: 000028 D042 rcall USI_TRANSMIT
90: ; 7SEG DIGIT 1 <-------------> OUT PD2 ; 86:
91: ; 7SEG DIGIT 2 <-------------> OUT PD3 ; 87: _indicate_3:
92: ; 7SEG DIGIT 3 <-------------> OUT PD4 ; 88: 000029 3042 cpi r20, 2
93: ; 7SEG DIGIT 4 <-------------> OUT PD5 ; 89: 00002A F441 brne _indicate_4
94: ; ; 90:
95: ; USI CLOCK PIN <-------------> OUT PB0 ; 91: 00002B 9892 cbi PORTD, DIGIT_1_PIN
96: ; USI DATA OUT PIN <-------------> OUT PB6 ; 92: 00002C 9893 cbi PORTD, DIGIT_2_PIN
97: ; USI LATCH PIN <-------------> OUT PB7 ; 93: 00002D 9895 cbi PORTD, DIGIT_4_PIN
98: ;=======================================================; 94: 00002E 9A94 sbi PORTD, DIGIT_3_PIN
99: 000003 E70C ldi r16, (1<<LED_POWER_PIN) | (1<<DISPLAY_1_PIN) | (1<<DISPLAY_2_PIN) | (1<<DISPLAY_3_PIN) | (1<<DISPLAY_4_PIN) 95: 00002F 9100 lds TEMP_REG_A, DIGITS+1
100: 000004 BB01 out DDRD, r16 000030 0064
101: 000005 EC01 ldi r16, (1<<USI_CLK_PIN) | (1<<USI_DO_PIN) | (1<<USI_LATCH_PIN) 96: 000031 D061 rcall DISPLAY_DECODER
102: 000006 BB07 out DDRB, r16 97: 000032 D038 rcall USI_TRANSMIT
103: 000007 9A92 sbi PORTD, PD2 98:
104: 000008 9A93 sbi PORTD, PD3 99: _indicate_4:
105: 000009 9A94 sbi PORTD, PD4 100: 000033 3043 cpi r20, 3
106: 00000A 9A95 sbi PORTD, PD5 101: 000034 F441 brne _indicate_exit
107: 102:
108: 00000B E004 ldi TEMP_REG_A, 4 103: 000035 9892 cbi PORTD, DIGIT_1_PIN
109: 00000C 9300 sts DISPLAY_DIGIT, TEMP_REG_A 104: 000036 9893 cbi PORTD, DIGIT_2_PIN
00000D 0060 105: 000037 9894 cbi PORTD, DIGIT_3_PIN
106: 000038 9A95 sbi PORTD, DIGIT_4_PIN
107: 000039 9100 lds TEMP_REG_A, DIGITS
00003A 0063
108: 00003B D057 rcall DISPLAY_DECODER
109: 00003C D02E rcall USI_TRANSMIT
110: 110:
111: 00000E E003 ldi TEMP_REG_A, 3 111: _indicate_exit:
112: 00000F 9300 sts DISPLAY_DIGIT+1, TEMP_REG_A 112: 00003D 9543 inc r20
000010 0061 113: 00003E 9340 sts CURRENT_DIGIT, r20
113: 00003F 0067
114: 000011 E002 ldi TEMP_REG_A, 2 114: 000040 9518 reti
115: 000012 9300 sts DISPLAY_DIGIT+2, TEMP_REG_A 115:
000013 0062 116: RESET_vect:
116: 117: 000041 ED0F ldi TEMP_REG_A, LOW(RAMEND)
117: 000014 E001 ldi TEMP_REG_A, 1 118: 000042 BF0D out SPL, TEMP_REG_A
118: 000015 9300 sts DISPLAY_DIGIT+3, TEMP_REG_A
000016 0063
119: 119:
120: 000017 2411 clr r1 120: MCU_INIT:
121: 000018 E9E6 ldi ZL,LOW(2*DISPLAY_SYMBOLS) 121: ; **** ИНИЦИАЛИЗАЦИЯ ПОРТОВ ************************************
122: 000019 E0F0 ldi ZH,HIGH(2*DISPLAY_SYMBOLS) 122: 000043 E70C ldi r16, (1<<LED_POWER_PIN) | (1<<DIGIT_1_PIN) | (1<<DIGIT_2_PIN) | (1<<DIGIT_3_PIN) | (1<<DIGIT_4_PIN)
123: 123: 000044 BB01 out DDRD, r16
124: 00001A C00A rjmp LOOP 124: 000045 EC05 ldi r16, (1<<USI_CLK_PIN) | (1<<USI_DO_PIN) | (1<<USI_LATCH_PIN) | (1<<PB2)
125: 125: 000046 BB07 out DDRB, r16
126: ;=START================================================================================================; 126:
127: ; Transmit byte into 74HC595 using USI 127: ; **** ИНИЦИАЛИЗАЦИЯ ТАЙМЕРОВ **********************************
128: ;======================================================================================================; 128: 000047 E402 ldi r16, (1<<COM0A0) | (1<<WGM01)
129: USI_TRANSMIT: 129: 000048 BF00 out TCCR0A, r16
130: 00001B B80F out USIDR, r0 ; Move byte from temp register to USI Data Register 130:
131: 131: 000049 E005 ldi r16, (1<<CS02) | (1<<CS00)
132: ; Enable USI Overflow Interrupt Flag (will be 0 if transfer is not compeleted) 132: 00004A BF03 out TCCR0B, r16
133: 00001C E400 ldi TEMP_REG_A, (1<<USIOIF) 133:
134: 00001D B90E out USISR, TEMP_REG_A 134: 00004B E208 ldi r16, 40
135: 135: 00004C BF06 out OCR0A, r16
136: ; Load settings of USI into temp register 136:
137: ; This will setup USI to Three-wire mode, Software clock strobe (USITC) 137: 00004D E001 ldi r16, (1<<OCIE0A)
138: ; with External, positive edge and toggle USCK 138: 00004E BF09 out TIMSK, r16
139: ; 139:
140: ; USIWM0 <--------------> USI Wire Mode 140: 00004F 2411 clr r1
141: ; USICS1 <--------------> USI Clock Source Select 141: 000050 E6E2 ldi ZL,LOW(2*DISPLAY_SYMBOLS)
142: ; USICLK <--------------> USI Clock Strobe 142: 000051 E0F1 ldi ZH,HIGH(2*DISPLAY_SYMBOLS)
143: ; USITC <--------------> USI Toggle Clock (Enable clock generation) 143:
144: 00001E E10B ldi TEMP_REG_A, (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC) 144: ; загружаем число, которое нужно показать на индикатор
145: 145: .EQU DISPLAY_NUMBER = 279
146: _USI_TRANSMIT_LOOP: ; Execute loop when USIOIF is 0 146: 000052 E167 ldi r22, LOW(DISPLAY_NUMBER)
147: 00001F B90D out USICR, TEMP_REG_A ; Load settings from temp register into USI Control Register 147: 000053 E071 ldi r23, HIGH(DISPLAY_NUMBER)
148: 000020 9B76 sbis USISR, USIOIF ; If transfer is comleted then move out of loop 148:
149: 000021 CFFD rjmp _USI_TRANSMIT_LOOP 149: 000054 9210 sts CURRENT_DIGIT, r1
000055 0067
150: 150:
151: ; Send pulse into LATCH pin. 151: 000056 9478 sei
152: ; This will copy byte from 74hc595 shift register into 74hc595 storage register 152:
153: 000022 9AC0 sbi PORTB, USI_LATCH_PIN 153: 000057 C01D rjmp LOOP
154: 000023 98C0 cbi PORTB, USI_LATCH_PIN 154:
155: 000024 9508 ret 155: ; **** ПОДПРОГРАММЫ **********************************************
156: ;=END==================================================================================================; 156: .INCLUDE "div16u.asm"
157: Including file div16u.asm
158: ; .MACRO DISPLAY_SEND
159: ; ldi TEMP_REG_A, @0 1: ;***************************************************************************
160: ; mov r0, TEMP_REG_A 2: ;*
161: ; rcall USI_TRANSMIT 3: ;* "div16u" - 16/16 Bit Unsigned Division
162: ; .ENDMACRO 4: ;*
163: 5: ;* This subroutine divides the two 16-bit numbers
164: ;========================================; 6: ;* "dd8uH:dd8uL" (dividend) and "dv16uH:dv16uL" (divisor).
165: ; MAIN PROGRAM LOOP ; 7: ;* The result is placed in "dres16uH:dres16uL" and the remainder in
166: ;========================================; 8: ;* "drem16uH:drem16uL".
167: 9: ;*
168: LOOP: 10: ;* Number of words :19
169: 000025 D020 rcall TOGGLE_POWER_LED 11: ;* Number of cycles :235/251 (Min/Max)
170: 12: ;* Low registers used :2 (drem16uL,drem16uH)
171: 000026 E01A ldi TEMP_REG_B, 10 13: ;* High registers used :5 (dres16uL/dd16uL,dres16uH/dd16uH,dv16uL,dv16uH,
172: 000027 1611 cp r1, TEMP_REG_B 14: ;* dcnt16u)
173: 000028 F40C brge RESET_POINTER 15: ;*
174: 000029 C003 rjmp DISPLAY_SEND 16: ;***************************************************************************
175: 17:
176: RESET_POINTER: 18: ;***** Subroutine Register Variables
177: 00002A 2411 clr r1 19:
178: 00002B E9E6 ldi ZL,LOW(2*DISPLAY_SYMBOLS) 20: .def drem16uL=r14
179: 00002C E0F0 ldi ZH,HIGH(2*DISPLAY_SYMBOLS) 21: .def drem16uH=r15
180: 22: .def dres16uL=r16
181: DISPLAY_SEND: 23: .def dres16uH=r17
182: 00002D 9005 lpm r0, Z+ 24: .def dd16uL =r16
183: 00002E 9413 inc r1 25: .def dd16uH =r17
184: 00002F DFEB rcall USI_TRANSMIT 26: .def dv16uL =r18
185: 27: .def dv16uH =r19
186: 000030 D005 rcall DELAY 28: .def dcnt16u =r20
187: 000031 D004 rcall DELAY 29:
188: 000032 D003 rcall DELAY 30: ;***** Code
189: 000033 D002 rcall DELAY 31:
190: 000034 D001 rcall DELAY 32: 000058 24EE clr drem16uL ;clear remainder Low byte
191: 33: 000059 18FF sub drem16uH,drem16uH;clear remainder High byte and carry
192: 000035 CFEF rjmp LOOP 34: 00005A E141 ldi dcnt16u,17 ;init loop counter
193: 35: 00005B 1F00 rol dd16uL ;shift left dividend
194: DELAY: 36: 00005C 1F11 rol dd16uH
195: 000036 930F push r16 37: 00005D 954A dec dcnt16u ;decrement counter
196: 000037 931F push r17 38: 00005E F409 brne d16u_2 ;if done
197: 000038 94F8 cli 39: 00005F 9508 ret ; return
198: 000039 EF0F ldi r16, 255 40: 000060 1CEE rol drem16uL ;shift dividend into remainder
199: _DELAY_1: 41: 000061 1CFF rol drem16uH
200: 00003A EF1F ldi r17, 255 42: 000062 1AE2 sub drem16uL,dv16uL ;remainder = remainder - divisor
201: _DELAY_2: 43: 000063 0AF3 sbc drem16uH,dv16uH ;
202: 00003B 951A dec r17 44: 000064 F420 brcc d16u_3 ;if result negative
203: 00003C 0000 nop 45: 000065 0EE2 add drem16uL,dv16uL ; restore remainder
204: 00003D 0000 nop 46: 000066 1EF3 adc drem16uH,dv16uH
205: 00003E 0000 nop 47: 000067 9488 clc ; clear carry to be shifted into result
206: 00003F F7D9 brne _DELAY_2 48: 000068 CFF2 rjmp d16u_1 ;else
207: 49: 000069 9408 sec ; set carry to be shifted into result
208: 000040 950A dec r16 50: 00006A CFF0 rjmp d16u_1
209: 000041 F7C1 brne _DELAY_1 Continuing file firmware.asm
210: 000042 9478 sei 157: .INCLUDE "usi.asm"
211: Including file usi.asm
212: 000043 911F pop r17
213: 000044 910F pop r16 1: ; **** ОТПРАВКА БАЙТА В СДВИГОВЫЙ РЕГИСТР *************************
214: 000045 9508 ret 2: USI_TRANSMIT:
215: 3: 00006B B80F out USIDR, r0 ; Move byte from temp register to USI Data Register
216: TOGGLE_POWER_LED: 4:
217: 000046 E400 ldi r16, (1<<LED_POWER_PIN) 5: ; Enable USI Overflow Interrupt Flag (will be 0 if transfer is not compeleted)
218: 000047 B312 in r17, PORTD 6: 00006C E400 ldi TEMP_REG_A, (1<<USIOIF)
219: 000048 2710 eor r17, r16 7: 00006D B90E out USISR, TEMP_REG_A
220: 000049 BB12 out PORTD, r17 8:
221: 00004A 9508 ret 9: ; Load settings of USI into temp register
222: 10: ; This will setup USI to Three-wire mode, Software clock strobe (USITC)
223: DISPLAY_SYMBOLS: 11: ; with External, positive edge and toggle USCK
224: ; HGFEDCBA HGFEDCBA 12: ;
225: .DB 0b11000000, 0b11111001 ; 0, 1 13: ; USIWM0 <--------------> USI Wire Mode
00004B F9C0 14: ; USICS1 <--------------> USI Clock Source Select
226: .DB 0b10100100, 0b10110000 ; 2, 3 15: ; USICLK <--------------> USI Clock Strobe
00004C B0A4 16: ; USITC <--------------> USI Toggle Clock (Enable clock generation)
227: .DB 0b10011001, 0b10010010 ; 4, 5 17: 00006E E10B ldi TEMP_REG_A, (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC)
00004D 9299 18:
228: .DB 0b10000010, 0b11111000 ; 6, 7 19: _USI_TRANSMIT_LOOP: ; Execute loop when USIOIF is 0
00004E F882 20: 00006F B90D out USICR, TEMP_REG_A ; Load settings from temp register into USI Control Register
229: .DB 0b10000000, 0b10010000 ; 8, 9 21: 000070 9B76 sbis USISR, USIOIF ; If transfer is comleted then move out of loop
00004F 9080 22: 000071 CFFD rjmp _USI_TRANSMIT_LOOP
230: 23:
231: ;========================================; 24: ; Send pulse into LATCH pin.
232: ; EEPROM SEGMENT ; 25: ; This will copy byte from 74hc595 shift register into 74hc595 storage register
233: ;========================================; 26: 000072 9AC0 sbi PORTB, USI_LATCH_PIN
234: 27: 000073 98C0 cbi PORTB, USI_LATCH_PIN
235: .ESEG 28: 000074 9508 ret
236: INFO: .DB "AVR Thermostat. Written by Sergey Yarkov 22.01.2023" Continuing file firmware.asm
000000 41 56 52 20 54 48 45 52 158:
000008 4D 4F 53 54 41 54 2E 20 159: ; **** ГЛАВНЫЙ ЦИКЛ **********************************************
000010 57 52 49 54 54 45 4E 20 160: LOOP:
000018 42 59 20 53 45 52 47 45 161: ; **** ПОЛУЧЕНИЕ ЦИФР ИЗ 16-ТИ БИТНОГО ЧИСЛА *******************
000020 59 20 59 41 52 4B 4F 56 162: ; Описание: Перемещает цифры числа в соответствующие ячейки памяти в SRAM
000028 20 32 32 2E 30 31 2E 32 163: ; путем деления этого числа несколько раз
000030 30 32 33 164: GET_DIGITS:
165: 000075 94F8 cli
166: 000076 E084 ldi r24, 4 ; максимум 4 цифры, т.к индикатор четырех разрядный
167: 000077 E6A3 ldi XL, LOW(DIGITS)
168: 000078 E0B0 ldi XH, HIGH(DIGITS)
169:
170: .equ dividend_addr = $0060
171: .equ divisor = 10
172:
173: ; загружаем делимое в адрес SRAM делимого
174: 000079 9360 sts dividend_addr, r22
00007A 0060
175: 00007B 9370 sts dividend_addr+1, r23
00007C 0061
176:
177: ; четыре раза производим деление для получения остатков
178: DIV_LOOP:
179: ; заполняем нужные регистры
180: 00007D 9100 lds dd16uL, dividend_addr
00007E 0060
181: 00007F 9110 lds dd16uH, dividend_addr+1
000080 0061
182: 000081 E02A ldi dv16uL, LOW(divisor)
183: 000082 E030 ldi dv16uH, HIGH(divisor)
184:
185: 000083 DFD4 rcall div16u ; делим
186:
187: 000084 92ED st X+, drem16uL ; сохраняем остаток в ячейку по указателю
188:
189: ; обновляем делимое
190: 000085 9300 sts dividend_addr, dres16uL
000086 0060
191: 000087 9310 sts dividend_addr+1, dres16uH
000088 0061
192:
193: 000089 958A dec r24 ; декрементируем счетчик цикла
194: 00008A F791 brne DIV_LOOP ; делим еще раз если не 0
195: 00008B 9478 sei
196:
197: 00008C D01B rcall TOGGLE_POWER_LED
198: 00008D D00C rcall DELAY
199: 00008E D00B rcall DELAY
200: 00008F D00A rcall DELAY
201: 000090 D009 rcall DELAY
202: 000091 D008 rcall DELAY
203:
204: 000092 CFE2 rjmp LOOP
205:
206: DISPLAY_DECODER:
207: 000093 E6E2 ldi ZL, LOW(2*DISPLAY_SYMBOLS)
208: 000094 E0F1 ldi ZH, HIGH(2*DISPLAY_SYMBOLS)
209:
210: 000095 E010 ldi TEMP_REG_B, 0
211: 000096 0FE0 add ZL, TEMP_REG_A
212: 000097 1FF1 adc ZH, TEMP_REG_B
213:
214: 000098 95C8 lpm
215: 000099 9508 ret
216:
217: DELAY:
218: 00009A 930F push r16
219: 00009B 931F push r17
220: 00009C EF0F ldi r16, 255
221: _DELAY_1:
222: 00009D EF1F ldi r17, 255
223: _DELAY_2:
224: 00009E 951A dec r17
225: 00009F 0000 nop
226: 0000A0 0000 nop
227: 0000A1 0000 nop
228: 0000A2 F7D9 brne _DELAY_2
229:
230: 0000A3 950A dec r16
231: 0000A4 F7C1 brne _DELAY_1
232:
233: 0000A5 911F pop r17
234: 0000A6 910F pop r16
235: 0000A7 9508 ret
236:
237: TOGGLE_POWER_LED:
238: 0000A8 930F push r16
239: 0000A9 931F push r17
240: 0000AA E400 ldi r16, (1<<LED_POWER_PIN)
241: 0000AB B312 in r17, PORTD
242: 0000AC 2710 eor r17, r16
243: 0000AD BB12 out PORTD, r17
244: 0000AE 911F pop r17
245: 0000AF 910F pop r16
246: 0000B0 9508 ret
247:
248: DISPLAY_SYMBOLS:
249: ; HGFEDCBA HGFEDCBA
250: .DB 0b11000000, 0b11111001 ; 0, 1
0000B1 F9C0
251: .DB 0b10100100, 0b10110000 ; 2, 3
0000B2 B0A4
252: .DB 0b10011001, 0b10010010 ; 4, 5
0000B3 9299
253: .DB 0b10000010, 0b11111000 ; 6, 7
0000B4 F882
254: .DB 0b10000000, 0b10010000 ; 8, 9
0000B5 9080
255:
256: ; **** СЕГМЕНТ EEPROM ********************************************
257: ; .ESEG
258: ; INFO: .DB "AVR Thermostat. Written by Sergey Yarkov 22.01.2023"
List of symbols: List of symbols:
Type nDef nUsed Decimalval Hexval Name Type nDef nUsed Decimalval Hexval Name
T 1 1 89 59 ATTINY2313A T 1 1 89 59 ATTINY2313A
L 1 4 96 60 DISPLAY_DIGIT L 1 0 96 60 MCU_STATE
L 1 2 1 01 RESET_VECT L 1 0 97 61 NUMBER
L 1 0 3 03 MCU_INIT L 1 6 99 63 DIGITS
L 1 2 27 1B USI_TRANSMIT L 1 4 103 67 CURRENT_DIGIT
L 1 2 31 1F _USI_TRANSMIT_LOOP L 1 2 14 0E TIMER0_COMPA_VECT
L 1 4 37 25 LOOP L 1 2 19 13 RESET_DIGIT_IDX
L 1 2 42 2A RESET_POINTER L 1 2 22 16 _INDICATE_1
L 1 2 45 2D DISPLAY_SEND L 1 2 31 1F _INDICATE_2
L 1 10 54 36 DELAY L 1 2 41 29 _INDICATE_3
L 1 2 58 3A _DELAY_1 L 1 2 51 33 _INDICATE_4
L 1 2 59 3B _DELAY_2 L 1 2 61 3D _INDICATE_EXIT
L 1 2 70 46 TOGGLE_POWER_LED L 1 2 65 41 RESET_VECT
L 1 4 75 4B DISPLAY_SYMBOLS L 1 0 67 43 MCU_INIT
L 1 0 0 00 INFO L 1 2 88 58 DIV16U
R 1 14 16 10 TEMP_REG_A L 1 4 91 5B D16U_1
L 1 2 96 60 D16U_2
L 1 2 105 69 D16U_3
L 1 8 107 6B USI_TRANSMIT
L 1 2 111 6F _USI_TRANSMIT_LOOP
L 1 4 117 75 LOOP
L 1 0 117 75 GET_DIGITS
L 1 2 125 7D DIV_LOOP
L 1 8 147 93 DISPLAY_DECODER
L 1 10 154 9A DELAY
L 1 2 157 9D _DELAY_1
L 1 2 158 9E _DELAY_2
L 1 2 168 A8 TOGGLE_POWER_LED
L 1 4 177 B1 DISPLAY_SYMBOLS
R 1 11 16 10 TEMP_REG_A
R 1 2 17 11 TEMP_REG_B R 1 2 17 11 TEMP_REG_B
R 1 5 14 0E DREM16UL
R 1 5 15 0F DREM16UH
R 1 1 16 10 DRES16UL
R 1 1 17 11 DRES16UH
R 1 2 16 10 DD16UL
R 1 2 17 11 DD16UH
R 1 3 18 12 DV16UL
R 1 3 19 13 DV16UH
R 1 2 20 14 DCNT16U
C 1 0 23 17 NOW_Y C 1 0 23 17 NOW_Y
C 1 0 2 02 NOW_M C 1 0 4 04 NOW_M
C 1 0 25 19 NOW_D C 1 0 20 14 NOW_D
C 1 0 44982 AFB6 NOW_I C 1 0 45036 AFEC NOW_I
C 1 1 2 02 DISPLAY_1_PIN C 1 5 2 02 DIGIT_1_PIN
C 1 1 3 03 DISPLAY_2_PIN C 1 4 3 03 DIGIT_2_PIN
C 1 1 4 04 DISPLAY_3_PIN C 1 4 4 04 DIGIT_3_PIN
C 1 1 5 05 DISPLAY_4_PIN C 1 4 5 05 DIGIT_4_PIN
C 1 2 6 06 LED_POWER_PIN C 1 2 6 06 LED_POWER_PIN
C 1 3 0 00 USI_LATCH_PIN C 1 3 0 00 USI_LATCH_PIN
C 1 1 6 06 USI_DO_PIN C 1 1 6 06 USI_DO_PIN
C 1 1 7 07 USI_CLK_PIN C 1 1 7 07 USI_CLK_PIN
C 1 0 1 01 MCU_STATE_DEFAULT
C 1 0 2 02 MCU_STATE_PROGRAM
C 1 0 3 03 MCU_STATE_ERROR
C 1 2 279 0117 DISPLAY_NUMBER
C 1 6 96 60 DIVIDEND_ADDR
C 1 2 10 0A DIVISOR
No macros. No macros.
Program : 75 words. Program : 165 words.
Constants : 5 words. Constants : 5 words.
Total program memory: 80 words. Total program memory: 170 words.
Eeprom space : 51 bytes. Eeprom space : 0 bytes.
Data segment : 4 bytes. Data segment : 8 bytes.
Compilation completed, no errors. Compilation completed, no errors.
Compilation ended 25.02.2023, 10:41:03 Compilation ended 20.04.2023, 00:25:25

View File

@ -1,10 +1,12 @@
/avr_sim_project_file /avr_sim_project_file
/home/sergeyyarkov/Documents/Applications/attiny2313a_thermostat/firmware.asm /home/sergeyyarkov/Documents/Projects/Firmwares/AVR/attiny2313a_thermostat/firmware.asm
mainasm=firmware.asm mainasm=firmware.asm
file=firmware.lst,173,1,1 file=firmware.lst,122,33,48
file=firmware.asm,1,1,1 file=firmware.asm,1,1,1
clock=1000000, Div8 file=div16u.asm,1,1,1
file=usi.asm,1,1,1
clock=8000000
device-type=ATtiny2313A device-type=ATtiny2313A
device-package=20-pin-PDIP_SOIC device-package=20-pin-PDIP_SOIC
windows=acepStwz windows=acepSTwz
alert1=0,0,-1,-1,,0,0 alert1=0,0,-1,-1,,0,0

28
usi.asm Normal file
View File

@ -0,0 +1,28 @@
; **** ОТПРАВКА БАЙТА В СДВИГОВЫЙ РЕГИСТР *************************
USI_TRANSMIT:
out USIDR, r0 ; Move byte from temp register to USI Data Register
; Enable USI Overflow Interrupt Flag (will be 0 if transfer is not compeleted)
ldi TEMP_REG_A, (1<<USIOIF)
out USISR, TEMP_REG_A
; Load settings of USI into temp register
; This will setup USI to Three-wire mode, Software clock strobe (USITC)
; with External, positive edge and toggle USCK
;
; USIWM0 <--------------> USI Wire Mode
; USICS1 <--------------> USI Clock Source Select
; USICLK <--------------> USI Clock Strobe
; USITC <--------------> USI Toggle Clock (Enable clock generation)
ldi TEMP_REG_A, (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC)
_USI_TRANSMIT_LOOP: ; Execute loop when USIOIF is 0
out USICR, TEMP_REG_A ; Load settings from temp register into USI Control Register
sbis USISR, USIOIF ; If transfer is comleted then move out of loop
rjmp _USI_TRANSMIT_LOOP
; Send pulse into LATCH pin.
; This will copy byte from 74hc595 shift register into 74hc595 storage register
sbi PORTB, USI_LATCH_PIN
cbi PORTB, USI_LATCH_PIN
ret