AVRASM ver. 2.2.7 main.asm Thu Jun 29 23:01:33 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(354): warning: Register r16 already defined by the .DEF directive main.asm(355): 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 TEMP_L: .BYTE 1 ; Младший байт температуры 000069 TEMP_H: .BYTE 1 ; Старший байт температуры 00006a TEMP_F: .BYTE 1 ; Дробная часть 00006b SETTING_TEMP_H: .BYTE 1 ; Уставка температуры (старший байт) 00006c SETTING_TEMP_L: .BYTE 1 ; Уставка температуры (младший байт) 00006d SETTING_HYST: .BYTE 1 ; Гистерезис: отклонение от уставки 00006e SETTING_MODE: .BYTE 1 ; Режим работы: '1' - нагрев; '0' - 'охлаждение' 00006f DEVICE_FAMILY_CODE: .BYTE 1 ; Должно быть 0x10 для DS18B20 000070 PROGRAM_STEPS: .BYTE 1 ; Текущий "шаг" для настройки (0 - ничего; 1 - уставка T; 2 - гистерезис) 000071 SW_DATA: .BYTE 1 ;// // ; **** СЕГМЕНТ КОДА ********************************************** .CSEG // .ORG 0x00 000000 c06f rjmp RESET_vect .ORG 0x04 000004 9518 reti .ORG 0x000B 00000b c002 rjmp PCINT0_vect .ORG 0x000D 00000d c00d rjmp TIMER0_COMPA_vect // // PCINT0_vect: 00000e 930f push r16 00000f 931f push r17 000010 b70f in r16, SREG 000011 b316 in r17, SW_PIN ; если нажаты две кнопки то входим в режим программирования 000012 701c andi r17, (1< // ; **** ДИНАМИЧЕСКАЯ ИНДИКАЦИЯ ************************************ TIMER0_COMPA_vect: 00001b 930f push r16 00001c 931f push r17 00001d 932f push r18 00001e 933f push r19 00001f 934f push r20 000020 935f push r21 000021 b75f in r21, SREG 000022 9140 0067 lds r20, CURRENT_DIGIT 000024 3045 cpi r20, 5 000025 f40c brge _CLR_CURRENT_DIGIT ; сброс активного разряда если >= 5 000026 c003 rjmp _indicate_1 _CLR_CURRENT_DIGIT: ; сброс текущего активного разряда в ноль 000027 2744 clr r20 000028 9340 0067 sts CURRENT_DIGIT, r20 _indicate_1: 00002a 3040 cpi r20, 0 00002b f481 brne _indicate_2 00002c 9893 cbi PORTD, DIGIT_2_PIN 00002d 9894 cbi PORTD, DIGIT_3_PIN 00002e 9895 cbi PORTD, DIGIT_4_PIN 00002f f00e brts PC+2 000030 c002 rjmp PC+3 000031 e00b ldi TEMP_REG_A, 11 ; // - 000032 c002 rjmp PC+3 000033 9100 0065 lds TEMP_REG_A, DIGITS+2 000035 2300 tst TEMP_REG_A 000036 f011 breq PC+3 000037 9a92 sbi PORTD, DIGIT_1_PIN 000038 c001 rjmp PC+2 000039 9892 cbi PORTD, DIGIT_1_PIN 00003a d2db rcall DISPLAY_DECODER 00003b d19b rcall USI_TRANSMIT _indicate_2: 00003c 3041 cpi r20, 1 00003d f481 brne _indicate_3 00003e 9892 cbi PORTD, DIGIT_1_PIN 00003f 9894 cbi PORTD, DIGIT_3_PIN 000040 9895 cbi PORTD, DIGIT_4_PIN 000041 9100 0064 lds TEMP_REG_A, DIGITS+1 000043 9130 0065 lds r19, DIGITS+2 000045 2b03 or TEMP_REG_A, r19 000046 f011 breq PC+3 000047 9a93 sbi PORTD, DIGIT_2_PIN 000048 c001 rjmp PC+2 000049 9893 cbi PORTD, DIGIT_2_PIN 00004a 9100 0064 lds TEMP_REG_A, DIGITS+1 00004c d2c9 rcall DISPLAY_DECODER 00004d d189 rcall USI_TRANSMIT _indicate_3: 00004e 3042 cpi r20, 2 00004f f459 brne _indicate_4 000050 9892 cbi PORTD, DIGIT_1_PIN 000051 9893 cbi PORTD, DIGIT_2_PIN 000052 9895 cbi PORTD, DIGIT_4_PIN 000053 9a94 sbi PORTD, DIGIT_3_PIN 000054 9100 0063 lds TEMP_REG_A, DIGITS 000056 d2bf rcall DISPLAY_DECODER ; зажигаем точку 000057 2d00 mov r16, r0 000058 770f cbr r16, (1<<7) 000059 2e00 mov r0, r16 00005a d17c rcall USI_TRANSMIT _indicate_4: 00005b 3043 cpi r20, 3 00005c f441 brne _indicate_exit 00005d 9892 cbi PORTD, DIGIT_1_PIN 00005e 9893 cbi PORTD, DIGIT_2_PIN 00005f 9894 cbi PORTD, DIGIT_3_PIN 000060 9a95 sbi PORTD, DIGIT_4_PIN 000061 9100 0066 lds TEMP_REG_A, DIGITS+3 000063 d2b2 rcall DISPLAY_DECODER 000064 d172 rcall USI_TRANSMIT _indicate_exit: 000065 9543 inc r20 000066 9340 0067 sts CURRENT_DIGIT, r20 000068 bf5f out SREG, r21 000069 915f pop r21 00006a 914f pop r20 00006b 913f pop r19 00006c 912f pop r18 00006d 911f pop r17 00006e 910f pop r16 00006f 9518 reti ;// ; **** СТАРТ ПРОГРАММЫ ******************************************* RESET_vect: 000070 ed0f ldi TEMP_REG_A, LOW(RAMEND) 000071 bf0d out SPL, TEMP_REG_A // ; **** ПРОЦЕСС ИНИЦИАЛИЗАЦИИ МК ********************************** MCU_INIT: ; **** ИНИЦИАЛИЗАЦИЯ ПИНОВ ************************************* 000072 e70f 000073 bb01 outi r16, DDRD, (1< // ; **** ГЛАВНЫЙ ЦИКЛ ********************************************** LOOP: 0000b6 9100 0060 lds r16, MCU_STATE ; получаем текущее состояние МК 0000b8 d243 rcall DISPLAY_UPD_DIGITS _STATE_DEFAULT: 0000b9 3000 cpi r16, MCU_STATE_DEFAULT 0000ba f451 brne _STATE_PROGRAM 0000bb 9896 cbi LED_ERR_PORT, LED_ERR_PIN 0000bc 9120 006a lds r18, TEMP_F 0000be 9320 0066 sts DIGITS+3, r18 0000c0 d0a7 rcall TEMP_UPD ; обновление данных о температуре 0000c1 d059 rcall TEMP_COMPARSION ; логика термостата 0000c2 e011 0000c3 bf19 outi r17, 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: 0000cd 24ee clr drem16uL ; clear remainder Low byte 0000ce 18ff sub drem16uH,drem16uH ; clear remainder High byte and carry 0000cf e141 ldi dcnt16u,17 ; init loop counter d16u_1: 0000d0 1f00 rol dd16uL ; shift left dividend 0000d1 1f11 rol dd16uH 0000d2 954a dec dcnt16u ; decrement counter 0000d3 f409 brne d16u_2 ; if done 0000d4 9508 ret ; return d16u_2: 0000d5 1cee rol drem16uL ; shift dividend into remainder 0000d6 1cff rol drem16uH 0000d7 1ae2 sub drem16uL,dv16uL ; remainder = remainder - divisor 0000d8 0af3 sbc drem16uH,dv16uH 0000d9 f420 brcc d16u_3 ; if result negative 0000da 0ee2 add drem16uL,dv16uL ; restore remainder 0000db 1ef3 adc drem16uH,dv16uH 0000dc 9488 clc ; clear carry to be shifted into result 0000dd cff2 rjmp d16u_1 ; else d16u_3: 0000de 9408 sec ; set carry to be shifted into result .INCLUDE "div8u.asm" 0000df 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 0000e0 18ff div8u: sub drem8u,drem8u ;clear remainder and carry 0000e1 e029 ldi dcnt8u,9 ;init loop counter 0000e2 1f00 d8u_1: rol dd8u ;shift left dividend 0000e3 952a dec dcnt8u ;decrement counter 0000e4 f409 brne d8u_2 ;if done 0000e5 9508 ret ; return 0000e6 1cff d8u_2: rol drem8u ;shift dividend into remainder 0000e7 1af1 sub drem8u,dv8u ;remainder = remainder - divisor 0000e8 f418 brcc d8u_3 ;if result negative 0000e9 0ef1 add drem8u,dv8u ; restore remainder 0000ea 9488 clc ; clear carry to be shifted into result 0000eb cff6 rjmp d8u_1 ;else 0000ec 9408 d8u_3: sec ; set carry to be shifted into result .INCLUDE "mpy16u.asm" 0000ed 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 0000ee 2755 mpy16u: clr m16u3 ;clear 2 highest bytes of result 0000ef 2744 clr m16u2 0000f0 e160 ldi mcnt16u,16 ;init loop counter 0000f1 9536 lsr mp16uH 0000f2 9527 ror mp16uL 0000f3 f410 m16u_1: brcc noad8 ;if bit 0 of multiplier set 0000f4 0f40 add m16u2,mc16uL ;add multiplicand Low to byte 2 of res 0000f5 1f51 adc m16u3,mc16uH ;add multiplicand high to byte 3 of res 0000f6 9557 noad8: ror m16u3 ;shift right result byte 3 0000f7 9547 ror m16u2 ;rotate right result byte 2 0000f8 9537 ror m16u1 ;rotate result byte 1 and multiplier High 0000f9 9527 ror m16u0 ;rotate result byte 0 and multiplier Low 0000fa 956a dec mcnt16u ;decrement loop counter 0000fb f7b9 brne m16u_1 ;if not done, loop more 0000fc 9508 // TEMP_SEND_UART: 0000fd 930f push r16 0000fe 931f push r17 ; целая часть 0000ff 9100 0068 lds r16, TEMP_L 000101 2e50 mov r5, r16 000102 d014 rcall UART_WR_BYTE ; дробная часть 000103 9100 006a lds r16, TEMP_F 000105 2e50 mov r5, r16 000106 d010 rcall UART_WR_BYTE ; состояние реле 000107 b300 in r16, PIND 000108 7001 andi r16, (1< // UART_WR_BYTE: 000117 9b5d sbis UCSRA, UDRE 000118 cffe rjmp UART_WR_BYTE 000119 b85c out UDR, r5 00011a 9508 ret// // TEMP_COMPARSION: 00011b 930f push r16 00011c 931f push r17 00011d 932f push r18 00011e 933f push r19 00011f 934f push r20 000120 935f push r21 000121 937f push r23 .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 000122 9100 0068 lds mc16uL, TEMP_L // r16 000124 9110 0069 lds mc16uH, TEMP_H // r17 000126 e02a ldi mp16uL, LOW(10) 000127 e030 ldi mp16uH, HIGH(10) 000128 dfc5 rcall mpy16u 000129 2f02 mov temp_r_l, m16u0 ; L 00012a 2f13 mov temp_r_h, m16u1 ; H ; добавляем дробную часть 00012b 9120 006a lds r18, TEMP_F 00012d 2733 clr r19 00012e 0f02 add temp_r_l, r18 00012f 1f13 adc temp_r_h, r19 ; определяем нижний и верхний пороги 000130 9140 006c lds r20, SETTING_TEMP_L 000132 9150 006b lds r21, SETTING_TEMP_H 000134 9160 006d lds r22, SETTING_HYST 000136 934f push r20 000137 935f push r21 000138 2777 clr r23 000139 1b46 sub r20, r22 00013a 0b57 sbc r21, r23 00013b 2eb4 mov min_r_trhd_l, r20 00013c 2ea5 mov min_r_trhd_h, r21 00013d 915f pop r21 00013e 914f pop r20 00013f 2777 clr r23 000140 0f46 add r20, r22 000141 1f57 adc r21, r23 000142 2ed4 mov max_r_trhd_l, r20 000143 2ec5 mov max_r_trhd_h, r21 ; определяем знак температуры 000144 f00e brts _NEGATE_TEMP 000145 c004 rjmp _COMPARE _NEGATE_TEMP: 000146 9500 com temp_r_l 000147 9510 com temp_r_h 000148 5f0f subi temp_r_l, low(-1) 000149 4f1f sbci temp_r_h, high(-1) _COMPARE: ; проверяем нижний порог 00014a 16b0 cp min_r_trhd_l, temp_r_l 00014b 06a1 cpc min_r_trhd_h, temp_r_h 00014c f424 brge _MIN_THRESHOLD ; TEMP <= MIN ; проверяем верхний порог 00014d 150d cp temp_r_l, max_r_trhd_l 00014e 051c cpc temp_r_h, max_r_trhd_h 00014f f44c brge _MAX_THRESHOLD ; TEMP >= TOP 000150 c00f rjmp _COMPARSION_EXIT _MIN_THRESHOLD: ; определяем режим работы 000151 9140 006e lds r20, SETTING_MODE 000153 2344 tst r20 000154 f411 brne PC+3 000155 9890 relay_off 000156 c001 rjmp PC+2 000157 9a90 relay_on 000158 c007 rjmp _COMPARSION_EXIT _MAX_THRESHOLD: 000159 9140 006e lds r20, SETTING_MODE 00015b 2344 tst r20 00015c f411 brne PC+3 00015d 9a90 relay_on 00015e c001 rjmp PC+2 00015f 9890 relay_off _COMPARSION_EXIT: 000160 917f pop r23 000161 915f pop r21 000162 914f pop r20 000163 913f pop r19 000164 912f pop r18 000165 911f pop r17 000166 910f pop r16 000167 9508 ret// // TEMP_UPD: 000168 931f push r17 000169 d061 rcall TEMP_CONV 00016a e152 00016b e535 00016c eb4d 00016d d1d5 DELAY24 751000 00016e d012 rcall TEMP_RD ; обновляем данные в ячейках 00016f 9110 0068 lds r17, TEMP_L 000171 2f81 mov DISP_NUM_L, r17 000172 9110 0069 lds r17, TEMP_H 000174 2f91 mov DISP_NUM_H, r17 000175 911f pop r17 000176 9508 ret // // RD_F_CODE: 000177 930f push r16 000178 d135 rcall OW_PRESENCE 000179 e303 ldi r16, DS18B20_CMD_READROM 00017a 2e80 mov OW_CMD_r, r16 00017b d147 rcall OW_SEND_BYTE 00017c e6af ldi XL, LOW(DEVICE_FAMILY_CODE) 00017d e0b0 ldi XH, HIGH(DEVICE_FAMILY_CODE) 00017e d163 rcall OW_RD_BYTE 00017f 910f pop r16 000180 9508 ret// // TEMP_RD: 000181 930f push r16 000182 931f push r17 000183 932f push r18 000184 933f push r19 000185 934f push r20 000186 d127 rcall OW_PRESENCE 000187 ff70 sbrs OWFR, OWPRF 000188 c03c rjmp _TEMP_RD_EXIT 000189 ec0c ldi r16, DS18B20_CMD_SKIPROM 00018a 2e80 mov OW_CMD_r, r16 00018b d137 rcall OW_SEND_BYTE 00018c eb0e ldi r16, DS18B20_CMD_RSCRATCHPAD 00018d 2e80 mov OW_CMD_r, r16 00018e d134 rcall OW_SEND_BYTE 00018f e6a8 ldi XL, LOW(TEMP_L) 000190 e0b0 ldi XH, HIGH(TEMP_L) 000191 d150 rcall OW_RD_BYTE 000192 e6a9 ldi XL, LOW(TEMP_H) 000193 e0b0 ldi XH, HIGH(TEMP_H) 000194 d14d rcall OW_RD_BYTE 000195 9110 0068 lds r17, TEMP_L 000197 9120 0069 lds r18, TEMP_H 000199 932f push r18 00019a 7f28 cbr r18, (1<<0) | (1<<1) | (1<<2) ; убираем ненужные биты на время (интересуют последних битов в TEMP_H) 00019b 3f28 cpi r18, 0xf8 ; проверяется является ли число минусовой 00019c f011 breq _TEMP_RD_TO_UNSIGNED ; если да то конвертируем в беззнаковое число 00019d 94e8 clt 00019e c007 rjmp _TEMP_RD_CONTINUE ; если нет то преобразуем значение АЦП в температуру (делим на 16) _TEMP_RD_TO_UNSIGNED: 00019f 912f pop r18 0001a0 9468 set 0001a1 9510 com r17 0001a2 9520 com r18 0001a3 5f1f subi r17, low(-1) 0001a4 4f2f sbci r18, high(-1) ; ldi r19, 1 ; add r17, r19 ; ldi r19, 0 ; adc r18, r19 0001a5 c001 rjmp PC+2 _TEMP_RD_CONTINUE: ; Температура = Число с АЦП / 16 (сдвиг вправо 4) 0001a6 912f pop r18 0001a7 9526 lsr r18 0001a8 9517 ror r17 0001a9 9526 lsr r18 0001aa 9517 ror r17 0001ab 9526 lsr r18 0001ac 9517 ror r17 0001ad 9526 lsr r18 0001ae 9517 ror r17 _TEMP_RD_END: 0001af 9130 0068 lds r19, TEMP_L 0001b1 f40e brtc PC+2 0001b2 9531 neg r19 ; переводим в беззнаковое число если минус ; далее происходит такое для получения дробной части: ; ((n<<3) + (n<<1))>>4 или (n*10)/16 0001b3 2f43 mov r20, r19 0001b4 703f andi r19, 0x0f 0001b5 2f43 mov r20, r19 0001b6 0f33 lsl r19 0001b7 0f33 lsl r19 0001b8 0f33 lsl r19 0001b9 0f44 lsl r20 0001ba 0f34 add r19, r20 0001bb 9536 lsr r19 0001bc 9536 lsr r19 0001bd 9536 lsr r19 0001be 9536 lsr r19 ; записываем данные 0001bf 9310 0068 sts TEMP_L, r17 0001c1 9320 0069 sts TEMP_H, r18 0001c3 9330 006a sts TEMP_F, r19 _TEMP_RD_EXIT: 0001c5 914f pop r20 0001c6 913f pop r19 0001c7 912f pop r18 0001c8 911f pop r17 0001c9 910f pop r16 0001ca 9508 ret ; TEMP_CONV: 0001cb 930f push r16 0001cc d0e1 rcall OW_PRESENCE 0001cd ff70 sbrs OWFR, OWPRF 0001ce c006 rjmp _TEMP_CONV_EXIT 0001cf ec0c ldi r16, DS18B20_CMD_SKIPROM 0001d0 2e80 mov OW_CMD_r, r16 0001d1 d0f1 rcall OW_SEND_BYTE 0001d2 e404 ldi r16, DS18B20_CMD_CONVERTTEMP 0001d3 2e80 mov OW_CMD_r, r16 0001d4 d0ee rcall OW_SEND_BYTE _TEMP_CONV_EXIT: 0001d5 910f pop r16 0001d6 9508 ret // // ; **** ОТПРАВКА БАЙТА В СДВИГОВЫЙ РЕГИСТР ************************* USI_TRANSMIT: 0001d7 930f push r16 0001d8 920f push r0 0001d9 b80f out USIDR, r0 ; Байт для отправки всегда находится в регистре r0. Помещаем данные в регистр USIDR. ; Enable USI Overflow Interrupt Flag (will be 0 if transfer is not compeleted) 0001da 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) 0001dc e10b ldi TEMP_REG_A, (1< BUTTON_PROCESS: 0001e5 930f push r16 _SW_CHECK_ON_0: 0001e6 9bb4 sbis SW_PIN, SW_SET_PIN 0001e7 c001 rjmp _SW_SET_0 0001e8 c01a rjmp _SW_CHECK_ON_1 _SW_SET_0: 0001e9 9100 0071 lds r16, SW_DATA 0001eb 2300 tst r16 0001ec f409 brne _SW_SET_FROM_0_TO_1 0001ed c015 rjmp _SW_CHECK_ON_1 _SW_SET_FROM_0_TO_1: 0001ee 2700 clr r16 0001ef 9300 0071 sts SW_DATA, r16 0001f1 d13d rcall DEBOUNCE_SW 0001f2 9463 inc REPROGRAM_STEP_r 0001f3 2d16 mov r17, REPROGRAM_STEP_r 0001f4 3014 cpi r17, 4 0001f5 f414 brge _SAVE_SETTINGS 0001f6 d12a rcall BEEP_SHORT 0001f7 c00b rjmp _SW_CHECK_ON_1 _SAVE_SETTINGS: 0001f8 e010 0001f9 bf19 outi r17, TIMSK, (0< REPROGRAM_SETTINGS: 000211 930f push r16 000212 931f push r17 000213 932f push r18 000214 933f push r19 000215 934f push r20 000216 2d06 mov r16, REPROGRAM_STEP_r 000217 2300 tst r16 000218 f009 breq _INTO 000219 c002 rjmp _REPROGRAM_SETTINGS_LOOP _INTO: 00021a d106 rcall BEEP_SHORT 00021b 9463 inc REPROGRAM_STEP_r _REPROGRAM_SETTINGS_LOOP: 00021c dfc8 rcall BUTTON_PROCESS _CHECK_STEP: 00021d 3001 cpi r16, 1 00021e f029 breq _STEP_1 00021f 3002 cpi r16, 2 000220 f149 breq _STEP_2 000221 3003 cpi r16, 3 000222 f131 breq _S3_JMP 000223 c084 rjmp _REPROGRAM_SETTINGS_END // _STEP_1: ; установка и отображение гистерезиса 000224 0000 nop _S1_CHECK_PLUS: 000225 9bb2 sbis SW_PIN, SW_PLUS_PIN 000226 c004 rjmp _INCREASE_HYST 000227 c000 rjmp _S1_CHECK_MINUS _S1_CHECK_MINUS: 000228 9bb3 sbis SW_PIN, SW_MINUS_PIN 000229 c00a rjmp _DECREASE_HYST 00022a c011 rjmp _SHOW_HYST _INCREASE_HYST: 00022b d103 rcall DEBOUNCE_SW 00022c 9110 006d lds r17, SETTING_HYST 00022e 3c18 cpi r17, MAX_HYST 00022f f009 breq PC+2 000230 9513 inc r17 000231 9310 006d sts SETTING_HYST, r17 000233 c008 rjmp _SHOW_HYST _DECREASE_HYST: 000234 d0fa rcall DEBOUNCE_SW 000235 9110 006d lds r17, SETTING_HYST 000237 3011 cpi r17, MIN_HYST 000238 f009 breq PC+2 000239 951a dec r17 00023a 9310 006d sts SETTING_HYST, r17 _SHOW_HYST: 00023c 930f push dd8u 00023d 931f push dv8u 00023e 9100 006d lds dd8u, SETTING_HYST 000240 e01a ldi dv8u, 10 000241 de9e rcall div8u 000242 2f80 mov DISP_NUM_L, dres8u 000243 2799 clr DISP_NUM_H ; гистерезис 8 битный так что ноль пишем в старший байт 000244 92f0 0066 sts DIGITS+3, drem8u 000246 911f pop dv8u 000247 910f pop dd8u 000248 c05f rjmp _REPROGRAM_SETTINGS_END // _S3_JMP: ; просто прыжок на _STEP_3 000249 c03f rjmp _STEP_3 // _STEP_2: 00024a 0000 nop _S2_CHECK_PLUS: 00024b 9bb2 sbis SW_PIN, SW_PLUS_PIN 00024c c004 rjmp _INCREASE_TEMP 00024d c000 rjmp _S2_CHECK_MINUS _S2_CHECK_MINUS: 00024e 9bb3 sbis SW_PIN, SW_MINUS_PIN 00024f c00f rjmp _DECREASE_TEMP 000250 c019 rjmp _SHOW_TEMP _INCREASE_TEMP: 000251 d0dd rcall DEBOUNCE_SW 000252 9110 006c lds r17, SETTING_TEMP_L 000254 9120 006b lds r18, SETTING_TEMP_H 000256 e03a ldi r19, 10 000257 0f13 add r17, r19 000258 2733 clr r19 000259 1f23 adc r18, r19 00025a 9310 006c sts SETTING_TEMP_L, r17 00025c 9320 006b sts SETTING_TEMP_H, r18 00025e c00b rjmp _SHOW_TEMP _DECREASE_TEMP: 00025f d0cf rcall DEBOUNCE_SW 000260 9110 006c lds r17, SETTING_TEMP_L 000262 9120 006b lds r18, SETTING_TEMP_H 000264 501a subi r17, 10 000265 4020 sbci r18, 0 000266 9310 006c sts SETTING_TEMP_L, r17 000268 9320 006b sts SETTING_TEMP_H, r18 _SHOW_TEMP: 00026a 930f push dd16uL 00026b 931f push dd16uH 00026c 932f push dv16uL 00026d 933f push dv16uH 00026e 9100 006c lds dd16uL, SETTING_TEMP_L 000270 9110 006b lds dd16uH, SETTING_TEMP_H 000272 2f21 mov r18, dd16uH 000273 7820 andi r18, (1<<7) 000274 f411 brne _NEGATE_SET_TEMP 000275 94e8 clt 000276 c005 rjmp _DIVIDE_SET_TEMP _NEGATE_SET_TEMP: 000277 9468 set 000278 9500 000279 9510 00027a 5f0f 00027b 4f1f com16 dd16uL, dd16uH _DIVIDE_SET_TEMP: 00027c e02a ldi dv16uL, LOW(10) 00027d e030 ldi dv16uH, HIGH(10) 00027e de4e rcall div16u 00027f 2f80 mov DISP_NUM_L, dres16uL 000280 2f91 mov DISP_NUM_H, dres16uH 000281 e00a ldi r16, 10 000282 9300 0066 sts DIGITS+3, r16 ; значок градуса 000284 913f pop dv16uH 000285 912f pop dv16uL 000286 911f pop dd16uH 000287 910f pop dd16uL 000288 c01f rjmp _REPROGRAM_SETTINGS_END // // _STEP_3: 000289 94e8 clt _S3_CHECK_PLUS: 00028a 9bb2 sbis SW_PIN, SW_PLUS_PIN 00028b c004 rjmp _SET_HEAT_MODE 00028c c000 rjmp _S3_CHECK_MINUS _S3_CHECK_MINUS: 00028d 9bb3 sbis SW_PIN, SW_MINUS_PIN 00028e c006 rjmp _SET_COOLING_MODE 00028f c009 rjmp _SHOW_MODE _SET_HEAT_MODE: 000290 d09e rcall DEBOUNCE_SW 000291 e011 ldi r17, HEAT_MODE 000292 9310 006e sts SETTING_MODE, r17 000294 c004 rjmp _SHOW_MODE _SET_COOLING_MODE: 000295 d099 rcall DEBOUNCE_SW 000296 e010 ldi r17, COOLING_MODE 000297 9310 006e sts SETTING_MODE, r17 _SHOW_MODE: 000299 2711 clr r17 00029a 2f81 mov DISP_NUM_L, r17 00029b 2f91 mov DISP_NUM_H, r17 00029c 9120 006e lds r18, SETTING_MODE 00029e 2322 tst r18 00029f f009 breq _SHOW_COOLING 0002a0 c004 rjmp _SHOW_HEATING _SHOW_COOLING: 0002a1 e01c ldi r17, 12 0002a2 9310 0066 sts DIGITS+3, r17 0002a4 c003 rjmp _REPROGRAM_SETTINGS_END _SHOW_HEATING: 0002a5 e01d ldi r17, 13 0002a6 9310 0066 sts DIGITS+3, r17 // _REPROGRAM_SETTINGS_END: 0002a8 914f pop r20 0002a9 913f pop r19 0002aa 912f pop r18 0002ab 911f pop r17 0002ac 910f pop r16 0002ad 9508 ret // ;DBG_LED_TOGGLE: ; push r18 ; push r19 ; in r18, PIND ; ldi r19, (1< // ; **** ОПРОС ПРИСУТСТВИЯ УСТРОЙСТВА ****************************** OW_PRESENCE: 0002ae 94f8 cli 0002af 9ab9 ow_pull 0002b0 e033 0002b1 eb4e 0002b2 d08c DELAY16 480 0002b3 98b9 ow_release 0002b4 e030 0002b5 e84a 0002b6 d088 DELAY16 70 0002b7 d005 rcall OW_CHECK_PRESENCE 0002b8 e033 0002b9 e342 0002ba d084 DELAY16 410 0002bb 9478 sei 0002bc 9508 ret // // ; **** ПРОВЕРКА НАЛИЧИЯ УСТРОЙСТВА ******************************* ; Если подчиненное устройство притянет шину, то устанавливаем флаг OWPRF в единицу в регистре флагов ; OW_CHECK_PRESENCE: 0002bd 9bb1 sbis OW_PIN, OW_LINE 0002be 6071 sbr OWFR, (1< // OW_SEND_BYTE: 0002c3 94f8 cli 0002c4 930f push r16 0002c5 931f push r17 0002c6 2d08 mov r16, OW_CMD_r 0002c7 e018 ldi r17, 8 _OW_SEND_BYTE_LOOP: 0002c8 9506 lsr r16 0002c9 f408 brcc _OW_SEND_0 0002ca f048 brcs _OW_SEND_1 _OW_SEND_0: 0002cb 9ab9 ow_pull 0002cc e030 0002cd e746 0002ce d070 DELAY16 60 0002cf 98b9 ow_release 0002d0 e030 0002d1 e142 0002d2 d06c DELAY16 10 0002d3 c008 rjmp _OW_SEND_BYTE_END _OW_SEND_1: 0002d4 9ab9 ow_pull 0002d5 e030 0002d6 e04a 0002d7 d067 DELAY16 6 0002d8 98b9 ow_release 0002d9 e030 0002da e74e 0002db d063 DELAY16 64 _OW_SEND_BYTE_END: 0002dc 951a dec r17 0002dd f751 brne _OW_SEND_BYTE_LOOP 0002de 911f pop r17 0002df 910f pop r16 0002e0 9478 sei 0002e1 9508 ret // // OW_RD_BYTE: 0002e2 94f8 cli 0002e3 930f push r16 0002e4 931f push r17 0002e5 2700 clr r16 0002e6 e018 ldi r17, 8 _OW_RD_BYTE_LP: 0002e7 9506 lsr r16 0002e8 9ab9 ow_pull 0002e9 e030 0002ea e04a 0002eb d053 DELAY16 6 0002ec 98b9 ow_release 0002ed e030 0002ee e140 0002ef d04f DELAY16 9 0002f0 99b1 sbic OW_PIN, OW_LINE 0002f1 6800 sbr r16, (1<<7) 0002f2 e030 0002f3 e64c 0002f4 d04a DELAY16 55 0002f5 951a dec r17 0002f6 f781 brne _OW_RD_BYTE_LP 0002f7 930c st X, r16 0002f8 911f pop r17 0002f9 910f pop r16 0002fa 9478 sei 0002fb 9508 ret // // // ; **** ПОЛУЧЕНИЕ ЦИФР ИЗ 16-ТИ БИТНОГО ЧИСЛА ********************* ; Описание: Перемещает цифры числа в соответствующие ячейки памяти в SRAM ; путем деления этого числа несколько раз DISPLAY_UPD_DIGITS: 0002fc 930f push r16 0002fd 935f push r21 0002fe e053 ldi r21, 3 ; инициализация указателя (за каждый проход цикла будет инкрементироваться) 0002ff e6a3 ldi XL, LOW(DIGITS) 000300 e0b0 ldi XH, HIGH(DIGITS) .equ dividend = SRAM_TEMP_1 ; число которе будем делить .equ divisor = 10 ; на что делим ; загружаем число которое хотим поделить в адрес SRAM делимого 000301 9380 0061 sts dividend, DISP_NUM_L 000303 9390 0062 sts dividend+1, DISP_NUM_H ; четыре раза производим деление для получения остатков DIV_LOOP: ; заполняем нужные регистры 000305 9100 0061 lds dd16uL, dividend 000307 9110 0062 lds dd16uH, dividend+1 000309 e02a ldi dv16uL, LOW(divisor) 00030a e030 ldi dv16uH, HIGH(divisor) 00030b ddc1 rcall div16u ; делим 00030c 92ed st X+, drem16uL ; сохраняем остаток в ячейку по указателю и увеличиваем его ; обновляем делимое 00030d 9300 0061 sts dividend, dres16uL 00030f 9310 0062 sts dividend+1, dres16uH 000311 955a dec r21 ; декрементируем счетчик цикла 000312 f791 brne DIV_LOOP ; делим еще раз если не 0 000313 915f pop r21 000314 910f pop r16 000315 9508 ret // // ; **** ЗАГРУЖАЕТ НУЖНЫЙ АДРЕС СИМВОЛА В R0 *********************** DISPLAY_DECODER: 000316 930f push r16 000317 931f push r17 000318 ebe0 ldi ZL, LOW(2*DISPLAY_SYMBOLS) 000319 e0f6 ldi ZH, HIGH(2*DISPLAY_SYMBOLS) 00031a 2711 clr TEMP_REG_B 00031b 0fe0 add ZL, TEMP_REG_A 00031c 1ff1 adc ZH, TEMP_REG_B 00031d 9004 lpm r0, Z 00031e 911f pop r17 00031f 910f pop r16 000320 9508 ret // // BEEP_SHORT: 000321 9ac5 sbi BUZZER_PORT, BUZZER_PIN 000322 e053 000323 ea39 000324 e74d 000325 d01d DELAY24 150000 000326 98c5 cbi BUZZER_PORT, BUZZER_PIN 000327 9508 ret // // BEEP_LONG: 000328 9ac5 sbi BUZZER_PORT, BUZZER_PIN 000329 e05c 00032a e334 00032b ef4d 00032c d016 DELAY24 500000 00032d 98c5 cbi BUZZER_PORT, BUZZER_PIN 00032e 9508 ret // // DEBOUNCE_SW: 00032f 930f push r16 000330 931f push r17 000331 932f push r18 000332 e02a ldi r18, 10 _loop_2: 000333 ef1f ldi r17, 255 _loop_0: 000334 ef0f ldi r16, 255 _dec_0: 000335 950a dec r16 000336 f7f1 brne _dec_0 _loop_1: 000337 951a dec r17 000338 f7d9 brne _loop_0 _loop_3: 000339 952a dec r18 00033a f7c1 brne _loop_2 00033b 912f pop r18 00033c 911f pop r17 00033d 910f pop r16 00033e 9508 ret// // DELAY_LOOP_16: 00033f 5041 subi DELAY_8_r, 1 000340 4030 sbci DELAY_16_r, 0 000341 f7e8 brcc DELAY_LOOP_16 000342 9508 ret // // DELAY_LOOP_24: 000343 5041 subi DELAY_8_r, 1 000344 4030 sbci DELAY_16_r, 0 000345 4050 sbci DELAY_24_r, 0 000346 f7e0 brcc DELAY_LOOP_24 000347 9508 ret // // DELAY: 000348 930f push r16 000349 931f push r17 00034a 932f push r18 00034b e026 ldi r18, 6 _DELAY_0: 00034c ef0f ldi r16, 255 _DELAY_1: 00034d ef1f ldi r17, 255 _DELAY_2: 00034e 951a dec r17 00034f f7f1 brne _DELAY_2 000350 950a dec r16 000351 f7d9 brne _DELAY_1 000352 952a dec r18 000353 f7c1 brne _DELAY_0 000354 912f pop r18 000355 911f pop r17 000356 910f pop r16 000357 9508 ret // // DISPLAY_SYMBOLS: ; HGFEDCBA HGFEDCBA 000358 f9c0 .DB 0b11000000, 0b11111001 ; 0, 1 000359 b0a4 .DB 0b10100100, 0b10110000 ; 2, 3 00035a 9299 .DB 0b10011001, 0b10010010 ; 4, 5 00035b f882 .DB 0b10000010, 0b11111000 ; 6, 7 00035c 9080 .DB 0b10000000, 0b10010000 ; 8, 9 00035d bf9c .DB 0b10011100, 0b10111111 ; °, - 00035e 89c6 .DB 0b11000110, 0b10001001 ; C, H // // // ; **** СЕГМЕНТ EEPROM ******************************************** .ESEG 000000 E_SETTING_TEMP_H: .BYTE 1 000001 E_SETTING_TEMP_L: .BYTE 1 000002 E_SETTING_HYST: .BYTE 1 000003 E_SETTING_MODE: .BYTE 1 000004 E_FIRST_TIME_RUN: .BYTE 1 ; 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 : 6 r1 : 2 r2 : 0 r3 : 0 r4 : 0 r5 : 6 r6 : 6 r7 : 0 r8 : 6 r9 : 0 r10: 2 r11: 2 r12: 2 r13: 2 r14: 5 r15: 11 r16: 167 r17: 110 r18: 55 r19: 55 r20: 53 r21: 24 r22: 5 r23: 10 r24: 6 r25: 6 r26: 4 r27: 4 r28: 0 r29: 0 r30: 2 r31: 2 Registers used: 27 out of 35 (77.1%) "ATtiny2313A" instruction use summary: .lds : 0 .sts : 0 adc : 6 add : 8 adiw : 0 and : 0 andi : 4 asr : 0 bclr : 0 bld : 0 brbc : 0 brbs : 0 brcc : 6 brcs : 1 break : 0 breq : 11 brge : 4 brhc : 0 brhs : 0 brid : 0 brie : 0 brlo : 0 brlt : 0 brmi : 0 brne : 26 brpl : 0 brsh : 0 brtc : 1 brts : 2 brvc : 0 brvs : 0 bset : 0 bst : 0 cbi : 29 cbr : 3 clc : 2 clh : 0 cli : 3 cln : 0 clr : 18 cls : 0 clt : 3 clv : 0 clz : 0 com : 6 cp : 2 cpc : 2 cpi : 16 cpse : 0 dec : 14 eor : 0 icall : 0 ijmp : 0 in : 4 inc : 4 ld : 0 ldd : 0 ldi : 100 lds : 39 lpm : 2 lsl : 4 lsr : 11 mov : 31 movw : 0 neg : 1 nop : 2 or : 1 ori : 0 out : 21 pop : 57 push : 56 rcall : 64 ret : 25 reti : 3 rjmp : 58 rol : 6 ror : 9 sbc : 2 sbci : 7 sbi : 14 sbic : 3 sbis : 10 sbiw : 0 sbr : 2 sbrc : 0 sbrs : 2 sec : 2 seh : 0 sei : 3 sen : 0 ser : 2 ses : 0 set : 2 sev : 0 sez : 0 sleep : 0 spm : 0 st : 2 std : 0 sts : 37 sub : 5 subi : 6 swap : 0 tst : 7 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 0x0006be 1692 14 1706 2048 83.3% [.dseg] 0x000060 0x000072 0 18 18 128 14.1% [.eseg] 0x000000 0x000005 0 5 5 128 3.9% Assembly complete, 0 errors, 21 warnings