AVRASM ver. 2.2.7 main.asm Mon Jun 26 12:19:45 2023 [builtin](2): Including file '/home/sergeyyarkov/.mchp_packs/Microchip/ATtiny_DFP/3.0.151/avrasm/inc\tn2313Adef.inc' main.asm(15): Including file 'definitions.asm' main.asm(16): Including file 'macros.asm' main.asm(295): Including file 'div16u.asm' div16u.asm(22): warning: Register r16 already defined by the .DEF directive main.asm(295): 'div16u.asm' included form here div16u.asm(23): warning: Register r17 already defined by the .DEF directive main.asm(295): 'div16u.asm' included form here div16u.asm(24): warning: Register r16 already defined by the .DEF directive main.asm(295): 'div16u.asm' included form here div16u.asm(25): warning: Register r17 already defined by the .DEF directive main.asm(295): 'div16u.asm' included form here div16u.asm(27): warning: Register r19 already defined by the .DEF directive main.asm(295): 'div16u.asm' included form here div16u.asm(28): warning: Register r20 already defined by the .DEF directive main.asm(295): 'div16u.asm' included form here main.asm(296): Including file 'div8u.asm' div8u.asm(18): warning: Register r15 already defined by the .DEF directive main.asm(296): 'div8u.asm' included form here div8u.asm(19): warning: Register r16 already defined by the .DEF directive main.asm(296): 'div8u.asm' included form here div8u.asm(20): warning: Register r16 already defined by the .DEF directive main.asm(296): 'div8u.asm' included form here div8u.asm(21): warning: Register r17 already defined by the .DEF directive main.asm(296): 'div8u.asm' included form here div8u.asm(22): warning: Register r18 already defined by the .DEF directive main.asm(296): 'div8u.asm' included form here main.asm(297): Including file 'mpy16u.asm' mpy16u.asm(19): warning: Register r16 already defined by the .DEF directive main.asm(297): 'mpy16u.asm' included form here mpy16u.asm(20): warning: Register r17 already defined by the .DEF directive main.asm(297): 'mpy16u.asm' included form here mpy16u.asm(21): warning: Register r18 already defined by the .DEF directive main.asm(297): 'mpy16u.asm' included form here mpy16u.asm(22): warning: Register r19 already defined by the .DEF directive main.asm(297): 'mpy16u.asm' included form here mpy16u.asm(23): warning: Register r18 already defined by the .DEF directive main.asm(297): 'mpy16u.asm' included form here mpy16u.asm(24): warning: Register r19 already defined by the .DEF directive main.asm(297): 'mpy16u.asm' included form here mpy16u.asm(25): warning: Register r20 already defined by the .DEF directive main.asm(297): 'mpy16u.asm' included form here mpy16u.asm(26): warning: Register r21 already defined by the .DEF directive main.asm(297): 'mpy16u.asm' included form here main.asm(352): warning: Register r16 already defined by the .DEF directive main.asm(353): warning: Register r17 already defined by the .DEF directive [builtin](2): Including file '/home/sergeyyarkov/.mchp_packs/Microchip/ATtiny_DFP/3.0.151/avrasm/inc\tn2313Adef.inc' main.asm(15): Including file 'definitions.asm' main.asm(16): Including file 'macros.asm' main.asm(295): Including file 'div16u.asm' main.asm(296): Including file 'div8u.asm' main.asm(297): Including file 'mpy16u.asm' ; ;***** Created: 2011-02-09 12:04 ******* Source: ATtiny2313A.xml ********* ;************************************************************************* ;* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y ;* ;* Number : AVR000 ;* File Name : "tn2313Adef.inc" ;* Title : Register/Bit Definitions for the ATtiny2313A ;* Date : 2011-02-09 ;* Version : 2.35 ;* Support E-mail : avr@atmel.com ;* Target MCU : ATtiny2313A ;* ;* DESCRIPTION ;* When including this file in the assembly program file, all I/O register ;* names and I/O register bit names appearing in the data book can be used. ;* In addition, the six registers forming the three data pointers X, Y and ;* Z have been assigned names XL - ZH. Highest RAM address for Internal ;* SRAM is also defined ;* ;* The Register names are represented by their hexadecimal address. ;* ;* The Register Bit names are represented by their bit number (0-7). ;* ;* Please observe the difference in using the bit names with instructions ;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc" ;* (skip if bit in register set/cleared). The following example illustrates ;* this: ;* ;* in r16,PORTB ;read PORTB latch ;* sbr r16,(1< ; **** СЕГМЕНТ ДАННЫХ ******************************************** .DSEG .ORG SRAM_START 000060 MCU_STATE: .BYTE 1 ; Текущее состояние МК 000061 SRAM_TEMP_1: .BYTE 2 ; Хранения временного 16-бит числа в ячейке 000063 DIGITS: .BYTE 4 ; Ячейки, где хранятся символы, для вывода на индикатор 000067 CURRENT_DIGIT: .BYTE 1 ; Номер разряда индикатора, который сейчас горит 000068 SW_FLAGS: .BYTE 1 ; Состояние кнопок 000069 TEMP_L: .BYTE 1 ; Младший байт температуры 00006a TEMP_H: .BYTE 1 ; Старший байт температуры 00006b TEMP_F: .BYTE 1 ; Дробная часть 00006c SETTING_TEMP_H: .BYTE 1 ; Уставка температуры (старший байт) 00006d SETTING_TEMP_L: .BYTE 1 ; Уставка температуры (младший байт) 00006e SETTING_HYST: .BYTE 1 ; Гистерезис: отклонение от уставки 00006f SETTING_MODE: .BYTE 1 ; Режим работы: '1' - нагрев; '0' - 'охлаждение' 000070 DEVICE_FAMILY_CODE: .BYTE 1 ; Должно быть 0x10 для DS18B20 000071 SRAM_TEMP_2: .BYTE 1 000072 SRAM_TEMP_3: .BYTE 1 ;// // ; **** СЕГМЕНТ КОДА ********************************************** .CSEG // .ORG 0x00 000000 c073 rjmp RESET_vect .ORG 0x000B ; rjmp PCINT0_vect 00000b 9518 reti .ORG 0x000D 00000d c015 rjmp TIMER0_COMPA_vect // // PCINT0_vect: 00000e 930f push r16 00000f 931f push r17 000010 932f push r18 000011 933f push r19 000012 b70f in r16, SREG ; display_off ; in r17, SW_PIN ; clr r18 ; ldi r18, (1< // ; **** ДИНАМИЧЕСКАЯ ИНДИКАЦИЯ ************************************ TIMER0_COMPA_vect: 000023 934f push r20 000024 935f push r21 000025 930f push r16 000026 931f push r17 000027 b75f in r21, SREG 000028 9140 0067 lds r20, CURRENT_DIGIT 00002a 3045 cpi r20, 5 00002b f40c brge _CLR_CURRENT_DIGIT ; сброс активного разряда если >= 5 00002c c003 rjmp _indicate_1 _CLR_CURRENT_DIGIT: ; сброс текущего активного разряда в ноль 00002d 2744 clr r20 00002e 9340 0067 sts CURRENT_DIGIT, r20 _indicate_1: 000030 3040 cpi r20, 0 000031 f481 brne _indicate_2 000032 9893 cbi PORTD, DIGIT_2_PIN 000033 9894 cbi PORTD, DIGIT_3_PIN 000034 9895 cbi PORTD, DIGIT_4_PIN 000035 f00e brts PC+2 000036 c002 rjmp PC+3 000037 e00b ldi TEMP_REG_A, 11 ; // - 000038 c002 rjmp PC+3 000039 9100 0065 lds TEMP_REG_A, DIGITS+2 00003b 2300 tst TEMP_REG_A 00003c f011 breq PC+3 00003d 9a92 sbi PORTD, DIGIT_1_PIN 00003e c001 rjmp PC+2 00003f 9892 cbi PORTD, DIGIT_1_PIN 000040 d20f rcall DISPLAY_DECODER 000041 d18c rcall USI_TRANSMIT _indicate_2: 000042 3041 cpi r20, 1 000043 f481 brne _indicate_3 000044 9892 cbi PORTD, DIGIT_1_PIN 000045 9894 cbi PORTD, DIGIT_3_PIN 000046 9895 cbi PORTD, DIGIT_4_PIN 000047 9100 0064 lds TEMP_REG_A, DIGITS+1 000049 9130 0065 lds r19, DIGITS+2 00004b 2b03 or TEMP_REG_A, r19 00004c f011 breq PC+3 00004d 9a93 sbi PORTD, DIGIT_2_PIN 00004e c001 rjmp PC+2 00004f 9893 cbi PORTD, DIGIT_2_PIN 000050 9100 0064 lds TEMP_REG_A, DIGITS+1 000052 d1fd rcall DISPLAY_DECODER 000053 d17a rcall USI_TRANSMIT _indicate_3: 000054 3042 cpi r20, 2 000055 f459 brne _indicate_4 000056 9892 cbi PORTD, DIGIT_1_PIN 000057 9893 cbi PORTD, DIGIT_2_PIN 000058 9895 cbi PORTD, DIGIT_4_PIN 000059 9a94 sbi PORTD, DIGIT_3_PIN 00005a 9100 0063 lds TEMP_REG_A, DIGITS 00005c d1f3 rcall DISPLAY_DECODER ; зажигаем точку 00005d 2d00 mov r16, r0 00005e 770f cbr r16, (1<<7) 00005f 2e00 mov r0, r16 000060 d16d rcall USI_TRANSMIT _indicate_4: 000061 3043 cpi r20, 3 000062 f441 brne _indicate_exit 000063 9892 cbi PORTD, DIGIT_1_PIN 000064 9893 cbi PORTD, DIGIT_2_PIN 000065 9894 cbi PORTD, DIGIT_3_PIN 000066 9a95 sbi PORTD, DIGIT_4_PIN 000067 9100 006b lds TEMP_REG_A, TEMP_F 000069 d1e6 rcall DISPLAY_DECODER 00006a d163 rcall USI_TRANSMIT _indicate_exit: 00006b 9543 inc r20 00006c 9340 0067 sts CURRENT_DIGIT, r20 00006e bf5f out SREG, r21 00006f 911f pop r17 000070 910f pop r16 000071 915f pop r21 000072 914f pop r20 000073 9518 reti ;// ; **** СТАРТ ПРОГРАММЫ ******************************************* RESET_vect: 000074 ed0f ldi TEMP_REG_A, LOW(RAMEND) 000075 bf0d out SPL, TEMP_REG_A // ; **** ПРОЦЕСС ИНИЦИАЛИЗАЦИИ МК ********************************** MCU_INIT: ; **** ИНИЦИАЛИЗАЦИЯ ПИНОВ ************************************* 000076 e70f 000077 bb01 outi r16, DDRD, (1< // ; **** ГЛАВНЫЙ ЦИКЛ ********************************************** LOOP: ; rcall DISPLAY_UPD_DIGITS 0000b6 9100 0060 lds r16, MCU_STATE ; получаем текущее состояние МК _STATE_DEFAULT: 0000b8 3000 cpi r16, MCU_STATE_DEFAULT 0000b9 f439 brne _STATE_PROGRAM 0000ba 9896 cbi LED_ERR_PORT, LED_ERR_PIN 0000bb d17a rcall DISPLAY_UPD_DIGITS 0000bc d0a2 rcall TEMP_UPD ; обновление данных о температуре 0000bd e001 0000be bf09 outi r16, TIMSK, (1< ; **** ПОДПРОГРАММЫ ********************************************** .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 div16u: 0000ca 24ee clr drem16uL ; clear remainder Low byte 0000cb 18ff sub drem16uH,drem16uH ; clear remainder High byte and carry 0000cc e141 ldi dcnt16u,17 ; init loop counter d16u_1: 0000cd 1f00 rol dd16uL ; shift left dividend 0000ce 1f11 rol dd16uH 0000cf 954a dec dcnt16u ; decrement counter 0000d0 f409 brne d16u_2 ; if done 0000d1 9508 ret ; return d16u_2: 0000d2 1cee rol drem16uL ; shift dividend into remainder 0000d3 1cff rol drem16uH 0000d4 1ae2 sub drem16uL,dv16uL ; remainder = remainder - divisor 0000d5 0af3 sbc drem16uH,dv16uH 0000d6 f420 brcc d16u_3 ; if result negative 0000d7 0ee2 add drem16uL,dv16uL ; restore remainder 0000d8 1ef3 adc drem16uH,dv16uH 0000d9 9488 clc ; clear carry to be shifted into result 0000da cff2 rjmp d16u_1 ; else d16u_3: 0000db 9408 sec ; set carry to be shifted into result .INCLUDE "div8u.asm" 0000dc cff0 ;* ;* "div8u" - 8/8 Bit Unsigned Division ;* ;* This subroutine divides the two register variables "dd8u" (dividend) and ;* "dv8u" (divisor). The result is placed in "dres8u" and the remainder in ;* "drem8u". ;* ;* Number of words :14 ;* Number of cycles :97 ;* Low registers used :1 (drem8u) ;* High registers used :3 (dres8u/dd8u,dv8u,dcnt8u) ;* ;*************************************************************************** ;***** Subroutine Register Variables .def drem8u =r15 ;remainder .def dres8u =r16 ;result .def dd8u =r16 ;dividend .def dv8u =r17 ;divisor .def dcnt8u =r18 ;loop counter ;***** Code 0000dd 18ff div8u: sub drem8u,drem8u ;clear remainder and carry 0000de e029 ldi dcnt8u,9 ;init loop counter 0000df 1f00 d8u_1: rol dd8u ;shift left dividend 0000e0 952a dec dcnt8u ;decrement counter 0000e1 f409 brne d8u_2 ;if done 0000e2 9508 ret ; return 0000e3 1cff d8u_2: rol drem8u ;shift dividend into remainder 0000e4 1af1 sub drem8u,dv8u ;remainder = remainder - divisor 0000e5 f418 brcc d8u_3 ;if result negative 0000e6 0ef1 add drem8u,dv8u ; restore remainder 0000e7 9488 clc ; clear carry to be shifted into result 0000e8 cff6 rjmp d8u_1 ;else 0000e9 9408 d8u_3: sec ; set carry to be shifted into result .INCLUDE "mpy16u.asm" 0000ea cff4 ;* ;* "mpy16u" - 16x16 Bit Unsigned Multiplication ;* ;* This subroutine multiplies the two 16-bit register variables ;* mp16uH:mp16uL and mc16uH:mc16uL. ;* The result is placed in m16u3:m16u2:m16u1:m16u0. ;* ;* Number of words :14 + return ;* Number of cycles :153 + return ;* Low registers used :None ;* High registers used :7 (mp16uL,mp16uH,mc16uL/m16u0,mc16uH/m16u1,m16u2, ;* m16u3,mcnt16u) ;* ;*************************************************************************** ;***** Subroutine Register Variables .def mc16uL =r16 ;multiplicand low byte .def mc16uH =r17 ;multiplicand high byte .def mp16uL =r18 ;multiplier low byte .def mp16uH =r19 ;multiplier high byte .def m16u0 =r18 ;result byte 0 (LSB) .def m16u1 =r19 ;result byte 1 .def m16u2 =r20 ;result byte 2 .def m16u3 =r21 ;result byte 3 (MSB) .def mcnt16u =r22 ;loop counter ;***** Code 0000eb 2755 mpy16u: clr m16u3 ;clear 2 highest bytes of result 0000ec 2744 clr m16u2 0000ed e160 ldi mcnt16u,16 ;init loop counter 0000ee 9536 lsr mp16uH 0000ef 9527 ror mp16uL 0000f0 f410 m16u_1: brcc noad8 ;if bit 0 of multiplier set 0000f1 0f40 add m16u2,mc16uL ;add multiplicand Low to byte 2 of res 0000f2 1f51 adc m16u3,mc16uH ;add multiplicand high to byte 3 of res 0000f3 9557 noad8: ror m16u3 ;shift right result byte 3 0000f4 9547 ror m16u2 ;rotate right result byte 2 0000f5 9537 ror m16u1 ;rotate result byte 1 and multiplier High 0000f6 9527 ror m16u0 ;rotate result byte 0 and multiplier Low 0000f7 956a dec mcnt16u ;decrement loop counter 0000f8 f7b9 brne m16u_1 ;if not done, loop more 0000f9 9508 // TEMP_SEND_UART: 0000fa 930f push r16 ; целая часть 0000fb 9100 0069 lds r16, TEMP_L 0000fd 2e50 mov r5, r16 0000fe d00d rcall UART_WR_BYTE ; дробная часть 0000ff 9100 006b lds r16, TEMP_F 000101 2e50 mov r5, r16 000102 d009 rcall UART_WR_BYTE ; состояние реле 000103 b300 in r16, PIND 000104 7001 andi r16, (1< // UART_WR_BYTE: 00010c 9b5d sbis UCSRA, UDRE 00010d cffe rjmp UART_WR_BYTE 00010e b85c out UDR, r5 00010f 9508 ret// // TEMP_COMPARSION: 000110 930f push r16 000111 931f push r17 000112 932f push r18 000113 933f push r19 000114 934f push r20 000115 935f push r21 ; ; lds dd8u, SETTING_HYST ; ldi dv8u, 10 ; rcall div8u ; ; ; определение нижнего и верхнего порого срабатывания ; lds r19, SETTING_INT ; mov r20, r19 ; sub r19, dres8u ; MIN = SET - HYST_INT ; add r20, dres8u ; MAX = SET + HYST_INT ; .DEF temp_r_l = r16 .DEF temp_r_h = r17 .DEF min_r_trhd_l = r11 .DEF min_r_trhd_h = r10 .DEF max_r_trhd_l = r13 .DEF max_r_trhd_h = r12 ; умножаем температуру на 10 000116 9100 0069 lds mc16uL, TEMP_L // r16 000118 9110 006a lds mc16uH, TEMP_H // r17 00011a e02a ldi mp16uL, LOW(10) 00011b e030 ldi mp16uH, HIGH(10) 00011c dfce rcall mpy16u 00011d 2f02 mov temp_r_l, m16u0 ; L 00011e 2f13 mov temp_r_h, m16u1 ; H ; добавляем дробную часть 00011f 9120 006b lds r18, TEMP_F 000121 2733 clr r19 000122 0f02 add temp_r_l, r18 000123 1f13 adc temp_r_h, r19 000124 9310 0071 sts SRAM_TEMP_2, temp_r_h 000126 9300 0072 sts SRAM_TEMP_3, temp_r_l ; определяем нижний и верхний пороги 000128 9140 006d lds r20, SETTING_TEMP_L 00012a 9150 006c lds r21, SETTING_TEMP_H 00012c 9160 006e lds r22, SETTING_HYST 00012e 934f push r20 00012f 935f push r21 000130 2777 clr r23 000131 1b46 sub r20, r22 000132 0b57 sbc r21, r23 000133 2eb4 mov min_r_trhd_l, r20 000134 2ea5 mov min_r_trhd_h, r21 000135 915f pop r21 000136 914f pop r20 000137 2777 clr r23 000138 0f46 add r20, r22 000139 1f57 adc r21, r23 00013a 2ed4 mov max_r_trhd_l, r20 00013b 2ec5 mov max_r_trhd_h, r21 ; определяем знак температуры 00013c f00e brts _NEGATE_TEMP 00013d c004 rjmp _COMPARE _NEGATE_TEMP: 00013e 9500 com temp_r_l 00013f 9510 com temp_r_h 000140 5f0f subi temp_r_l, low(-1) 000141 4f1f sbci temp_r_h, high(-1) _COMPARE: ; проверяем нижний порог 000142 16b0 cp min_r_trhd_l, temp_r_l 000143 06a1 cpc min_r_trhd_h, temp_r_h 000144 f424 brge _MIN_THRESHOLD ; TEMP <= MIN ; проверяем верхний порог 000145 150d cp temp_r_l, max_r_trhd_l 000146 051c cpc temp_r_h, max_r_trhd_h 000147 f44c brge _MAX_THRESHOLD ; TEMP >= TOP 000148 c00f rjmp _COMPARSION_EXIT _MIN_THRESHOLD: ; определяем режим работы 000149 9140 006f lds r20, SETTING_MODE 00014b 2344 tst r20 00014c f411 brne PC+3 00014d 9890 relay_off 00014e c001 rjmp PC+2 00014f 9a90 relay_on 000150 c007 rjmp _COMPARSION_EXIT _MAX_THRESHOLD: 000151 9140 006f lds r20, SETTING_MODE 000153 2344 tst r20 000154 f411 brne PC+3 000155 9a90 relay_on 000156 c001 rjmp PC+2 000157 9890 relay_off _COMPARSION_EXIT: 000158 915f pop r21 000159 914f pop r20 00015a 913f pop r19 00015b 912f pop r18 00015c 911f pop r17 00015d 910f pop r16 00015e 9508 ret// // TEMP_UPD: 00015f 931f push r17 000160 d061 rcall TEMP_CONV 000161 e153 000162 e837 000163 ef4d 000164 d115 DELAY24 800000 000165 d012 rcall TEMP_RD ; обновляем данные в ячейках 000166 9110 0069 lds r17, TEMP_L 000168 2f81 mov DISP_NUM_L, r17 000169 9110 006a lds r17, TEMP_H 00016b 2f91 mov DISP_NUM_H, r17 00016c 911f pop r17 00016d 9508 ret // // RD_F_CODE: 00016e 930f push r16 00016f d078 rcall OW_PRESENCE 000170 e303 ldi r16, DS18B20_CMD_READROM 000171 2e80 mov OW_CMD_r, r16 000172 d08a rcall OW_SEND_BYTE 000173 e7a0 ldi XL, LOW(DEVICE_FAMILY_CODE) 000174 e0b0 ldi XH, HIGH(DEVICE_FAMILY_CODE) 000175 d0a6 rcall OW_RD_BYTE 000176 910f pop r16 000177 9508 ret// // TEMP_RD: 000178 930f push r16 000179 931f push r17 00017a 932f push r18 00017b 933f push r19 00017c 934f push r20 ; cli 00017d d06a rcall OW_PRESENCE 00017e ff70 sbrs OWFR, OWPRF 00017f c03c rjmp _TEMP_RD_EXIT 000180 ec0c ldi r16, DS18B20_CMD_SKIPROM 000181 2e80 mov OW_CMD_r, r16 000182 d07a rcall OW_SEND_BYTE 000183 eb0e ldi r16, DS18B20_CMD_RSCRATCHPAD 000184 2e80 mov OW_CMD_r, r16 000185 d077 rcall OW_SEND_BYTE 000186 e6a9 ldi XL, LOW(TEMP_L) 000187 e0b0 ldi XH, HIGH(TEMP_L) 000188 d093 rcall OW_RD_BYTE 000189 e6aa ldi XL, LOW(TEMP_H) 00018a e0b0 ldi XH, HIGH(TEMP_H) 00018b d090 rcall OW_RD_BYTE 00018c 9110 0069 lds r17, TEMP_L 00018e 9120 006a lds r18, TEMP_H 000190 932f push r18 000191 7f28 cbr r18, (1<<0) | (1<<1) | (1<<2) ; убираем ненужные биты на время (интересуют последних битов в TEMP_H) 000192 3f28 cpi r18, 0xf8 ; проверяется является ли число минусовой 000193 f011 breq _TEMP_RD_TO_UNSIGNED ; если да то конвертируем в беззнаковое число 000194 94e8 clt 000195 c007 rjmp _TEMP_RD_CONTINUE ; если нет то преобразуем значение АЦП в температуру (делим на 16) _TEMP_RD_TO_UNSIGNED: 000196 912f pop r18 000197 9468 set 000198 9510 com r17 000199 9520 com r18 00019a 5f1f subi r17, low(-1) 00019b 4f2f sbci r18, high(-1) ; ldi r19, 1 ; add r17, r19 ; ldi r19, 0 ; adc r18, r19 00019c c001 rjmp PC+2 _TEMP_RD_CONTINUE: ; Температура = Число с АЦП / 16 (сдвиг вправо 4) 00019d 912f pop r18 00019e 9526 lsr r18 00019f 9517 ror r17 0001a0 9526 lsr r18 0001a1 9517 ror r17 0001a2 9526 lsr r18 0001a3 9517 ror r17 0001a4 9526 lsr r18 0001a5 9517 ror r17 _TEMP_RD_END: 0001a6 9130 0069 lds r19, TEMP_L 0001a8 f40e brtc PC+2 0001a9 9531 neg r19 ; переводим в беззнаковое число если минус ; далее происходит такое для получения дробной части: ; ((n<<3) + (n<<1))>>4 или (n*10)/16 0001aa 2f43 mov r20, r19 0001ab 703f andi r19, 0x0f 0001ac 2f43 mov r20, r19 0001ad 0f33 lsl r19 0001ae 0f33 lsl r19 0001af 0f33 lsl r19 0001b0 0f44 lsl r20 0001b1 0f34 add r19, r20 0001b2 9536 lsr r19 0001b3 9536 lsr r19 0001b4 9536 lsr r19 0001b5 9536 lsr r19 ; записываем данные 0001b6 9310 0069 sts TEMP_L, r17 0001b8 9320 006a sts TEMP_H, r18 0001ba 9330 006b sts TEMP_F, r19 ; sei _TEMP_RD_EXIT: 0001bc 914f pop r20 0001bd 913f pop r19 0001be 912f pop r18 0001bf 911f pop r17 0001c0 910f pop r16 0001c1 9508 ret ; TEMP_CONV: 0001c2 930f push r16 ; cli 0001c3 d024 rcall OW_PRESENCE 0001c4 ff70 sbrs OWFR, OWPRF 0001c5 c006 rjmp _TEMP_CONV_EXIT 0001c6 ec0c ldi r16, DS18B20_CMD_SKIPROM 0001c7 2e80 mov OW_CMD_r, r16 0001c8 d034 rcall OW_SEND_BYTE 0001c9 e404 ldi r16, DS18B20_CMD_CONVERTTEMP 0001ca 2e80 mov OW_CMD_r, r16 0001cb d031 rcall OW_SEND_BYTE ; sei _TEMP_CONV_EXIT: 0001cc 910f pop r16 0001cd 9508 ret // // ; **** ОТПРАВКА БАЙТА В СДВИГОВЫЙ РЕГИСТР ************************* USI_TRANSMIT: 0001ce 930f push r16 0001cf b80f out USIDR, r0 ; Байт для отправки всегда находится в регистре r0. Помещаем данные в регистр USIDR. ; Enable USI Overflow Interrupt Flag (will be 0 if transfer is not compeleted) 0001d0 e400 ldi TEMP_REG_A, (1< USI Wire Mode ; USICS1 <--------------> USI Clock Source Select ; USICLK <--------------> USI Clock Strobe ; USITC <--------------> USI Toggle Clock (Enable clock generation) 0001d2 e10b ldi TEMP_REG_A, (1< // SW_CHECK_PROCESS: 0001da 930f push r16 0001db d08a rcall DEBOUNCE_SW 0001dc 9bb2 sbis SW_PIN, SW_PLUS_PIN 0001dd 9601 adiw DISP_NUM_L, 1 0001de 9bb3 sbis SW_PIN, SW_MINUS_PIN 0001df 9701 sbiw DISP_NUM_L, 1 0001e0 9bb4 sbis SW_PIN, SW_SET_PIN 0001e1 c001 rjmp _INTO_DEFAULT_STATE 0001e2 c003 rjmp _SW_CHECK_PROCESS_END _INTO_DEFAULT_STATE: 0001e3 e000 ldi r16, MCU_STATE_DEFAULT 0001e4 9300 0060 sts MCU_STATE, r16 _SW_CHECK_PROCESS_END: 0001e6 910f pop r16 0001e7 9508 ret // // // ; **** ОПРОС ПРИСУТСТВИЯ УСТРОЙСТВА ****************************** OW_PRESENCE: 0001e8 94f8 cli 0001e9 9ab9 ow_pull 0001ea e033 0001eb eb4e 0001ec d089 DELAY16 480 0001ed 98b9 ow_release 0001ee e030 0001ef e84a 0001f0 d085 DELAY16 70 0001f1 d005 rcall OW_CHECK_PRESENCE 0001f2 e033 0001f3 e342 0001f4 d081 DELAY16 410 0001f5 9478 sei 0001f6 9508 ret // // ; **** ПРОВЕРКА НАЛИЧИЯ УСТРОЙСТВА ******************************* ; Если подчиненное устройство притянет шину, то устанавливаем флаг OWPRF в единицу в регистре флагов ; OW_CHECK_PRESENCE: 0001f7 9bb1 sbis OW_PIN, OW_LINE 0001f8 6071 sbr OWFR, (1< // OW_SEND_BYTE: 0001fd 930f push r16 0001fe 931f push r17 0001ff 94f8 cli 000200 2d08 mov r16, OW_CMD_r 000201 e018 ldi r17, 8 _OW_SEND_BYTE_LOOP: 000202 9506 lsr r16 000203 f408 brcc _OW_SEND_0 000204 f048 brcs _OW_SEND_1 _OW_SEND_0: 000205 9ab9 ow_pull 000206 e030 000207 e746 000208 d06d DELAY16 60 000209 98b9 ow_release 00020a e030 00020b e142 00020c d069 DELAY16 10 00020d c008 rjmp _OW_SEND_BYTE_END _OW_SEND_1: 00020e 9ab9 ow_pull 00020f e030 000210 e04a 000211 d064 DELAY16 6 000212 98b9 ow_release 000213 e030 000214 e74e 000215 d060 DELAY16 64 _OW_SEND_BYTE_END: 000216 951a dec r17 000217 f751 brne _OW_SEND_BYTE_LOOP 000218 9478 sei 000219 911f pop r17 00021a 910f pop r16 00021b 9508 ret // // OW_RD_BYTE: 00021c 930f push r16 00021d 931f push r17 00021e 94f8 cli 00021f 2700 clr r16 000220 e018 ldi r17, 8 _OW_RD_BYTE_LP: 000221 9506 lsr r16 000222 9ab9 ow_pull 000223 e030 000224 e04a 000225 d050 DELAY16 6 000226 98b9 ow_release 000227 e030 000228 e140 000229 d04c DELAY16 9 00022a 99b1 sbic OW_PIN, OW_LINE 00022b 6800 sbr r16, (1<<7) 00022c e030 00022d e64c 00022e d047 DELAY16 55 00022f 951a dec r17 000230 f781 brne _OW_RD_BYTE_LP 000231 930c st X, r16 000232 9478 sei 000233 911f pop r17 000234 910f pop r16 000235 9508 ret // // // ; **** ПОЛУЧЕНИЕ ЦИФР ИЗ 16-ТИ БИТНОГО ЧИСЛА ********************* ; Описание: Перемещает цифры числа в соответствующие ячейки памяти в SRAM ; путем деления этого числа несколько раз DISPLAY_UPD_DIGITS: 000236 94f8 cli 000237 935f push r21 000238 e054 ldi r21, 4 ; (4 раза делим) т.к индикатор четырех разрядный ; инициализация указателя (за каждый проход цикла будет инкрементироваться) 000239 e6a3 ldi XL, LOW(DIGITS) 00023a e0b0 ldi XH, HIGH(DIGITS) .equ dividend = SRAM_TEMP_1 ; число которе будем делить .equ divisor = 10 ; на что делим ; загружаем число которое хотим поделить в адрес SRAM делимого 00023b 9380 0061 sts dividend, DISP_NUM_L 00023d 9390 0062 sts dividend+1, DISP_NUM_H ; четыре раза производим деление для получения остатков DIV_LOOP: ; заполняем нужные регистры 00023f 9100 0061 lds dd16uL, dividend 000241 9110 0062 lds dd16uH, dividend+1 000243 e02a ldi dv16uL, LOW(divisor) 000244 e030 ldi dv16uH, HIGH(divisor) 000245 de84 rcall div16u ; делим 000246 92ed st X+, drem16uL ; сохраняем остаток в ячейку по указателю и увеличиваем его ; обновляем делимое 000247 9300 0061 sts dividend, dres16uL 000249 9310 0062 sts dividend+1, dres16uH 00024b 955a dec r21 ; декрементируем счетчик цикла 00024c f791 brne DIV_LOOP ; делим еще раз если не 0 00024d 915f pop r21 00024e 9478 sei 00024f 9508 ret // // ; **** ЗАГРУЖАЕТ НУЖНЫЙ АДРЕС СИМВОЛА В R0 *********************** DISPLAY_DECODER: 000250 930f push r16 000251 931f push r17 000252 e1ee ldi ZL, LOW(2*DISPLAY_SYMBOLS) 000253 e0f5 ldi ZH, HIGH(2*DISPLAY_SYMBOLS) 000254 2711 clr TEMP_REG_B 000255 0fe0 add ZL, TEMP_REG_A 000256 1ff1 adc ZH, TEMP_REG_B 000257 9004 lpm r0, Z 000258 911f pop r17 000259 910f pop r16 00025a 9508 ret// // BEEP_SHORT: 00025b 9ac5 sbi BUZZER_PORT, BUZZER_PIN 00025c d022 rcall DELAY 00025d 98c5 cbi BUZZER_PORT, BUZZER_PIN 00025e 9508 ret // // BEEP_LONG: 00025f 9ac5 sbi BUZZER_PORT, BUZZER_PIN 000260 d01e rcall DELAY 000261 d01d rcall DELAY 000262 d01c rcall DELAY 000263 d01b rcall DELAY 000264 98c5 cbi BUZZER_PORT, BUZZER_PIN 000265 9508 ret// // DEBOUNCE_SW: 000266 930f push r16 000267 931f push r17 000268 932f push r18 000269 e02a ldi r18, 10 _loop_2: 00026a ef1f ldi r17, 255 _loop_0: 00026b ef0f ldi r16, 255 _dec_0: 00026c 950a dec r16 00026d f7f1 brne _dec_0 _loop_1: 00026e 951a dec r17 00026f f7d9 brne _loop_0 _loop_3: 000270 952a dec r18 000271 f7c1 brne _loop_2 000272 912f pop r18 000273 911f pop r17 000274 910f pop r16 000275 9508 ret// // DELAY_LOOP_16: 000276 5041 subi DELAY_8_r, 1 000277 4030 sbci DELAY_16_r, 0 000278 f7e8 brcc DELAY_LOOP_16 000279 9508 ret // // DELAY_LOOP_24: 00027a 5041 subi DELAY_8_r, 1 00027b 4030 sbci DELAY_16_r, 0 00027c 4050 sbci DELAY_24_r, 0 00027d f7e0 brcc DELAY_LOOP_24 00027e 9508 ret // // DELAY: 00027f 930f push r16 000280 931f push r17 000281 932f push r18 000282 e026 ldi r18, 6 _DELAY_0: 000283 ef0f ldi r16, 255 _DELAY_1: 000284 ef1f ldi r17, 255 _DELAY_2: 000285 951a dec r17 000286 f7f1 brne _DELAY_2 000287 950a dec r16 000288 f7d9 brne _DELAY_1 000289 952a dec r18 00028a f7c1 brne _DELAY_0 00028b 912f pop r18 00028c 911f pop r17 00028d 910f pop r16 00028e 9508 ret // // DISPLAY_SYMBOLS: ; HGFEDCBA HGFEDCBA 00028f f9c0 .DB 0b11000000, 0b11111001 ; 0, 1 000290 b0a4 .DB 0b10100100, 0b10110000 ; 2, 3 000291 9299 .DB 0b10011001, 0b10010010 ; 4, 5 000292 f882 .DB 0b10000010, 0b11111000 ; 6, 7 000293 9080 .DB 0b10000000, 0b10010000 ; 8, 9 000294 bf9c .DB 0b10011100, 0b10111111 ; °, -// // // ; **** СЕГМЕНТ EEPROM ******************************************** ; .ESEG ; INFO: .DB "AVR Thermostat. Written by Sergey Yarkov 22.01.2023" ; RESOURCE USE INFORMATION ------------------------ Notice: The register and instruction counts are symbol table hit counts, and hence implicitly used resources are not counted, eg, the 'lpm' instruction without operands implicitly uses r0 and z, none of which are counted. x,y,z are separate entities in the symbol table and are counted separately from r26..r31 here. .dseg memory usage only counts static data declared with .byte "ATtiny2313A" register use summary: x : 2 y : 0 z : 1 r0 : 4 r1 : 2 r2 : 0 r3 : 0 r4 : 0 r5 : 5 r6 : 0 r7 : 0 r8 : 6 r9 : 0 r10: 2 r11: 2 r12: 2 r13: 2 r14: 5 r15: 10 r16: 139 r17: 60 r18: 40 r19: 44 r20: 49 r21: 22 r22: 5 r23: 8 r24: 5 r25: 3 r26: 4 r27: 4 r28: 0 r29: 0 r30: 2 r31: 2 Registers used: 26 out of 35 (74.3%) "ATtiny2313A" instruction use summary: .lds : 0 .sts : 0 adc : 5 add : 7 adiw : 1 and : 0 andi : 2 asr : 0 bclr : 0 bld : 0 brbc : 0 brbs : 0 brcc : 6 brcs : 1 break : 0 breq : 4 brge : 3 brhc : 0 brhs : 0 brid : 0 brie : 0 brlo : 0 brlt : 0 brmi : 0 brne : 22 brpl : 0 brsh : 0 brtc : 1 brts : 2 brvc : 0 brvs : 0 bset : 0 bst : 0 cbi : 25 cbr : 3 clc : 2 clh : 0 cli : 4 cln : 0 clr : 11 cls : 0 clt : 1 clv : 0 clz : 0 com : 4 cp : 2 cpc : 2 cpi : 11 cpse : 0 dec : 12 eor : 0 icall : 0 ijmp : 0 in : 3 inc : 1 ld : 0 ldd : 0 ldi : 83 lds : 27 lpm : 2 lsl : 4 lsr : 11 mov : 22 movw : 0 neg : 1 nop : 0 or : 1 ori : 0 out : 20 pop : 42 push : 41 rcall : 54 ret : 24 reti : 3 rjmp : 31 rol : 6 ror : 9 sbc : 2 sbci : 5 sbi : 14 sbic : 3 sbis : 6 sbiw : 1 sbr : 2 sbrc : 0 sbrs : 2 sec : 2 seh : 0 sei : 4 sen : 0 ser : 0 ses : 0 set : 1 sev : 0 sez : 0 sleep : 0 spm : 0 st : 2 std : 0 sts : 23 sub : 5 subi : 4 swap : 0 tst : 3 wdr : 0 Instructions used: 57 out of 105 (54.3%) "ATtiny2313A" memory use summary [bytes]: Segment Begin End Code Data Used Size Use% --------------------------------------------------------------- [.cseg] 0x000000 0x00052a 1288 12 1300 2048 63.5% [.dseg] 0x000060 0x000073 0 19 19 128 14.8% [.eseg] 0x000000 0x000000 0 0 0 128 0.0% Assembly complete, 0 errors, 21 warnings