AVRASM ver. 2.2.7 main.asm Mon Jun 19 15:34:12 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(244): Including file 'div16u.asm' div16u.asm(22): warning: Register r16 already defined by the .DEF directive main.asm(244): 'div16u.asm' included form here div16u.asm(23): warning: Register r17 already defined by the .DEF directive main.asm(244): 'div16u.asm' included form here div16u.asm(24): warning: Register r16 already defined by the .DEF directive main.asm(244): 'div16u.asm' included form here div16u.asm(25): warning: Register r17 already defined by the .DEF directive main.asm(244): 'div16u.asm' included form here div16u.asm(27): warning: Register r19 already defined by the .DEF directive main.asm(244): 'div16u.asm' included form here div16u.asm(28): warning: Register r20 already defined by the .DEF directive main.asm(244): 'div16u.asm' included form here [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(244): Including file 'div16u.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 HYSTERESIS: .BYTE 1 ; Отклонение температуры от уставки 00006a OW_RECEIVE: .BYTE 1 ;// // ; **** СЕГМЕНТ КОДА ********************************************** .CSEG // .ORG 0x00 000000 c049 rjmp RESET_vect .ORG 0x000D 00000d c000 rjmp TIMER0_COMPA_vect // // ; **** ДИНАМИЧЕСКАЯ ИНДИКАЦИЯ ************************************ TIMER0_COMPA_vect: 00000e 934f push r20 00000f 935f push r21 000010 930f push r16 000011 b75f in r21, SREG 000012 9140 0067 lds r20, CURRENT_DIGIT 000014 3045 cpi r20, 5 000015 f40c brge _CLR_CURRENT_DIGIT ; сброс активного разряда если >= 5 000016 c003 rjmp _indicate_1 _CLR_CURRENT_DIGIT: ; сброс текущего активного разряда в ноль 000017 2744 clr r20 000018 9340 0067 sts CURRENT_DIGIT, r20 _indicate_1: 00001a 3040 cpi r20, 0 00001b f441 brne _indicate_2 00001c 9893 cbi PORTD, DIGIT_2_PIN 00001d 9894 cbi PORTD, DIGIT_3_PIN 00001e 9895 cbi PORTD, DIGIT_4_PIN 00001f 9a92 sbi PORTD, DIGIT_1_PIN 000020 9100 0066 lds TEMP_REG_A, DIGITS+3 000022 d116 rcall DISPLAY_DECODER 000023 d09f rcall USI_TRANSMIT _indicate_2: 000024 3041 cpi r20, 1 000025 f441 brne _indicate_3 000026 9892 cbi PORTD, DIGIT_1_PIN 000027 9894 cbi PORTD, DIGIT_3_PIN 000028 9895 cbi PORTD, DIGIT_4_PIN 000029 9a93 sbi PORTD, DIGIT_2_PIN 00002a 9100 0065 lds TEMP_REG_A, DIGITS+2 00002c d10c rcall DISPLAY_DECODER 00002d d095 rcall USI_TRANSMIT _indicate_3: 00002e 3042 cpi r20, 2 00002f f441 brne _indicate_4 000030 9892 cbi PORTD, DIGIT_1_PIN 000031 9893 cbi PORTD, DIGIT_2_PIN 000032 9895 cbi PORTD, DIGIT_4_PIN 000033 9a94 sbi PORTD, DIGIT_3_PIN 000034 9100 0064 lds TEMP_REG_A, DIGITS+1 000036 d102 rcall DISPLAY_DECODER 000037 d08b rcall USI_TRANSMIT _indicate_4: 000038 3043 cpi r20, 3 000039 f441 brne _indicate_exit 00003a 9892 cbi PORTD, DIGIT_1_PIN 00003b 9893 cbi PORTD, DIGIT_2_PIN 00003c 9894 cbi PORTD, DIGIT_3_PIN 00003d 9a95 sbi PORTD, DIGIT_4_PIN 00003e 9100 0063 lds TEMP_REG_A, DIGITS 000040 d0f8 rcall DISPLAY_DECODER 000041 d081 rcall USI_TRANSMIT _indicate_exit: 000042 9543 inc r20 000043 9340 0067 sts CURRENT_DIGIT, r20 000045 bf5f out SREG, r21 000046 910f pop r16 000047 915f pop r21 000048 914f pop r20 000049 9518 reti ;// ; **** СТАРТ ПРОГРАММЫ ******************************************* RESET_vect: 00004a ed0f ldi TEMP_REG_A, LOW(RAMEND) 00004b bf0d out SPL, TEMP_REG_A // ; **** ПРОЦЕСС ИНИЦИАЛИЗАЦИИ МК ********************************** MCU_INIT: ; **** ИНИЦИАЛИЗАЦИЯ ПИНОВ ************************************* 00004c e70e 00004d bb01 outi r16, DDRD, (1< // ; **** ГЛАВНЫЙ ЦИКЛ ********************************************** LOOP: ; rcall DISPLAY_UPD_DIGITS 00006f 9100 0060 lds r16, MCU_STATE ; получаем текущее состояние МК _STATE_DEFAULT: 000071 3000 cpi r16, MCU_STATE_DEFAULT 000072 f479 brne _STATE_PROGRAM 000073 d0ab rcall DISPLAY_UPD_DIGITS ; rcall TEMP_RD 000074 fd70 sbrc OWFR, OWPRF 000075 9a96 sbi PORTD, PD6 000076 ff70 sbrs OWFR, OWPRF 000077 9896 cbi PORTD, PD6 000078 d03e rcall TEMP_CONV 000079 d0ca rcall DEBOUNCE_SW 00007a d0c9 rcall DEBOUNCE_SW 00007b d0c8 rcall DEBOUNCE_SW 00007c d0c7 rcall DEBOUNCE_SW 00007d d02c rcall TEMP_RD 00007e 9110 006a lds r17, OW_RECEIVE 000080 2f81 mov DISP_NUM_L, r17 000081 e090 ldi DISP_NUM_H, 0 _STATE_PROGRAM: 000082 3001 cpi r16, MCU_STATE_PROGRAM 000083 f411 brne _STATE_ERROR 000084 d09a rcall DISPLAY_UPD_DIGITS 000085 d049 rcall SW_CHECK_PROCESS _STATE_ERROR: 000086 3002 cpi r16, MCU_STATE_ERROR 000087 f739 brne LOOP 000088 e01b ldi r17, 11 000089 9310 0063 sts DIGITS, r17 00008b 9310 0064 sts DIGITS+1, r17 00008d 9310 0065 sts DIGITS+2, r17 00008f 9310 0066 sts DIGITS+3, r17 000091 0000 nop 000092 cfdc 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 div16u: 000093 24ee clr drem16uL ; clear remainder Low byte 000094 18ff sub drem16uH,drem16uH ; clear remainder High byte and carry 000095 e141 ldi dcnt16u,17 ; init loop counter d16u_1: 000096 1f00 rol dd16uL ; shift left dividend 000097 1f11 rol dd16uH 000098 954a dec dcnt16u ; decrement counter 000099 f409 brne d16u_2 ; if done 00009a 9508 ret ; return d16u_2: 00009b 1cee rol drem16uL ; shift dividend into remainder 00009c 1cff rol drem16uH 00009d 1ae2 sub drem16uL,dv16uL ; remainder = remainder - divisor 00009e 0af3 sbc drem16uH,dv16uH 00009f f420 brcc d16u_3 ; if result negative 0000a0 0ee2 add drem16uL,dv16uL ; restore remainder 0000a1 1ef3 adc drem16uH,dv16uH 0000a2 9488 clc ; clear carry to be shifted into result 0000a3 cff2 rjmp d16u_1 ; else d16u_3: 0000a4 9408 sec ; set carry to be shifted into result 0000a5 cff0 DELAY_LOOP_16: 0000a6 5041 subi DELAY_8_r, 1 0000a7 4030 sbci DELAY_16_r, 0 0000a8 f7e8 brcc DELAY_LOOP_16 0000a9 9508 ret // TEMP_RD: 0000aa 930f push r16 0000ab 94f8 cli 0000ac d028 rcall OW_PRESENCE 0000ad ec0c ldi r16, DS18B20_CMD_SKIPROM 0000ae 2e80 mov OW_CMD_r, r16 0000af d038 rcall OW_SEND_BYTE 0000b0 eb0e ldi r16, DS18B20_CMD_RSCRATCHPAD 0000b1 2e80 mov OW_CMD_r, r16 0000b2 d035 rcall OW_SEND_BYTE 0000b3 d051 rcall OW_RD_BYTE 0000b4 9478 sei 0000b5 910f pop r16 0000b6 9508 ret ; TEMP_CONV: 0000b7 930f push r16 0000b8 94f8 cli 0000b9 d01b rcall OW_PRESENCE 0000ba ec0c ldi r16, DS18B20_CMD_SKIPROM 0000bb 2e80 mov OW_CMD_r, r16 0000bc d02b rcall OW_SEND_BYTE 0000bd e404 ldi r16, DS18B20_CMD_CONVERTTEMP 0000be 2e80 mov OW_CMD_r, r16 0000bf d028 rcall OW_SEND_BYTE 0000c0 9478 sei 0000c1 910f pop r16 0000c2 9508 ret // // ; **** ОТПРАВКА БАЙТА В СДВИГОВЫЙ РЕГИСТР ************************* USI_TRANSMIT: 0000c3 930f push r16 0000c4 b80f out USIDR, r0 ; Байт для отправки всегда находится в регистре r0. Помещаем данные в регистр USIDR. ; Enable USI Overflow Interrupt Flag (will be 0 if transfer is not compeleted) 0000c5 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) 0000c7 e10b ldi TEMP_REG_A, (1< // SW_CHECK_PROCESS: 0000cf d074 rcall DEBOUNCE_SW 0000d0 9bb2 sbis SW_PIN, SW_PLUS_PIN 0000d1 9601 adiw DISP_NUM_L, 1 0000d2 9bb3 sbis SW_PIN, SW_MINUS_PIN 0000d3 9701 sbiw DISP_NUM_L, 1 0000d4 9508 ret// // // ; **** ОПРОС ПРИСУТСТВИЯ УСТРОЙСТВА ****************************** OW_PRESENCE: 0000d5 9ab9 ow_pull 0000d6 e033 0000d7 eb4e 0000d8 dfcd DELAY16 480 0000d9 98b9 ow_release 0000da e030 0000db e84a 0000dc dfc9 DELAY16 70 0000dd d004 rcall OW_CHECK_PRESENCE 0000de e033 0000df e342 0000e0 dfc5 DELAY16 410 0000e1 9508 ret // // ; **** ПРОВЕРКА НАЛИЧИЯ УСТРОЙСТВА ******************************* ; Если подчиненное устройство притянет шину, то устанавливаем флаг OWPRF в единицу в регистре флагов ; OW_CHECK_PRESENCE: 0000e2 9bb1 sbis OW_PIN, OW_LINE 0000e3 6071 sbr OWFR, (1< // OW_SEND_BYTE: 0000e8 930f push r16 0000e9 931f push r17 0000ea 2d08 mov r16, OW_CMD_r 0000eb e018 ldi r17, 8 _OW_SEND_BYTE_LOOP: 0000ec 9506 lsr r16 0000ed f408 brcc _OW_SEND_0 0000ee f048 brcs _OW_SEND_1 _OW_SEND_0: 0000ef 9ab9 ow_pull 0000f0 e030 0000f1 e746 0000f2 dfb3 DELAY16 60 0000f3 98b9 ow_release 0000f4 e030 0000f5 e142 0000f6 dfaf DELAY16 10 0000f7 c008 rjmp _OW_SEND_BYTE_END _OW_SEND_1: 0000f8 9ab9 ow_pull 0000f9 e030 0000fa e04a 0000fb dfaa DELAY16 6 0000fc 98b9 ow_release 0000fd e030 0000fe e74e 0000ff dfa6 DELAY16 64 _OW_SEND_BYTE_END: 000100 951a dec r17 000101 f751 brne _OW_SEND_BYTE_LOOP 000102 911f pop r17 000103 910f pop r16 000104 9508 ret // // OW_RD_BYTE: 000105 930f push r16 000106 931f push r17 000107 e008 ldi r16, 8 _OW_RD_BYTE_LP: 000108 9ab9 ow_pull 000109 e030 00010a e04a 00010b df9a DELAY16 6 00010c 98b9 ow_release 00010d e030 00010e e140 00010f df96 DELAY16 9 000110 9110 006a lds r17, OW_RECEIVE 000112 9516 lsr r17 000113 99b1 sbic OW_PIN, OW_LINE 000114 6810 sbr r17, (1<<7) 000115 9310 006a sts OW_RECEIVE, r17 000117 e030 000118 e64c 000119 df8c DELAY16 55 00011a 950a dec r16 00011b f761 brne _OW_RD_BYTE_LP 00011c 911f pop r17 00011d 910f pop r16 00011e 9508 ret // // // ; **** ПОЛУЧЕНИЕ ЦИФР ИЗ 16-ТИ БИТНОГО ЧИСЛА ********************* ; Описание: Перемещает цифры числа в соответствующие ячейки памяти в SRAM ; путем деления этого числа несколько раз DISPLAY_UPD_DIGITS: 00011f 94f8 cli 000120 935f push r21 000121 e054 ldi r21, 4 ; (4 раза делим) т.к индикатор четырех разрядный ; инициализация указателя (за каждый проход цикла будет инкрементироваться) 000122 e6a3 ldi XL, LOW(DIGITS) 000123 e0b0 ldi XH, HIGH(DIGITS) .equ dividend = SRAM_TEMP_1 ; число которе будем делить .equ divisor = 10 ; на что делим ; загружаем число которое хотим поделить в адрес SRAM делимого 000124 9380 0061 sts dividend, DISP_NUM_L 000126 9390 0062 sts dividend+1, DISP_NUM_H ; четыре раза производим деление для получения остатков DIV_LOOP: ; заполняем нужные регистры 000128 9100 0061 lds dd16uL, dividend 00012a 9110 0062 lds dd16uH, dividend+1 00012c e02a ldi dv16uL, LOW(divisor) 00012d e030 ldi dv16uH, HIGH(divisor) 00012e df64 rcall div16u ; делим 00012f 92ed st X+, drem16uL ; сохраняем остаток в ячейку по указателю и увеличиваем его ; обновляем делимое 000130 9300 0061 sts dividend, dres16uL 000132 9310 0062 sts dividend+1, dres16uH 000134 955a dec r21 ; декрементируем счетчик цикла 000135 f791 brne DIV_LOOP ; делим еще раз если не 0 000136 915f pop r21 000137 9478 sei 000138 9508 ret // // ; **** ЗАГРУЖАЕТ НУЖНЫЙ АДРЕС СИМВОЛА В R0 *********************** DISPLAY_DECODER: 000139 930f push r16 00013a 931f push r17 00013b ece4 ldi ZL, LOW(2*DISPLAY_SYMBOLS) 00013c e0f2 ldi ZH, HIGH(2*DISPLAY_SYMBOLS) 00013d 2711 clr TEMP_REG_B 00013e 0fe0 add ZL, TEMP_REG_A 00013f 1ff1 adc ZH, TEMP_REG_B 000140 9004 lpm r0, Z 000141 911f pop r17 000142 910f pop r16 000143 9508 ret// // DEBOUNCE_SW: 000144 930f push r16 000145 931f push r17 000146 932f push r18 000147 e02a ldi r18, 10 _loop_2: 000148 ef1f ldi r17, 255 _loop_0: 000149 ef0f ldi r16, 255 _dec_0: 00014a 950a dec r16 00014b f7f1 brne _dec_0 _loop_1: 00014c 951a dec r17 00014d f7d9 brne _loop_0 _loop_3: 00014e 952a dec r18 00014f f7c1 brne _loop_2 000150 912f pop r18 000151 911f pop r17 000152 910f pop r16 000153 9508 ret// // DELAY: 000154 930f push r16 000155 931f push r17 000156 ef0f ldi r16, 255 _DELAY_1: 000157 ef1f ldi r17, 255 _DELAY_2: 000158 951a dec r17 000159 0000 nop 00015a 0000 nop 00015b 0000 nop 00015c f7d9 brne _DELAY_2 00015d 950a dec r16 00015e f7c1 brne _DELAY_1 00015f 911f pop r17 000160 910f pop r16 000161 9508 ret // // DISPLAY_SYMBOLS: ; HGFEDCBA HGFEDCBA 000162 f9c0 .DB 0b11000000, 0b11111001 ; 0, 1 000163 b0a4 .DB 0b10100100, 0b10110000 ; 2, 3 000164 9299 .DB 0b10011001, 0b10010010 ; 4, 5 000165 f882 .DB 0b10000010, 0b11111000 ; 6, 7 000166 9080 .DB 0b10000000, 0b10010000 ; 8, 9 000167 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 : 1 y : 0 z : 1 r0 : 2 r1 : 2 r2 : 0 r3 : 0 r4 : 0 r5 : 0 r6 : 0 r7 : 0 r8 : 5 r9 : 0 r10: 0 r11: 0 r12: 0 r13: 0 r14: 5 r15: 5 r16: 72 r17: 32 r18: 7 r19: 14 r20: 25 r21: 8 r22: 0 r23: 4 r24: 6 r25: 4 r26: 1 r27: 1 r28: 0 r29: 0 r30: 2 r31: 2 Registers used: 20 out of 35 (57.1%) "ATtiny2313A" instruction use summary: .lds : 0 .sts : 0 adc : 2 add : 2 adiw : 1 and : 0 andi : 0 asr : 0 bclr : 0 bld : 0 brbc : 0 brbs : 0 brcc : 3 brcs : 1 break : 0 breq : 0 brge : 1 brhc : 0 brhs : 0 brid : 0 brie : 0 brlo : 0 brlt : 0 brmi : 0 brne : 16 brpl : 0 brsh : 0 brtc : 0 brts : 0 brvc : 0 brvs : 0 bset : 0 bst : 0 cbi : 18 cbr : 1 clc : 1 clh : 0 cli : 3 cln : 0 clr : 5 cls : 0 clt : 0 clv : 0 clz : 0 com : 0 cp : 0 cpc : 0 cpi : 8 cpse : 0 dec : 9 eor : 0 icall : 0 ijmp : 0 in : 1 inc : 1 ld : 0 ldd : 0 ldi : 55 lds : 11 lpm : 2 lsl : 0 lsr : 2 mov : 7 movw : 0 neg : 0 nop : 4 or : 0 ori : 0 out : 12 pop : 18 push : 18 rcall : 43 ret : 14 reti : 1 rjmp : 9 rol : 4 ror : 0 sbc : 1 sbci : 1 sbi : 10 sbic : 2 sbis : 4 sbiw : 1 sbr : 2 sbrc : 1 sbrs : 1 sec : 1 seh : 0 sei : 3 sen : 0 ser : 0 ses : 0 set : 0 sev : 0 sez : 0 sleep : 0 spm : 0 st : 1 std : 0 sts : 14 sub : 2 subi : 1 swap : 0 tst : 0 wdr : 0 Instructions used: 45 out of 105 (42.9%) "ATtiny2313A" memory use summary [bytes]: Segment Begin End Code Data Used Size Use% --------------------------------------------------------------- [.cseg] 0x000000 0x0002d0 684 12 696 2048 34.0% [.dseg] 0x000060 0x00006b 0 11 11 128 8.6% [.eseg] 0x000000 0x000000 0 0 0 128 0.0% Assembly complete, 0 errors, 6 warnings