2454 lines
149 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

AVRASM ver. 2.2.7 main.asm Sat Jul 01 19:34:07 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(312): Including file 'div16u.asm'
div16u.asm(22): warning: Register r16 already defined by the .DEF directive
main.asm(312): 'div16u.asm' included form here
div16u.asm(23): warning: Register r17 already defined by the .DEF directive
main.asm(312): 'div16u.asm' included form here
div16u.asm(24): warning: Register r16 already defined by the .DEF directive
main.asm(312): 'div16u.asm' included form here
div16u.asm(25): warning: Register r17 already defined by the .DEF directive
main.asm(312): 'div16u.asm' included form here
div16u.asm(27): warning: Register r19 already defined by the .DEF directive
main.asm(312): 'div16u.asm' included form here
div16u.asm(28): warning: Register r20 already defined by the .DEF directive
main.asm(312): 'div16u.asm' included form here
main.asm(313): Including file 'div8u.asm'
div8u.asm(18): warning: Register r15 already defined by the .DEF directive
main.asm(313): 'div8u.asm' included form here
div8u.asm(19): warning: Register r16 already defined by the .DEF directive
main.asm(313): 'div8u.asm' included form here
div8u.asm(20): warning: Register r16 already defined by the .DEF directive
main.asm(313): 'div8u.asm' included form here
div8u.asm(21): warning: Register r17 already defined by the .DEF directive
main.asm(313): 'div8u.asm' included form here
div8u.asm(22): warning: Register r18 already defined by the .DEF directive
main.asm(313): 'div8u.asm' included form here
main.asm(314): Including file 'mpy16u.asm'
mpy16u.asm(19): warning: Register r16 already defined by the .DEF directive
main.asm(314): 'mpy16u.asm' included form here
mpy16u.asm(20): warning: Register r17 already defined by the .DEF directive
main.asm(314): 'mpy16u.asm' included form here
mpy16u.asm(21): warning: Register r18 already defined by the .DEF directive
main.asm(314): 'mpy16u.asm' included form here
mpy16u.asm(22): warning: Register r19 already defined by the .DEF directive
main.asm(314): 'mpy16u.asm' included form here
mpy16u.asm(23): warning: Register r18 already defined by the .DEF directive
main.asm(314): 'mpy16u.asm' included form here
mpy16u.asm(24): warning: Register r19 already defined by the .DEF directive
main.asm(314): 'mpy16u.asm' included form here
mpy16u.asm(25): warning: Register r20 already defined by the .DEF directive
main.asm(314): 'mpy16u.asm' included form here
mpy16u.asm(26): warning: Register r21 already defined by the .DEF directive
main.asm(314): 'mpy16u.asm' included form here
main.asm(510): warning: Register r16 already defined by the .DEF directive
main.asm(511): 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(312): Including file 'div16u.asm'
main.asm(313): Including file 'div8u.asm'
main.asm(314): 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<<PB6)+(1<<PB5) ;set PB6 and PB5 (use masks, not bit#)
;* out PORTB,r16 ;output to PORTB
;*
;* in r16,TIFR ;read the Timer Interrupt Flag Register
;* sbrc r16,TOV0 ;test the overflow flag (use bit#)
;* rjmp TOV0_is_set ;jump if set
;* ... ;otherwise do something else
;*************************************************************************
#ifndef _TN2313ADEF_INC_
#define _TN2313ADEF_INC_
#pragma partinc 0
; ***** SPECIFY DEVICE ***************************************************
.device ATtiny2313A
#pragma AVRPART ADMIN PART_NAME ATtiny2313A
.equ SIGNATURE_000 = 0x1e
.equ SIGNATURE_001 = 0x91
.equ SIGNATURE_002 = 0x0a
#pragma AVRPART CORE CORE_VERSION V2
#pragma AVRPART CORE NEW_INSTRUCTIONS lpm rd,z+
; ***** I/O REGISTER DEFINITIONS *****************************************
; NOTE:
; Definitions marked "MEMORY MAPPED"are extended I/O ports
; and cannot be used with IN/OUT instructions
.equ SREG = 0x3f
.equ SPL = 0x3d
.equ OCR0B = 0x3c
.equ GIMSK = 0x3b
.equ EIFR = 0x3a
.equ TIMSK = 0x39
.equ TIFR = 0x38
.equ SPMCSR = 0x37
.equ OCR0A = 0x36
.equ MCUCR = 0x35
.equ MCUSR = 0x34
.equ TCCR0B = 0x33
.equ TCNT0 = 0x32
.equ OSCCAL = 0x31
.equ TCCR0A = 0x30
.equ TCCR1A = 0x2f
.equ TCCR1B = 0x2e
.equ TCNT1L = 0x2c
.equ TCNT1H = 0x2d
.equ OCR1AL = 0x2a
.equ OCR1AH = 0x2b
.equ OCR1BL = 0x28
.equ OCR1BH = 0x29
.equ CLKPR = 0x26
.equ ICR1L = 0x24
.equ ICR1H = 0x25
.equ GTCCR = 0x23
.equ TCCR1C = 0x22
.equ WDTCR = 0x21
.equ PCMSK0 = 0x20
.equ EEAR = 0x1e
.equ EEDR = 0x1d
.equ EECR = 0x1c
.equ PORTA = 0x1b
.equ DDRA = 0x1a
.equ PINA = 0x19
.equ PORTB = 0x18
.equ DDRB = 0x17
.equ PINB = 0x16
.equ GPIOR2 = 0x15
.equ GPIOR1 = 0x14
.equ GPIOR0 = 0x13
.equ PORTD = 0x12
.equ DDRD = 0x11
.equ PIND = 0x10
.equ USIDR = 0x0f
.equ USISR = 0x0e
.equ USICR = 0x0d
.equ UDR = 0x0c
.equ UCSRA = 0x0b
.equ UCSRB = 0x0a
.equ UBRRL = 0x09
.equ ACSR = 0x08
.equ BODCR = 0x07
.equ PRR = 0x06
.equ PCMSK2 = 0x05
.equ PCMSK1 = 0x04
.equ UCSRC = 0x03
.equ UBRRH = 0x02
.equ DIDR = 0x01
; ***** BIT DEFINITIONS **************************************************
; ***** PORTB ************************
; PORTB - Port B Data Register
.equ PORTB0 = 0 ; Port B Data Register bit 0
.equ PB0 = 0 ; For compatibility
.equ PORTB1 = 1 ; Port B Data Register bit 1
.equ PB1 = 1 ; For compatibility
.equ PORTB2 = 2 ; Port B Data Register bit 2
.equ PB2 = 2 ; For compatibility
.equ PORTB3 = 3 ; Port B Data Register bit 3
.equ PB3 = 3 ; For compatibility
.equ PORTB4 = 4 ; Port B Data Register bit 4
.equ PB4 = 4 ; For compatibility
.equ PORTB5 = 5 ; Port B Data Register bit 5
.equ PB5 = 5 ; For compatibility
.equ PORTB6 = 6 ; Port B Data Register bit 6
.equ PB6 = 6 ; For compatibility
.equ PORTB7 = 7 ; Port B Data Register bit 7
.equ PB7 = 7 ; For compatibility
; DDRB - Port B Data Direction Register
.equ DDB0 = 0 ; Port B Data Direction Register bit 0
.equ DDB1 = 1 ; Port B Data Direction Register bit 1
.equ DDB2 = 2 ; Port B Data Direction Register bit 2
.equ DDB3 = 3 ; Port B Data Direction Register bit 3
.equ DDB4 = 4 ; Port B Data Direction Register bit 4
.equ DDB5 = 5 ; Port B Data Direction Register bit 5
.equ DDB6 = 6 ; Port B Data Direction Register bit 6
.equ DDB7 = 7 ; Port B Data Direction Register bit 7
; PINB - Port B Input Pins
.equ PINB0 = 0 ; Port B Input Pins bit 0
.equ PINB1 = 1 ; Port B Input Pins bit 1
.equ PINB2 = 2 ; Port B Input Pins bit 2
.equ PINB3 = 3 ; Port B Input Pins bit 3
.equ PINB4 = 4 ; Port B Input Pins bit 4
.equ PINB5 = 5 ; Port B Input Pins bit 5
.equ PINB6 = 6 ; Port B Input Pins bit 6
.equ PINB7 = 7 ; Port B Input Pins bit 7
; ***** TIMER_COUNTER_0 **************
; TIMSK - Timer/Counter Interrupt Mask Register
.equ OCIE0A = 0 ; Timer/Counter0 Output Compare Match A Interrupt Enable
.equ TOIE0 = 1 ; Timer/Counter0 Overflow Interrupt Enable
.equ OCIE0B = 2 ; Timer/Counter0 Output Compare Match B Interrupt Enable
; TIFR - Timer/Counter Interrupt Flag register
.equ OCF0A = 0 ; Timer/Counter0 Output Compare Flag 0A
.equ TOV0 = 1 ; Timer/Counter0 Overflow Flag
.equ OCF0B = 2 ; Timer/Counter0 Output Compare Flag 0B
; OCR0B - Timer/Counter0 Output Compare Register
.equ OCR0_0 = 0 ;
.equ OCR0_1 = 1 ;
.equ OCR0_2 = 2 ;
.equ OCR0_3 = 3 ;
.equ OCR0_4 = 4 ;
.equ OCR0_5 = 5 ;
.equ OCR0_6 = 6 ;
.equ OCR0_7 = 7 ;
; OCR0A - Timer/Counter0 Output Compare Register
.equ OCR0A_0 = 0 ;
.equ OCR0A_1 = 1 ;
.equ OCR0A_2 = 2 ;
.equ OCR0A_3 = 3 ;
.equ OCR0A_4 = 4 ;
.equ OCR0A_5 = 5 ;
.equ OCR0A_6 = 6 ;
.equ OCR0A_7 = 7 ;
; TCCR0A - Timer/Counter Control Register A
.equ WGM00 = 0 ; Waveform Generation Mode
.equ WGM01 = 1 ; Waveform Generation Mode
.equ COM0B0 = 4 ; Compare Match Output B Mode
.equ COM0B1 = 5 ; Compare Match Output B Mode
.equ COM0A0 = 6 ; Compare Match Output A Mode
.equ COM0A1 = 7 ; Compare Match Output A Mode
; TCNT0 - Timer/Counter0
.equ TCNT0_0 = 0 ;
.equ TCNT0_1 = 1 ;
.equ TCNT0_2 = 2 ;
.equ TCNT0_3 = 3 ;
.equ TCNT0_4 = 4 ;
.equ TCNT0_5 = 5 ;
.equ TCNT0_6 = 6 ;
.equ TCNT0_7 = 7 ;
; TCCR0B - Timer/Counter Control Register B
.equ TCCR0 = TCCR0B ; For compatibility
.equ CS00 = 0 ; Clock Select
.equ CS01 = 1 ; Clock Select
.equ CS02 = 2 ; Clock Select
.equ WGM02 = 3 ;
.equ FOC0B = 6 ; Force Output Compare B
.equ FOC0A = 7 ; Force Output Compare B
; ***** TIMER_COUNTER_1 **************
; TIMSK - Timer/Counter Interrupt Mask Register
.equ ICIE1 = 3 ; Timer/Counter1 Input Capture Interrupt Enable
.equ TICIE = ICIE1 ; For compatibility
.equ OCIE1B = 5 ; Timer/Counter1 Output CompareB Match Interrupt Enable
.equ OCIE1A = 6 ; Timer/Counter1 Output CompareA Match Interrupt Enable
.equ TOIE1 = 7 ; Timer/Counter1 Overflow Interrupt Enable
; TIFR - Timer/Counter Interrupt Flag register
.equ ICF1 = 3 ; Input Capture Flag 1
.equ OCF1B = 5 ; Output Compare Flag 1B
.equ OCF1A = 6 ; Output Compare Flag 1A
.equ TOV1 = 7 ; Timer/Counter1 Overflow Flag
; TCCR1A - Timer/Counter1 Control Register A
.equ WGM10 = 0 ; Pulse Width Modulator Select Bit 0
.equ PWM10 = WGM10 ; For compatibility
.equ WGM11 = 1 ; Pulse Width Modulator Select Bit 1
.equ PWM11 = WGM11 ; For compatibility
.equ COM1B0 = 4 ; Comparet Ouput Mode 1B, bit 0
.equ COM1B1 = 5 ; Compare Output Mode 1B, bit 1
.equ COM1A0 = 6 ; Comparet Ouput Mode 1A, bit 0
.equ COM1A1 = 7 ; Compare Output Mode 1A, bit 1
; TCCR1B - Timer/Counter1 Control Register B
.equ CS10 = 0 ; Clock Select bit 0
.equ CS11 = 1 ; Clock Select 1 bit 1
.equ CS12 = 2 ; Clock Select1 bit 2
.equ WGM12 = 3 ; Waveform Generation Mode Bit 2
.equ CTC1 = WGM12 ; For compatibility
.equ WGM13 = 4 ; Waveform Generation Mode Bit 3
.equ ICES1 = 6 ; Input Capture 1 Edge Select
.equ ICNC1 = 7 ; Input Capture 1 Noise Canceler
; TCCR1C - Timer/Counter1 Control Register C
.equ FOC1B = 6 ; Force Output Compare for Channel B
.equ FOC1A = 7 ; Force Output Compare for Channel A
; ***** WATCHDOG *********************
; WDTCR - Watchdog Timer Control Register
.equ WDTCSR = WDTCR ; For compatibility
.equ WDP0 = 0 ; Watch Dog Timer Prescaler bit 0
.equ WDP1 = 1 ; Watch Dog Timer Prescaler bit 1
.equ WDP2 = 2 ; Watch Dog Timer Prescaler bit 2
.equ WDE = 3 ; Watch Dog Enable
.equ WDCE = 4 ; Watchdog Change Enable
.equ WDTOE = WDCE ; For compatibility
.equ WDP3 = 5 ; Watchdog Timer Prescaler Bit 3
.equ WDIE = 6 ; Watchdog Timeout Interrupt Enable
.equ WDIF = 7 ; Watchdog Timeout Interrupt Flag
; ***** USART ************************
; UDR - USART I/O Data Register
.equ UDR0 = 0 ; USART I/O Data Register bit 0
.equ UDR1 = 1 ; USART I/O Data Register bit 1
.equ UDR2 = 2 ; USART I/O Data Register bit 2
.equ UDR3 = 3 ; USART I/O Data Register bit 3
.equ UDR4 = 4 ; USART I/O Data Register bit 4
.equ UDR5 = 5 ; USART I/O Data Register bit 5
.equ UDR6 = 6 ; USART I/O Data Register bit 6
.equ UDR7 = 7 ; USART I/O Data Register bit 7
; UCSRA - USART Control and Status Register A
.equ USR = UCSRA ; For compatibility
.equ MPCM = 0 ; Multi-processor Communication Mode
.equ U2X = 1 ; Double the USART Transmission Speed
.equ UPE = 2 ; USART Parity Error
.equ PE = UPE ; For compatibility
.equ DOR = 3 ; Data overRun
.equ FE = 4 ; Framing Error
.equ UDRE = 5 ; USART Data Register Empty
.equ TXC = 6 ; USART Transmitt Complete
.equ RXC = 7 ; USART Receive Complete
; UCSRB - USART Control and Status Register B
.equ UCR = UCSRB ; For compatibility
.equ TXB8 = 0 ; Transmit Data Bit 8
.equ RXB8 = 1 ; Receive Data Bit 8
.equ UCSZ2 = 2 ; Character Size
.equ CHR9 = UCSZ2 ; For compatibility
.equ TXEN = 3 ; Transmitter Enable
.equ RXEN = 4 ; Receiver Enable
.equ UDRIE = 5 ; USART Data register Empty Interrupt Enable
.equ TXCIE = 6 ; TX Complete Interrupt Enable
.equ RXCIE = 7 ; RX Complete Interrupt Enable
; UCSRC - USART Control and Status Register C
.equ UCPOL = 0 ; Clock Polarity
.equ UCSZ0 = 1 ; Character Size Bit 0
.equ UCSZ1 = 2 ; Character Size Bit 1
.equ USBS = 3 ; Stop Bit Select
.equ UPM0 = 4 ; Parity Mode Bit 0
.equ UPM1 = 5 ; Parity Mode Bit 1
.equ UMSEL0 = 6 ; USART Mode Select 0
.equ UMSEL1 = 7 ; USART Mode Select 1
.equ UCPHA = 1 ; USART MSPIM Clock Phase
.equ UDORD = 2 ; USART MSPIM Data Order
.equ UBRR = UBRRL ; For compatibility
; ***** ANALOG_COMPARATOR ************
; ACSR - Analog Comparator Control And Status Register
.equ ACIS0 = 0 ; Analog Comparator Interrupt Mode Select bit 0
.equ ACIS1 = 1 ; Analog Comparator Interrupt Mode Select bit 1
.equ ACIC = 2 ;
.equ ACIE = 3 ; Analog Comparator Interrupt Enable
.equ ACI = 4 ; Analog Comparator Interrupt Flag
.equ ACO = 5 ; Analog Compare Output
.equ ACBG = 6 ; Analog Comparator Bandgap Select
.equ ACD = 7 ; Analog Comparator Disable
; DIDR - Digital Input Disable Register 1
.equ AIN0D = 0 ; AIN0 Digital Input Disable
.equ AIN1D = 1 ; AIN1 Digital Input Disable
; ***** PORTD ************************
; PORTD - Data Register, Port D
.equ PORTD0 = 0 ;
.equ PD0 = 0 ; For compatibility
.equ PORTD1 = 1 ;
.equ PD1 = 1 ; For compatibility
.equ PORTD2 = 2 ;
.equ PD2 = 2 ; For compatibility
.equ PORTD3 = 3 ;
.equ PD3 = 3 ; For compatibility
.equ PORTD4 = 4 ;
.equ PD4 = 4 ; For compatibility
.equ PORTD5 = 5 ;
.equ PD5 = 5 ; For compatibility
.equ PORTD6 = 6 ;
.equ PD6 = 6 ; For compatibility
; DDRD - Data Direction Register, Port D
.equ DDD0 = 0 ;
.equ DDD1 = 1 ;
.equ DDD2 = 2 ;
.equ DDD3 = 3 ;
.equ DDD4 = 4 ;
.equ DDD5 = 5 ;
.equ DDD6 = 6 ;
; PIND - Input Pins, Port D
.equ PIND0 = 0 ;
.equ PIND1 = 1 ;
.equ PIND2 = 2 ;
.equ PIND3 = 3 ;
.equ PIND4 = 4 ;
.equ PIND5 = 5 ;
.equ PIND6 = 6 ;
; ***** EEPROM ***********************
; EEAR - EEPROM Read/Write Access
.equ EEARL = EEAR ; For compatibility
.equ EEAR0 = 0 ; EEPROM Read/Write Access bit 0
.equ EEAR1 = 1 ; EEPROM Read/Write Access bit 1
.equ EEAR2 = 2 ; EEPROM Read/Write Access bit 2
.equ EEAR3 = 3 ; EEPROM Read/Write Access bit 3
.equ EEAR4 = 4 ; EEPROM Read/Write Access bit 4
.equ EEAR5 = 5 ; EEPROM Read/Write Access bit 5
.equ EEAR6 = 6 ; EEPROM Read/Write Access bit 6
; EEDR - EEPROM Data Register
.equ EEDR0 = 0 ; EEPROM Data Register bit 0
.equ EEDR1 = 1 ; EEPROM Data Register bit 1
.equ EEDR2 = 2 ; EEPROM Data Register bit 2
.equ EEDR3 = 3 ; EEPROM Data Register bit 3
.equ EEDR4 = 4 ; EEPROM Data Register bit 4
.equ EEDR5 = 5 ; EEPROM Data Register bit 5
.equ EEDR6 = 6 ; EEPROM Data Register bit 6
.equ EEDR7 = 7 ; EEPROM Data Register bit 7
; EECR - EEPROM Control Register
.equ EERE = 0 ; EEPROM Read Enable
.equ EEPE = 1 ; EEPROM Write Enable
.equ EEWE = EEPE ; For compatibility
.equ EEMPE = 2 ; EEPROM Master Write Enable
.equ EEMWE = EEMPE ; For compatibility
.equ EERIE = 3 ; EEProm Ready Interrupt Enable
.equ EEPM0 = 4 ;
.equ EEPM1 = 5 ;
; ***** PORTA ************************
; PORTA - Port A Data Register
.equ PORTA0 = 0 ; Port A Data Register bit 0
.equ PA0 = 0 ; For compatibility
.equ PORTA1 = 1 ; Port A Data Register bit 1
.equ PA1 = 1 ; For compatibility
.equ PORTA2 = 2 ; Port A Data Register bit 2
.equ PA2 = 2 ; For compatibility
; DDRA - Port A Data Direction Register
.equ DDA0 = 0 ; Data Direction Register, Port A, bit 0
.equ DDA1 = 1 ; Data Direction Register, Port A, bit 1
.equ DDA2 = 2 ; Data Direction Register, Port A, bit 2
; PINA - Port A Input Pins
.equ PINA0 = 0 ; Input Pins, Port A bit 0
.equ PINA1 = 1 ; Input Pins, Port A bit 1
.equ PINA2 = 2 ; Input Pins, Port A bit 2
; ***** USI **************************
; USIDR - USI Data Register
.equ USIDR0 = 0 ; USI Data Register bit 0
.equ USIDR1 = 1 ; USI Data Register bit 1
.equ USIDR2 = 2 ; USI Data Register bit 2
.equ USIDR3 = 3 ; USI Data Register bit 3
.equ USIDR4 = 4 ; USI Data Register bit 4
.equ USIDR5 = 5 ; USI Data Register bit 5
.equ USIDR6 = 6 ; USI Data Register bit 6
.equ USIDR7 = 7 ; USI Data Register bit 7
; USISR - USI Status Register
.equ USICNT0 = 0 ; USI Counter Value Bit 0
.equ USICNT1 = 1 ; USI Counter Value Bit 1
.equ USICNT2 = 2 ; USI Counter Value Bit 2
.equ USICNT3 = 3 ; USI Counter Value Bit 3
.equ USIDC = 4 ; Data Output Collision
.equ USIPF = 5 ; Stop Condition Flag
.equ USIOIF = 6 ; Counter Overflow Interrupt Flag
.equ USISIF = 7 ; Start Condition Interrupt Flag
; USICR - USI Control Register
.equ USITC = 0 ; Toggle Clock Port Pin
.equ USICLK = 1 ; Clock Strobe
.equ USICS0 = 2 ; USI Clock Source Select Bit 0
.equ USICS1 = 3 ; USI Clock Source Select Bit 1
.equ USIWM0 = 4 ; USI Wire Mode Bit 0
.equ USIWM1 = 5 ; USI Wire Mode Bit 1
.equ USIOIE = 6 ; Counter Overflow Interrupt Enable
.equ USISIE = 7 ; Start Condition Interrupt Enable
; ***** EXTERNAL_INTERRUPT ***********
; GIMSK - General Interrupt Mask Register
.equ PCIE1 = 3 ;
.equ PCIE2 = 4 ;
.equ PCIE0 = 5 ;
.equ INT0 = 6 ; External Interrupt Request 0 Enable
.equ INT1 = 7 ; External Interrupt Request 1 Enable
; EIFR - Extended Interrupt Flag Register
.equ GIFR = EIFR ; For compatibility
.equ PCIF0 = 5 ;
.equ PCIF2 = 4 ;
.equ PCIF1 = 3 ;
.equ INTF0 = 6 ; External Interrupt Flag 0
.equ INTF1 = 7 ; External Interrupt Flag 1
; PCMSK2 - Pin Change Interrupt Mask Register 2
.equ PCINT11 = 0 ; Pin Change Interrupt Mask 11
.equ PCINT12 = 1 ; Pin Change Interrupt Mask 12
.equ PCINT13 = 2 ; Pin Change Interrupt Mask 13
.equ PCINT14 = 3 ; Pin Change Interrupt Mask 14
.equ PCINT15 = 4 ; Pin Change Interrupt Mask 15
.equ PCINT16 = 5 ; Pin Change Interrupt Mask 16
.equ PCINT17 = 6 ; Pin Change Interrupt Mask 17
; PCMSK1 - Pin Change Interrupt Mask Register 1
.equ PCINT8 = 0 ; Pin Change Interrupt Mask 8
.equ PCINT9 = 1 ; Pin Change Interrupt Mask 9
.equ PCINT10 = 2 ; Pin Change Interrupt Mask 10
; ***** CPU **************************
; SREG - Status Register
.equ SREG_C = 0 ; Carry Flag
.equ SREG_Z = 1 ; Zero Flag
.equ SREG_N = 2 ; Negative Flag
.equ SREG_V = 3 ; Two's Complement Overflow Flag
.equ SREG_S = 4 ; Sign Bit
.equ SREG_H = 5 ; Half Carry Flag
.equ SREG_T = 6 ; Bit Copy Storage
.equ SREG_I = 7 ; Global Interrupt Enable
; SPMCSR - Store Program Memory Control and Status register
.equ SPMEN = 0 ; Store Program Memory Enable
.equ PGERS = 1 ; Page Erase
.equ PGWRT = 2 ; Page Write
.equ RFLB = 3 ; Read Fuse and Lock Bits
.equ CTPB = 4 ; Clear Temporary Page Buffer
; MCUCR - MCU Control Register
.equ ISC00 = 0 ; Interrupt Sense Control 0 bit 0
.equ ISC01 = 1 ; Interrupt Sense Control 0 bit 1
.equ ISC10 = 2 ; Interrupt Sense Control 1 bit 0
.equ ISC11 = 3 ; Interrupt Sense Control 1 bit 1
.equ SM0 = 4 ; Sleep Mode Select Bit 0
.equ SM = SM0 ; For compatibility
.equ SE = 5 ; Sleep Enable
.equ SM1 = 6 ; Sleep Mode Select Bit 1
.equ PUD = 7 ; Pull-up Disable
; CLKPR - Clock Prescale Register
.equ CLKPS0 = 0 ; Clock Prescaler Select Bit 0
.equ CLKPS1 = 1 ; Clock Prescaler Select Bit 1
.equ CLKPS2 = 2 ; Clock Prescaler Select Bit 2
.equ CLKPS3 = 3 ; Clock Prescaler Select Bit 3
.equ CLKPCE = 7 ; Clock Prescaler Change Enable
; MCUSR - MCU Status register
.equ PORF = 0 ; Power-On Reset Flag
.equ EXTRF = 1 ; External Reset Flag
.equ BORF = 2 ; Brown-out Reset Flag
.equ WDRF = 3 ; Watchdog Reset Flag
; OSCCAL - Oscillator Calibration Register
.equ CAL0 = 0 ; Oscillatro Calibration Value Bit 0
.equ CAL1 = 1 ; Oscillatro Calibration Value Bit 1
.equ CAL2 = 2 ; Oscillatro Calibration Value Bit 2
.equ CAL3 = 3 ; Oscillatro Calibration Value Bit 3
.equ CAL4 = 4 ; Oscillatro Calibration Value Bit 4
.equ CAL5 = 5 ; Oscillatro Calibration Value Bit 5
.equ CAL6 = 6 ; Oscillatro Calibration Value Bit 6
; GTCCR - General Timer Counter Control Register
.equ SFIOR = GTCCR ; For compatibility
.equ PSR10 = 0 ;
; PCMSK - Pin-Change Mask register
.equ PCINT0 = 0 ; Pin-Change Interrupt 0
.equ PCINT1 = 1 ; Pin-Change Interrupt 1
.equ PCINT2 = 2 ; Pin-Change Interrupt 2
.equ PCINT3 = 3 ; Pin-Change Interrupt 3
.equ PCINT4 = 4 ; Pin-Change Interrupt 4
.equ PCINT5 = 5 ; Pin-Change Interrupt 5
.equ PCINT6 = 6 ; Pin-Change Interrupt 6
.equ PCINT7 = 7 ; Pin-Change Interrupt 7
; GPIOR2 - General Purpose I/O Register 2
.equ GPIOR20 = 0 ; General Purpose I/O Register 2 bit 0
.equ GPIOR21 = 1 ; General Purpose I/O Register 2 bit 1
.equ GPIOR22 = 2 ; General Purpose I/O Register 2 bit 2
.equ GPIOR23 = 3 ; General Purpose I/O Register 2 bit 3
.equ GPIOR24 = 4 ; General Purpose I/O Register 2 bit 4
.equ GPIOR25 = 5 ; General Purpose I/O Register 2 bit 5
.equ GPIOR26 = 6 ; General Purpose I/O Register 2 bit 6
.equ GPIOR27 = 7 ; General Purpose I/O Register 2 bit 7
; GPIOR1 - General Purpose I/O Register 1
.equ GPIOR10 = 0 ; General Purpose I/O Register 1 bit 0
.equ GPIOR11 = 1 ; General Purpose I/O Register 1 bit 1
.equ GPIOR12 = 2 ; General Purpose I/O Register 1 bit 2
.equ GPIOR13 = 3 ; General Purpose I/O Register 1 bit 3
.equ GPIOR14 = 4 ; General Purpose I/O Register 1 bit 4
.equ GPIOR15 = 5 ; General Purpose I/O Register 1 bit 5
.equ GPIOR16 = 6 ; General Purpose I/O Register 1 bit 6
.equ GPIOR17 = 7 ; General Purpose I/O Register 1 bit 7
; GPIOR0 - General Purpose I/O Register 0
.equ GPIOR00 = 0 ; General Purpose I/O Register 0 bit 0
.equ GPIOR01 = 1 ; General Purpose I/O Register 0 bit 1
.equ GPIOR02 = 2 ; General Purpose I/O Register 0 bit 2
.equ GPIOR03 = 3 ; General Purpose I/O Register 0 bit 3
.equ GPIOR04 = 4 ; General Purpose I/O Register 0 bit 4
.equ GPIOR05 = 5 ; General Purpose I/O Register 0 bit 5
.equ GPIOR06 = 6 ; General Purpose I/O Register 0 bit 6
.equ GPIOR07 = 7 ; General Purpose I/O Register 0 bit 7
; PRR - Power reduction register
.equ PRUSART = 0 ;
.equ PRUSI = 1 ;
.equ PRTIM0 = 2 ;
.equ PRTIM1 = 3 ;
; BODCR - BOD control register
.equ BPDSE = 0 ;
.equ BPDS = 1 ;
; ***** LOCKSBITS ********************************************************
.equ LB1 = 0 ; Lockbit
.equ LB2 = 1 ; Lockbit
; ***** FUSES ************************************************************
; LOW fuse bits
.equ CKSEL0 = 0 ; Select Clock Source
.equ CKSEL1 = 1 ; Select Clock Source
.equ CKSEL2 = 2 ; Select Clock Source
.equ CKSEL3 = 3 ; Select Clock Source
.equ SUT0 = 4 ; Select start-up time
.equ SUT1 = 5 ; Select start-up time
.equ CKOUT = 6 ; Clock output
.equ CKDIV8 = 7 ; Divide clock by 8
; HIGH fuse bits
.equ BODLEVEL0 = 0 ; Brown-out Detector trigger level
.equ BODLEVEL1 = 1 ; Brown-out Detector trigger level
.equ BODLEVEL2 = 2 ; Brown-out Detector trigger level
.equ EESAVE = 3 ; EEPROM memory is preserved through chip erase
.equ WDTON = 4 ; Watchdog Timer Always On
.equ SPIEN = 5 ; Enable Serial programming and Data Downloading
.equ DWEN = 6 ; debugWIRE Enable
.equ RSTDISBL = 7 ; External reset disable
; EXTENDED fuse bits
.equ SELFPRGEN = 0 ; Self Programming Enable
; ***** CPU REGISTER DEFINITIONS *****************************************
.def XH = r27
.def XL = r26
.def YH = r29
.def YL = r28
.def ZH = r31
.def ZL = r30
; ***** DATA MEMORY DECLARATIONS *****************************************
.equ FLASHEND = 0x03ff ; Note: Word address
.equ IOEND = 0x003f
.equ SRAM_START = 0x0060
.equ SRAM_SIZE = 128
.equ RAMEND = 0x00df
.equ XRAMEND = 0x0000
.equ E2END = 0x007f
.equ EEPROMEND = 0x007f
.equ EEADRBITS = 7
#pragma AVRPART MEMORY PROG_FLASH 2048
#pragma AVRPART MEMORY EEPROM 128
#pragma AVRPART MEMORY INT_SRAM SIZE 128
#pragma AVRPART MEMORY INT_SRAM START_ADDR 0x60
; ***** BOOTLOADER DECLARATIONS ******************************************
.equ NRWW_START_ADDR = 0x0
.equ NRWW_STOP_ADDR = 0x3ff
.equ RWW_START_ADDR = 0x0
.equ RWW_STOP_ADDR = 0x0
.equ PAGESIZE = 16
; ***** INTERRUPT VECTORS ************************************************
.equ INT0addr = 0x0001 ; External Interrupt Request 0
.equ INT1addr = 0x0002 ; External Interrupt Request 1
.equ ICP1addr = 0x0003 ; Timer/Counter1 Capture Event
.equ OC1Aaddr = 0x0004 ; Timer/Counter1 Compare Match A
.equ OC1addr = 0x0004 ; For compatibility
.equ OVF1addr = 0x0005 ; Timer/Counter1 Overflow
.equ OVF0addr = 0x0006 ; Timer/Counter0 Overflow
.equ URXCaddr = 0x0007 ; USART, Rx Complete
.equ URXC0addr = 0x0007 ; For compatibility
.equ UDREaddr = 0x0008 ; USART Data Register Empty
.equ UDRE0addr = 0x0008 ; For compatibility
.equ UTXCaddr = 0x0009 ; USART, Tx Complete
.equ UTXC0addr = 0x0009 ; For compatibility
.equ ACIaddr = 0x000a ; Analog Comparator
.equ PCIBaddr = 0x000b ; Pin Change Interrupt Request B
.equ PCIaddr = 0x000b ; For compatibility
.equ OC1Baddr = 0x000c ;
.equ OC0Aaddr = 0x000d ;
.equ OC0Baddr = 0x000e ;
.equ USI_STARTaddr = 0x000f ; USI Start Condition
.equ USI_OVFaddr = 0x0010 ; USI Overflow
.equ ERDYaddr = 0x0011 ;
.equ WDTaddr = 0x0012 ; Watchdog Timer Overflow
.equ PCIAaddr = 0x0013 ; Pin Change Interrupt Request A
.equ PCIDaddr = 0x0014 ; Pin Change Interrupt Request D
.equ INT_VECTORS_SIZE = 21 ; size in words
#endif /* _TN2313ADEF_INC_ */
; ***** END OF FILE ******************************************************
; Project name: thermostat
; Description: Electronic thermostat on AVR Microcontroller
; Source code: https://github.com/sergeyyarkov/attiny2313a_thermostat
; Device: ATtiny2313A
; Device Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/doc8246.pdf
; Assembler: AVR macro assembler 2.2.7
; Clock frequency: 8 MHz External Crystal Oscillator
; Fuses: lfuse: 0xCF, hfuse: 0xDF, efuse: 0xFF, lock: 0xFF
;
; Written by Sergey Yarkov 01.07.2023
.LIST
.INCLUDE "definitions.asm"
.DEF TEMP_REG_A = r16
.DEF TEMP_REG_B = r17
.DEF DELAY_16_r = r19
.DEF DELAY_8_r = r20
.DEF DELAY_24_r = r21
.DEF DISP_NUM_L = r24 ; LSB числа которое сейчас на индикаторе
.DEF DISP_NUM_H = r25 ; MSB числа которое сейчас на индикаторе
.DEF EEP_A_r = r3
.DEF EEP_D_r = r4
.DEF REPROGRAM_STEP_r = r6
.EQU DIGIT_1_PIN = PD2 ; Пин разряда индикатора 1
.EQU DIGIT_2_PIN = PD3 ; Пин разряда индикатора 2
.EQU DIGIT_3_PIN = PD4 ; Пин разряда индикатора 3
.EQU DIGIT_4_PIN = PD5 ; Пин разряда индикатора 4
.EQU LED_PGM_PIN = PD6 ; Светодиод который говорит о том, что МК в состоянии настройки
.EQU LED_PGM_PORT = PORTD
.EQU OW_LINE = PB1 ; Пин шины 1-Wire
.EQU OW_DDR = DDRB
.EQU OW_PIN = PINB
.DEF OW_CMD_r = r8
.DEF OWFR = r23 ; Флаги состояния для 1-Wire интерфейса
.EQU OWPRF = 0 ; 1-Wire Флаг присутствия
.EQU OWSB = 1 ; Флаг передачи одного бита
; **** КОМАНДЫ ДАТЧИКА *****************************************
.EQU DS18B20_CMD_CONVERTTEMP = 0x44
.EQU DS18B20_CMD_RSCRATCHPAD = 0xbe
.EQU DS18B20_CMD_WSCRATCHPAD = 0x4e
.EQU DS18B20_CMD_CPYSCRATCHPAD = 0x48
.EQU DS18B20_CMD_RECEEPROM = 0xb8
.EQU DS18B20_CMD_RPWRSUPPLY = 0xb4
.EQU DS18B20_CMD_SEARCHROM = 0xf0
.EQU DS18B20_CMD_READROM = 0x33
.EQU DS18B20_CMD_MATCHROM = 0x55
.EQU DS18B20_CMD_SKIPROM = 0xcc
.EQU DS18B20_CMD_ALARMSEARCH = 0xec
.EQU USI_LATCH_PIN = PB0 ; ST_CP на 74HC595
.EQU USI_DO_PIN = PB6 ; DS на 74HC595
.EQU USI_CLK_PIN = PB7 ; SH_CP на 74HC595
.EQU SW_PORT = PORTB
.EQU SW_PIN = PINB
.EQU SW_PLUS_PIN = PB2 ; Кнопка "Минус"
.EQU SW_MINUS_PIN = PB3 ; Кнопка "Плюс"
.EQU SW_SET_PIN = PB4 ; Кнопка "Установить"
.EQU BUZZER_PIN = PB5 ; Пищалка
.EQU BUZZER_PORT = PORTB
.EQU RELAY_PIN = PD0 ; Реле
.EQU RELAY_PORT = PORTD
.EQU UART_TX_PIN = PD1
.EQU MCU_STATE_DEFAULT = 0x00 ; Режим измерения температуры и сравнения с заданными параметрами
.EQU MCU_STATE_PROGRAM = 0x01 ; Режим настройки параметров в EEPROM
.EQU MCU_STATE_ERROR = 0x02 ; Режим ошибки, например когда не подключен датчик
.EQU MIN_HYST = 1 ; минимальный гистерезис который можно выставить - 0.1
.EQU MAX_HYST = 200 ; максимальный гистерезис который можно выставить - 20
.EQU MIN_TEMP_H = 0xfe
.EQU MIN_TEMP_L = 0x0c ; минимум -50 градусов уставка
.EQU MAX_TEMP_H = 0x04 ; максимум 120 градусов уставка
.EQU MAX_TEMP_L = 0xb0
; **** СТАНДАРТНЫЕ ПАРАМЕТРЫ ***********************************
.EQU DEFAULT_TEMP = 300 ; 30 градусов
.EQU DEFAULT_HYST = 5 ; 0.5 градусов гистерезис
.EQU HEAT_MODE = 1
.EQU COOLING_MODE = 0
.EQU DEFAULT_MODE = HEAT_MODE
.EQU DEFAULT_SETTING_TEMP_L = LOW(DEFAULT_TEMP)
.EQU DEFAULT_SETTING_TEMP_H = HIGH(DEFAULT_TEMP)
.EQU DEFAULT_SETTING_HYST = DEFAULT_HYST
.EQU DEFAULT_SETTING_MODE = DEFAULT_MODE
.EQU EEP_SETTING_TEMP_H = 0x00
.EQU EEP_SETTING_TEMP_L = 0x01
.EQU EEP_SETTING_HYST = 0x02
.EQU EEP_SETTING_MODE = 0x03
.INCLUDE "macros.asm"
ldi @0, @2
out @1, @0
.ENDMACRO
.MACRO display_load
ldi DISP_NUM_L, LOW(@0)
ldi DISP_NUM_H, HIGH(@0)
.ENDMACRO
.MACRO ow_pull
sbi OW_DDR, OW_LINE
.ENDMACRO
.MACRO ow_release
cbi OW_DDR, OW_LINE
.ENDMACRO
.MACRO relay_on
sbi RELAY_PORT, RELAY_PIN
.ENDMACRO
.MACRO relay_off
cbi RELAY_PORT, RELAY_PIN
.ENDMACRO
; @0 - младший байт
; @1 - старший байт
.MACRO com16
com @0
com @1
subi @0, low(-1)
sbci @1, high(-1)
.ENDMACRO
.MACRO DELAY16
ldi DELAY_16_r, HIGH(@0*F_CPU/4-2)
ldi DELAY_8_r, LOW(@0*F_CPU/4-2)
rcall DELAY_LOOP_16
.ENDMACRO
.MACRO DELAY24
ldi DELAY_24_r, BYTE3(@0*F_CPU/5-3)
ldi DELAY_16_r, HIGH(@0*F_CPU/5-3)
ldi DELAY_8_r, LOW(@0*F_CPU/5-3)
rcall DELAY_LOOP_24
//<editor-fold defaultstate="collapsed" desc="Сегмент данных">
; **** СЕГМЕНТ ДАННЫХ ********************************************
.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
;//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Сегмент кода">
; **** СЕГМЕНТ КОДА **********************************************
.CSEG
//<editor-fold defaultstate="collapsed" desc="Вектора">
.ORG 0x00
000000 c071 rjmp RESET_vect
.ORG 0x04
000004 9518 reti
.ORG 0x000B
00000b c002 rjmp PCINT0_vect
.ORG 0x000D
00000d c012 rjmp TIMER0_COMPA_vect
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Прерывание: изменение состояния пина">
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<<SW_PLUS_PIN) | (1<<SW_MINUS_PIN)
000013 f441 brne _PCINT0_vect_end
000014 9110 0060 lds r17, MCU_STATE
000016 3010 cpi r17, MCU_STATE_DEFAULT
000017 f009 breq _INTO_PROGRAM_STATE
000018 c003 rjmp _PCINT0_vect_end
_INTO_PROGRAM_STATE:
000019 e011 ldi r17, MCU_STATE_PROGRAM
00001a 9310 0060 sts MCU_STATE, r17
_PCINT0_vect_end:
00001c bf0f out SREG, r16
00001d 911f pop r17
00001e 910f pop r16
00001f 9518 reti
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Прерывание: динамическая индикация">
; **** ДИНАМИЧЕСКАЯ ИНДИКАЦИЯ ************************************
TIMER0_COMPA_vect:
000020 930f push r16
000021 931f push r17
000022 932f push r18
000023 933f push r19
000024 934f push r20
000025 935f push r21
000026 b75f in r21, SREG
000027 9140 0067 lds r20, CURRENT_DIGIT
000029 3045 cpi r20, 5
00002a f40c brge _CLR_CURRENT_DIGIT ; сброс активного разряда если >= 5
00002b c003 rjmp _indicate_1
_CLR_CURRENT_DIGIT: ; сброс текущего активного разряда в ноль
00002c 2744 clr r20
00002d 9340 0067 sts CURRENT_DIGIT, r20
_indicate_1:
00002f 3040 cpi r20, 0
000030 f481 brne _indicate_2
000031 9893 cbi PORTD, DIGIT_2_PIN
000032 9894 cbi PORTD, DIGIT_3_PIN
000033 9895 cbi PORTD, DIGIT_4_PIN
000034 f00e brts PC+2
000035 c002 rjmp PC+3
000036 e00b ldi TEMP_REG_A, 11 ; // -
000037 c002 rjmp PC+3
000038 9100 0065 lds TEMP_REG_A, DIGITS+2
00003a 2300 tst TEMP_REG_A
00003b f011 breq PC+3
00003c 9a92 sbi PORTD, DIGIT_1_PIN
00003d c001 rjmp PC+2
00003e 9892 cbi PORTD, DIGIT_1_PIN
00003f d36c rcall DISPLAY_DECODER
000040 d218 rcall USI_TRANSMIT
_indicate_2:
000041 3041 cpi r20, 1
000042 f481 brne _indicate_3
000043 9892 cbi PORTD, DIGIT_1_PIN
000044 9894 cbi PORTD, DIGIT_3_PIN
000045 9895 cbi PORTD, DIGIT_4_PIN
000046 9100 0064 lds TEMP_REG_A, DIGITS+1
000048 9130 0065 lds r19, DIGITS+2
00004a 2b03 or TEMP_REG_A, r19
00004b f011 breq PC+3
00004c 9a93 sbi PORTD, DIGIT_2_PIN
00004d c001 rjmp PC+2
00004e 9893 cbi PORTD, DIGIT_2_PIN
00004f 9100 0064 lds TEMP_REG_A, DIGITS+1
000051 d35a rcall DISPLAY_DECODER
000052 d206 rcall USI_TRANSMIT
_indicate_3:
000053 3042 cpi r20, 2
000054 f441 brne _indicate_4
000055 9892 cbi PORTD, DIGIT_1_PIN
000056 9893 cbi PORTD, DIGIT_2_PIN
000057 9895 cbi PORTD, DIGIT_4_PIN
000058 9a94 sbi PORTD, DIGIT_3_PIN
000059 9100 0063 lds TEMP_REG_A, DIGITS
00005b d350 rcall DISPLAY_DECODER
00005c d1fc rcall USI_TRANSMIT
_indicate_4:
00005d 3043 cpi r20, 3
00005e f441 brne _indicate_exit
00005f 9892 cbi PORTD, DIGIT_1_PIN
000060 9893 cbi PORTD, DIGIT_2_PIN
000061 9894 cbi PORTD, DIGIT_3_PIN
000062 9a95 sbi PORTD, DIGIT_4_PIN
000063 9100 0066 lds TEMP_REG_A, DIGITS+3
000065 d346 rcall DISPLAY_DECODER
000066 d1f2 rcall USI_TRANSMIT
_indicate_exit:
000067 9543 inc r20
000068 9340 0067 sts CURRENT_DIGIT, r20
00006a bf5f out SREG, r21
00006b 915f pop r21
00006c 914f pop r20
00006d 913f pop r19
00006e 912f pop r18
00006f 911f pop r17
000070 910f pop r16
000071 9518 reti
;//</editor-fold>
; **** СТАРТ ПРОГРАММЫ *******************************************
RESET_vect:
000072 ed0f ldi TEMP_REG_A, LOW(RAMEND)
000073 bf0d out SPL, TEMP_REG_A
//<editor-fold defaultstate="collapsed" desc="Инициализация МК (настрока портов и переферии)">
; **** ПРОЦЕСС ИНИЦИАЛИЗАЦИИ МК **********************************
MCU_INIT:
; **** ИНИЦИАЛИЗАЦИЯ ПИНОВ *************************************
000074 e70f
000075 bb01 outi r16, DDRD, (1<<LED_PGM_PIN) | (1<<DIGIT_1_PIN) | (1<<DIGIT_2_PIN) | (1<<DIGIT_3_PIN) | (1<<DIGIT_4_PIN) | (1<<UART_TX_PIN) | (1<<RELAY_PIN)
000076 ee01
000077 bb07 outi r16, DDRB, (1<<USI_CLK_PIN) | (1<<USI_DO_PIN) | (1<<USI_LATCH_PIN) | (0<<SW_PLUS_PIN) | (0<<SW_MINUS_PIN) | (0<<SW_SET_PIN) | (1<<BUZZER_PIN)
000078 e10c
000079 bb08 outi r16, PORTB, (1<<SW_PLUS_PIN) | (1<<SW_MINUS_PIN) | (1<<SW_SET_PIN)
; **** ИНИЦИАЛИЗАЦИЯ ТАЙМЕРА 0 (8 бит) *************************
00007a e002
00007b bf00 outi r16, TCCR0A, (1<<WGM01) ; режим CTC Compare A
00007c e005
00007d bf03 outi r16, TCCR0B, (1<<CS02) | (1<<CS00) ; 1024 делитель
00007e e203
00007f bf06 outi r16, OCR0A, 35 ; число для сравнения. (~60Hz)
; **** ПРЕРЫВАНИЕ ПО ИЗМЕНЕНИЮ СОСТОЯНИЯ ПИНОВ ******************
000080 e200
000081 bf0b outi r16, GIMSK, (1<<PCIE0)
000082 e10c
000083 bd00 outi r16, PCMSK0, (1<<PCINT2) | (1<<PCINT3) | (1<<PCINT4) ; для кнопок
; **** ИНИЦИАЛИЗАЦИЯ USART **************************************
000084 e303
000085 b909 outi r16, UBRRL, LOW(51) ; 9600 БОД
000086 e000
000087 b902 outi r16, UBRRH, HIGH(51) ; 9600 БОД
000088 e008
000089 b90a outi r16, UCSRB, (1<<TXEN) ; Включение передачии
00008a e006
00008b b903 outi r16, UCSRC, (1<<UCSZ1) | (1<<UCSZ0) ; Асинхронный режим, 8 бит фрейм, 1 стоповый бит
; **** ИНИЦИАЛИЗАЦИЯ ДАННЫХ В ОЗУ ******************************
00008c 2411 clr r1
00008d 9210 0067 sts CURRENT_DIGIT, r1
00008f e000 ldi r16, 0x00
000090 9300 0060 sts MCU_STATE, r16 ; переводим МК сразу в режим измерения температуры
; проверяем впервые ли запускаем устройство
000092 e004 ldi r16, EEP_FIRST_TIME_RUN
000093 2e30 mov EEP_A_r, r16
000094 d100 rcall EEP_RD_BYTE
000095 2d04 mov r16, EEP_D_r
000096 3100 cpi r16, 0x10 ; 0x10 - зарезервированное число которое говорит о том что устройство запускается НЕ впервые
000097 f011 breq _INIT_PARAMS
_FIRST_TIME_RUN: ; если устройство запускается впервые то записываем в EEPROM и ОЗУ стандартные параметры
000098 d0b2 rcall INIT_DEFAULT_PARAMS
000099 c014 rjmp _CONTINUE_INIT
_INIT_PARAMS: ; иначе берем из EEPROM настройки и записываем в ОЗУ
00009a e000 ldi r16, EEP_SETTING_TEMP_H
00009b 2e30 mov EEP_A_r, r16
00009c d0f8 rcall EEP_RD_BYTE
00009d 9240 006b sts SETTING_TEMP_H, EEP_D_r
00009f e001 ldi r16, EEP_SETTING_TEMP_L
0000a0 2e30 mov EEP_A_r, r16
0000a1 d0f3 rcall EEP_RD_BYTE
0000a2 9240 006c sts SETTING_TEMP_L, EEP_D_r
0000a4 e002 ldi r16, EEP_SETTING_HYST
0000a5 2e30 mov EEP_A_r, r16
0000a6 d0ee rcall EEP_RD_BYTE
0000a7 9240 006d sts SETTING_HYST, EEP_D_r
0000a9 e003 ldi r16, EEP_SETTING_MODE
0000aa 2e30 mov EEP_A_r, r16
0000ab d0e9 rcall EEP_RD_BYTE
0000ac 9240 006e sts SETTING_MODE, EEP_D_r
_CONTINUE_INIT:
0000ae 2700 clr r16
0000af 9300 0068 sts TEMP_L, r16
0000b1 9300 0069 sts TEMP_H, r16
0000b3 ef00 ldi r16, 0xf0
0000b4 9300 006a sts TEMP_F, r16
0000b6 ef0f ser r16
0000b7 9300 0071 sts SW_DATA, r16
0000b9 2466 clr REPROGRAM_STEP_r
; **** СТАРТУЕМ ************************************************
0000ba d13e rcall RD_F_CODE ; проверяем что датчик есть на шине
0000bb 9100 006f lds r16, DEVICE_FAMILY_CODE
0000bd 3208 cpi r16, 0x28 ; код семейства для DS18B20 = 0x28
0000be f409 brne ERR_FAMILY_CODE
0000bf c005 rjmp START_PROGRAM
ERR_FAMILY_CODE:
0000c0 e012 ldi r17, MCU_STATE_ERROR
0000c1 9310 0060 sts MCU_STATE, r17
0000c3 d30f rcall BEEP_LONG
0000c4 c001 rjmp PC+2
START_PROGRAM:
0000c5 d306 rcall BEEP_SHORT
0000c6 e080
0000c7 e090 display_load 0
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Главный цикл">
; **** ГЛАВНЫЙ ЦИКЛ **********************************************
LOOP:
0000c8 9100 0060 lds r16, MCU_STATE ; получаем текущее состояние МК
_STATE_DEFAULT:
0000ca 3000 cpi r16, MCU_STATE_DEFAULT
0000cb f451 brne _STATE_PROGRAM
0000cc 9120 006a lds r18, TEMP_F
0000ce 9320 0066 sts DIGITS+3, r18
0000d0 d119 rcall TEMP_UPD ; обновление данных о температуре
0000d1 d2c0 rcall DISPLAY_UPD_DIGITS
0000d2 d0ca rcall TEMP_COMPARSION ; логика термостата
0000d3 e011
0000d4 bf19 outi r17, TIMSK, (1<<OCIE0A) ; вкл. индикатор
0000d5 d041 rcall TEMP_SEND_UART ; отпрака данных в UART
_STATE_PROGRAM:
0000d6 3001 cpi r16, MCU_STATE_PROGRAM
0000d7 f409 brne _STATE_ERROR
0000d8 d1bc rcall REPROGRAM_SETTINGS
_STATE_ERROR:
0000d9 3002 cpi r16, MCU_STATE_ERROR
0000da f769 brne LOOP
0000db e01b ldi r17, 11
0000dc 9310 0063 sts DIGITS, r17
0000de 9310 0064 sts DIGITS+1, r17
0000e0 9310 0065 sts DIGITS+2, r17
0000e2 9310 0066 sts DIGITS+3, r17
0000e4 e011
0000e5 bf19 outi r17, TIMSK, (1<<OCIE0A)
0000e6 cfe1 rjmp LOOP
//</editor-fold>
; **** ПОДПРОГРАММЫ **********************************************
.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:
0000e7 24ee clr drem16uL ; clear remainder Low byte
0000e8 18ff sub drem16uH,drem16uH ; clear remainder High byte and carry
0000e9 e141 ldi dcnt16u,17 ; init loop counter
d16u_1:
0000ea 1f00 rol dd16uL ; shift left dividend
0000eb 1f11 rol dd16uH
0000ec 954a dec dcnt16u ; decrement counter
0000ed f409 brne d16u_2 ; if done
0000ee 9508 ret ; return
d16u_2:
0000ef 1cee rol drem16uL ; shift dividend into remainder
0000f0 1cff rol drem16uH
0000f1 1ae2 sub drem16uL,dv16uL ; remainder = remainder - divisor
0000f2 0af3 sbc drem16uH,dv16uH
0000f3 f420 brcc d16u_3 ; if result negative
0000f4 0ee2 add drem16uL,dv16uL ; restore remainder
0000f5 1ef3 adc drem16uH,dv16uH
0000f6 9488 clc ; clear carry to be shifted into result
0000f7 cff2 rjmp d16u_1 ; else
d16u_3:
0000f8 9408 sec ; set carry to be shifted into result
.INCLUDE "div8u.asm"
0000f9 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
0000fa 18ff div8u: sub drem8u,drem8u ;clear remainder and carry
0000fb e029 ldi dcnt8u,9 ;init loop counter
0000fc 1f00 d8u_1: rol dd8u ;shift left dividend
0000fd 952a dec dcnt8u ;decrement counter
0000fe f409 brne d8u_2 ;if done
0000ff 9508 ret ; return
000100 1cff d8u_2: rol drem8u ;shift dividend into remainder
000101 1af1 sub drem8u,dv8u ;remainder = remainder - divisor
000102 f418 brcc d8u_3 ;if result negative
000103 0ef1 add drem8u,dv8u ; restore remainder
000104 9488 clc ; clear carry to be shifted into result
000105 cff6 rjmp d8u_1 ;else
000106 9408 d8u_3: sec ; set carry to be shifted into result
.INCLUDE "mpy16u.asm"
000107 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
000108 2755 mpy16u: clr m16u3 ;clear 2 highest bytes of result
000109 2744 clr m16u2
00010a e160 ldi mcnt16u,16 ;init loop counter
00010b 9536 lsr mp16uH
00010c 9527 ror mp16uL
00010d f410 m16u_1: brcc noad8 ;if bit 0 of multiplier set
00010e 0f40 add m16u2,mc16uL ;add multiplicand Low to byte 2 of res
00010f 1f51 adc m16u3,mc16uH ;add multiplicand high to byte 3 of res
000110 9557 noad8: ror m16u3 ;shift right result byte 3
000111 9547 ror m16u2 ;rotate right result byte 2
000112 9537 ror m16u1 ;rotate result byte 1 and multiplier High
000113 9527 ror m16u0 ;rotate result byte 0 and multiplier Low
000114 956a dec mcnt16u ;decrement loop counter
000115 f7b9 brne m16u_1 ;if not done, loop more
000116 9508
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: отправка данных в UART">
TEMP_SEND_UART:
000117 930f push r16
000118 931f push r17
; целая часть
000119 9100 0068 lds r16, TEMP_L
00011b 2e50 mov r5, r16
00011c d02a rcall UART_WR_BYTE
; дробная часть
00011d 9100 006a lds r16, TEMP_F
00011f 2e50 mov r5, r16
000120 d026 rcall UART_WR_BYTE
; состояние реле
000121 b300 in r16, PIND
000122 7001 andi r16, (1<<RELAY_PIN)
000123 2e50 mov r5, r16
000124 d022 rcall UART_WR_BYTE
; гистерезис
000125 9100 006d lds r16, SETTING_HYST
000127 2e50 mov r5, r16
000128 d01e rcall UART_WR_BYTE
; уставка HIGH
000129 9100 006b lds r16, SETTING_TEMP_H
00012b 2e50 mov r5, r16
00012c d01a rcall UART_WR_BYTE
; уставка LOW
00012d 9100 006c lds r16, SETTING_TEMP_L
00012f 2e50 mov r5, r16
000130 d016 rcall UART_WR_BYTE
; режим работы
000131 9100 006e lds r16, SETTING_MODE
000133 2e50 mov r5, r16
000134 d012 rcall UART_WR_BYTE
; состояние МК
000135 9100 0060 lds r16, MCU_STATE
000137 2e50 mov r5, r16
000138 d00e rcall UART_WR_BYTE
; статусный регистр МК
000139 b65f in r5, SREG
00013a d00c rcall UART_WR_BYTE
00013b e004 ldi r16, 0x04 ; EOT (End Of Transmission)
00013c 2e50 mov r5, r16
00013d d009 rcall UART_WR_BYTE
00013e 2700 clr r16
00013f 2e50 mov r5, r16
000140 e016 ldi r17, 6
_TEMP_SEND_UART_L:
000141 d005 rcall UART_WR_BYTE
000142 951a dec r17
000143 f7e9 brne _TEMP_SEND_UART_L
000144 911f pop r17
000145 910f pop r16
000146 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: отправка байта в UART из регистра r5">
UART_WR_BYTE:
000147 9b5d sbis UCSRA, UDRE
000148 cffe rjmp UART_WR_BYTE
000149 b85c out UDR, r5
00014a 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: инициализация стандартных параметров">
INIT_DEFAULT_PARAMS:
00014b e001 ldi r16, DEFAULT_SETTING_TEMP_H
00014c 9300 006b sts SETTING_TEMP_H, r16 ; уставка HIGH
00014e 2e40 mov EEP_D_r, r16
00014f e000 ldi r16, EEP_SETTING_TEMP_H
000150 2e30 mov EEP_A_r, r16
000151 d036 rcall EEP_WR_BYTE
000152 e20c ldi r16, DEFAULT_SETTING_TEMP_L
000153 9300 006c sts SETTING_TEMP_L, r16 ; уставка LOW
000155 2e40 mov EEP_D_r, r16
000156 e001 ldi r16, EEP_SETTING_TEMP_L
000157 2e30 mov EEP_A_r, r16
000158 d02f rcall EEP_WR_BYTE
000159 e005 ldi r16, DEFAULT_SETTING_HYST
00015a 9300 006d sts SETTING_HYST, r16 ; гистерезис
00015c 2e40 mov EEP_D_r, r16
00015d e002 ldi r16, EEP_SETTING_HYST
00015e 2e30 mov EEP_A_r, r16
00015f d028 rcall EEP_WR_BYTE
000160 e001 ldi r16, DEFAULT_SETTING_MODE
000161 9300 006e sts SETTING_MODE, r16 ; режим
000163 2e40 mov EEP_D_r, r16
000164 e003 ldi r16, EEP_SETTING_MODE
000165 2e30 mov EEP_A_r, r16
000166 d021 rcall EEP_WR_BYTE
000167 e100 ldi r16, 0x10
000168 2e40 mov EEP_D_r, r16
000169 e004 ldi r16, EEP_FIRST_TIME_RUN
00016a 2e30 mov EEP_A_r, r16
00016b d01c rcall EEP_WR_BYTE
00016c 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: запись параметров из ОЗУ в EEPROM">
WRITE_PARAMS_TO_EEP:
00016d 930f push r16
00016e 9100 006b lds r16, SETTING_TEMP_H ; уставка HIGH
000170 2e40 mov EEP_D_r, r16
000171 e000 ldi r16, EEP_SETTING_TEMP_H
000172 2e30 mov EEP_A_r, r16
000173 d014 rcall EEP_WR_BYTE
000174 9100 006c lds r16, SETTING_TEMP_L ; уставка LOW
000176 2e40 mov EEP_D_r, r16
000177 e001 ldi r16, EEP_SETTING_TEMP_L
000178 2e30 mov EEP_A_r, r16
000179 d00e rcall EEP_WR_BYTE
00017a 9100 006d lds r16, SETTING_HYST ; гистерезис
00017c 2e40 mov EEP_D_r, r16
00017d e002 ldi r16, EEP_SETTING_HYST
00017e 2e30 mov EEP_A_r, r16
00017f d008 rcall EEP_WR_BYTE
000180 9100 006e lds r16, SETTING_MODE ; режим
000182 2e40 mov EEP_D_r, r16
000183 e003 ldi r16, EEP_SETTING_MODE
000184 2e30 mov EEP_A_r, r16
000185 d002 rcall EEP_WR_BYTE
000186 910f pop r16
000187 9508 ret//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограммы: запись и чтение байта из EEPROM">
EEP_WR_BYTE:
000188 94f8 cli
000189 930f push r16
_EEP_WR_BYTE_LP:
; ждем завершения предыдущей записи
00018a 99e1 sbic EECR, EEPE
00018b cffe rjmp _EEP_WR_BYTE_LP
; режим программирования - атомарный
00018c e000 ldi r16, (0<<EEPM1) | (0<<EEPM0)
00018d bb0c out EECR, r16
; выставляем адресс куда записывать
00018e ba3e out EEARL, EEP_A_r
; помещаем данные
00018f ba4d out EEDR, EEP_D_r
; запись
000190 9ae2 sbi EECR, EEMPE
000191 9ae1 sbi EECR, EEPE
000192 910f pop r16
000193 9478 sei
000194 9508 ret
EEP_RD_BYTE:
000195 94f8 cli
_EEP_RD_BYTE_LP:
; ждем завершения предыдущей записи
000196 99e1 sbic EECR, EEPE
000197 cffe rjmp _EEP_RD_BYTE_LP
; выставляем адресс откуда читать
000198 ba3e out EEARL, EEP_A_r
; читаем
000199 9ae0 sbi EECR, EERE
00019a b24d in EEP_D_r, EEDR
00019b 9478 sei
00019c 9508 ret//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: сравнение температуры с уставкой">
TEMP_COMPARSION:
00019d 930f push r16
00019e 931f push r17
00019f 932f push r18
0001a0 933f push r19
0001a1 934f push r20
0001a2 935f push r21
0001a3 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
0001a4 9100 0068 lds mc16uL, TEMP_L // r16
0001a6 9110 0069 lds mc16uH, TEMP_H // r17
0001a8 e02a ldi mp16uL, LOW(10)
0001a9 e030 ldi mp16uH, HIGH(10)
0001aa df5d rcall mpy16u
0001ab 2f02 mov temp_r_l, m16u0 ; L
0001ac 2f13 mov temp_r_h, m16u1 ; H
; добавляем дробную часть
0001ad 9120 006a lds r18, TEMP_F
0001af 2733 clr r19
0001b0 0f02 add temp_r_l, r18
0001b1 1f13 adc temp_r_h, r19
; определяем нижний и верхний пороги
0001b2 9140 006c lds r20, SETTING_TEMP_L
0001b4 9150 006b lds r21, SETTING_TEMP_H
0001b6 9160 006d lds r22, SETTING_HYST
0001b8 934f push r20
0001b9 935f push r21
0001ba 2777 clr r23
0001bb 1b46 sub r20, r22
0001bc 0b57 sbc r21, r23
0001bd 2eb4 mov min_r_trhd_l, r20
0001be 2ea5 mov min_r_trhd_h, r21
0001bf 915f pop r21
0001c0 914f pop r20
0001c1 2777 clr r23
0001c2 0f46 add r20, r22
0001c3 1f57 adc r21, r23
0001c4 2ed4 mov max_r_trhd_l, r20
0001c5 2ec5 mov max_r_trhd_h, r21
; определяем знак температуры
0001c6 f00e brts _NEGATE_TEMP
0001c7 c004 rjmp _COMPARE
_NEGATE_TEMP:
0001c8 9500 com temp_r_l
0001c9 9510 com temp_r_h
0001ca 5f0f subi temp_r_l, low(-1)
0001cb 4f1f sbci temp_r_h, high(-1)
_COMPARE:
; проверяем нижний порог
0001cc 16b0 cp min_r_trhd_l, temp_r_l
0001cd 06a1 cpc min_r_trhd_h, temp_r_h
0001ce f424 brge _MIN_THRESHOLD ; TEMP <= MIN
; проверяем верхний порог
0001cf 150d cp temp_r_l, max_r_trhd_l
0001d0 051c cpc temp_r_h, max_r_trhd_h
0001d1 f44c brge _MAX_THRESHOLD ; TEMP >= TOP
0001d2 c00f rjmp _COMPARSION_EXIT
_MIN_THRESHOLD:
; определяем режим работы
0001d3 9140 006e lds r20, SETTING_MODE
0001d5 2344 tst r20
0001d6 f411 brne PC+3
0001d7 9890 relay_off
0001d8 c001 rjmp PC+2
0001d9 9a90 relay_on
0001da c007 rjmp _COMPARSION_EXIT
_MAX_THRESHOLD:
0001db 9140 006e lds r20, SETTING_MODE
0001dd 2344 tst r20
0001de f411 brne PC+3
0001df 9a90 relay_on
0001e0 c001 rjmp PC+2
0001e1 9890 relay_off
_COMPARSION_EXIT:
0001e2 917f pop r23
0001e3 915f pop r21
0001e4 914f pop r20
0001e5 913f pop r19
0001e6 912f pop r18
0001e7 911f pop r17
0001e8 910f pop r16
0001e9 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: обновляем данные о температуре">
TEMP_UPD:
0001ea 931f push r17
0001eb d061 rcall TEMP_CONV
0001ec e152
0001ed e535
0001ee eb4d
0001ef d1fe DELAY24 751000
0001f0 d012 rcall TEMP_RD
; обновляем данные в ячейках
0001f1 9110 0068 lds r17, TEMP_L
0001f3 2f81 mov DISP_NUM_L, r17
0001f4 9110 0069 lds r17, TEMP_H
0001f6 2f91 mov DISP_NUM_H, r17
0001f7 911f pop r17
0001f8 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подрограмма: чтение кода семейства датчика">
RD_F_CODE:
0001f9 930f push r16
0001fa d149 rcall OW_PRESENCE
0001fb e303 ldi r16, DS18B20_CMD_READROM
0001fc 2e80 mov OW_CMD_r, r16
0001fd d15b rcall OW_SEND_BYTE
0001fe e6af ldi XL, LOW(DEVICE_FAMILY_CODE)
0001ff e0b0 ldi XH, HIGH(DEVICE_FAMILY_CODE)
000200 d177 rcall OW_RD_BYTE
000201 910f pop r16
000202 9508 ret//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: опрос температуры и чтение">
TEMP_RD:
000203 930f push r16
000204 931f push r17
000205 932f push r18
000206 933f push r19
000207 934f push r20
000208 d13b rcall OW_PRESENCE
000209 ff70 sbrs OWFR, OWPRF
00020a c03c rjmp _TEMP_RD_EXIT
00020b ec0c ldi r16, DS18B20_CMD_SKIPROM
00020c 2e80 mov OW_CMD_r, r16
00020d d14b rcall OW_SEND_BYTE
00020e eb0e ldi r16, DS18B20_CMD_RSCRATCHPAD
00020f 2e80 mov OW_CMD_r, r16
000210 d148 rcall OW_SEND_BYTE
000211 e6a8 ldi XL, LOW(TEMP_L)
000212 e0b0 ldi XH, HIGH(TEMP_L)
000213 d164 rcall OW_RD_BYTE
000214 e6a9 ldi XL, LOW(TEMP_H)
000215 e0b0 ldi XH, HIGH(TEMP_H)
000216 d161 rcall OW_RD_BYTE
000217 9110 0068 lds r17, TEMP_L
000219 9120 0069 lds r18, TEMP_H
00021b 932f push r18
00021c 7f28 cbr r18, (1<<0) | (1<<1) | (1<<2) ; убираем ненужные биты на время (интересуют последних битов в TEMP_H)
00021d 3f28 cpi r18, 0xf8 ; проверяется является ли число минусовой
00021e f011 breq _TEMP_RD_TO_UNSIGNED ; если да то конвертируем в беззнаковое число
00021f 94e8 clt
000220 c007 rjmp _TEMP_RD_CONTINUE ; если нет то преобразуем значение АЦП в температуру (делим на 16)
_TEMP_RD_TO_UNSIGNED:
000221 912f pop r18
000222 9468 set
000223 9510 com r17
000224 9520 com r18
000225 5f1f subi r17, low(-1)
000226 4f2f sbci r18, high(-1)
; ldi r19, 1
; add r17, r19
; ldi r19, 0
; adc r18, r19
000227 c001 rjmp PC+2
_TEMP_RD_CONTINUE: ; Температура = Число с АЦП / 16 (сдвиг вправо 4)
000228 912f pop r18
000229 9526 lsr r18
00022a 9517 ror r17
00022b 9526 lsr r18
00022c 9517 ror r17
00022d 9526 lsr r18
00022e 9517 ror r17
00022f 9526 lsr r18
000230 9517 ror r17
_TEMP_RD_END:
000231 9130 0068 lds r19, TEMP_L
000233 f40e brtc PC+2
000234 9531 neg r19 ; переводим в беззнаковое число если минус
; далее происходит такое для получения дробной части:
; ((n<<3) + (n<<1))>>4 или (n*10)/16
000235 2f43 mov r20, r19
000236 703f andi r19, 0x0f
000237 2f43 mov r20, r19
000238 0f33 lsl r19
000239 0f33 lsl r19
00023a 0f33 lsl r19
00023b 0f44 lsl r20
00023c 0f34 add r19, r20
00023d 9536 lsr r19
00023e 9536 lsr r19
00023f 9536 lsr r19
000240 9536 lsr r19
; записываем данные
000241 9310 0068 sts TEMP_L, r17
000243 9320 0069 sts TEMP_H, r18
000245 9330 006a sts TEMP_F, r19
_TEMP_RD_EXIT:
000247 914f pop r20
000248 913f pop r19
000249 912f pop r18
00024a 911f pop r17
00024b 910f pop r16
00024c 9508 ret
;
TEMP_CONV:
00024d 930f push r16
00024e d0f5 rcall OW_PRESENCE
00024f ff70 sbrs OWFR, OWPRF
000250 c006 rjmp _TEMP_CONV_EXIT
000251 ec0c ldi r16, DS18B20_CMD_SKIPROM
000252 2e80 mov OW_CMD_r, r16
000253 d105 rcall OW_SEND_BYTE
000254 e404 ldi r16, DS18B20_CMD_CONVERTTEMP
000255 2e80 mov OW_CMD_r, r16
000256 d102 rcall OW_SEND_BYTE
_TEMP_CONV_EXIT:
000257 910f pop r16
000258 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: отправка байта в сдвиговый регистр">
; **** ОТПРАВКА БАЙТА В СДВИГОВЫЙ РЕГИСТР *************************
USI_TRANSMIT:
000259 930f push r16
00025a 920f push r0
00025b b80f out USIDR, r0 ; Байт для отправки всегда находится в регистре r0. Помещаем данные в регистр USIDR.
; Enable USI Overflow Interrupt Flag (will be 0 if transfer is not compeleted)
00025c e400 ldi TEMP_REG_A, (1<<USIOIF)
00025d b90e 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)
00025e e10b ldi TEMP_REG_A, (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC)
_USI_TRANSMIT_LOOP: ; Execute loop when USIOIF is 0
00025f b90d out USICR, TEMP_REG_A ; Load settings from temp register into USI Control Register
000260 9b76 sbis USISR, USIOIF ; If transfer is comleted then move out of loop
000261 cffd rjmp _USI_TRANSMIT_LOOP
; Send pulse into LATCH pin.
; This will copy byte from 74hc595 shift register into 74hc595 storage register
000262 9ac0 sbi PORTB, USI_LATCH_PIN
000263 98c0 cbi PORTB, USI_LATCH_PIN
000264 900f pop r0
000265 910f pop r16
000266 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: обработка нажатия кнопки SET">
BUTTON_PROCESS:
000267 930f push r16
_SW_CHECK_ON_0:
000268 9bb4 sbis SW_PIN, SW_SET_PIN
000269 c001 rjmp _SW_SET_0
00026a c01c rjmp _SW_CHECK_ON_1
_SW_SET_0:
00026b 9100 0071 lds r16, SW_DATA
00026d 2300 tst r16
00026e f409 brne _SW_SET_FROM_0_TO_1
00026f c017 rjmp _SW_CHECK_ON_1
_SW_SET_FROM_0_TO_1:
000270 2700 clr r16
000271 9300 0071 sts SW_DATA, r16
000273 d166 rcall DEBOUNCE_SW
000274 9463 inc REPROGRAM_STEP_r
000275 2d16 mov r17, REPROGRAM_STEP_r
000276 3014 cpi r17, 4
000277 f414 brge _SAVE_SETTINGS
000278 d153 rcall BEEP_SHORT
000279 c00d rjmp _SW_CHECK_ON_1
_SAVE_SETTINGS:
00027a e010
00027b bf19 outi r17, TIMSK, (0<<OCIE0A)
00027c 9892 cbi PORTD, DIGIT_1_PIN
00027d 9893 cbi PORTD, DIGIT_2_PIN
00027e 9894 cbi PORTD, DIGIT_3_PIN
00027f 9895 cbi PORTD, DIGIT_4_PIN
000280 2466 clr REPROGRAM_STEP_r
000281 deeb rcall WRITE_PARAMS_TO_EEP
000282 d150 rcall BEEP_LONG
000283 9896 cbi PORTD, LED_PGM_PIN
000284 e010 ldi r17, MCU_STATE_DEFAULT
000285 9310 0060 sts MCU_STATE, r17
_SW_CHECK_ON_1:
000287 99b4 sbic SW_PIN, SW_SET_PIN
000288 c001 rjmp _SW_SET_1
000289 c009 rjmp _BUTTON_PROCESS_END
_SW_SET_1:
00028a 9100 0071 lds r16, SW_DATA
00028c 2300 tst r16
00028d f009 breq _SW_SET_FROM_1_TO_0
00028e c004 rjmp _BUTTON_PROCESS_END
_SW_SET_FROM_1_TO_0:
00028f ef0f ser r16
000290 9300 0071 sts SW_DATA, r16
000292 d147 rcall DEBOUNCE_SW
_BUTTON_PROCESS_END:
000293 910f pop r16
000294 9508 ret//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: перепрограммирование параметров">
REPROGRAM_SETTINGS:
000295 930f push r16
000296 931f push r17
000297 932f push r18
000298 933f push r19
000299 934f push r20
00029a 2d06 mov r16, REPROGRAM_STEP_r
00029b 2300 tst r16
00029c f009 breq _INTO
00029d c004 rjmp _REPROGRAM_SETTINGS_LOOP
_INTO:
00029e 9890 relay_off
00029f 9a96 sbi PORTD, LED_PGM_PIN
0002a0 d12b rcall BEEP_SHORT
0002a1 9463 inc REPROGRAM_STEP_r
_REPROGRAM_SETTINGS_LOOP:
0002a2 dfc4 rcall BUTTON_PROCESS
_CHECK_STEP:
0002a3 3001 cpi r16, 1
0002a4 f029 breq _STEP_1
0002a5 3002 cpi r16, 2
0002a6 f151 breq _STEP_2
0002a7 3003 cpi r16, 3
0002a8 f139 breq _S3_JMP
0002a9 c094 rjmp _REPROGRAM_SETTINGS_END
//<editor-fold defaultstate="collapsed" desc="Настройка: шаг 1">
_STEP_1: ; установка и отображение гистерезиса
0002aa d0e7 rcall DISPLAY_UPD_DIGITS
_S1_CHECK_PLUS:
0002ab 9bb2 sbis SW_PIN, SW_PLUS_PIN
0002ac c004 rjmp _INCREASE_HYST
0002ad c000 rjmp _S1_CHECK_MINUS
_S1_CHECK_MINUS:
0002ae 9bb3 sbis SW_PIN, SW_MINUS_PIN
0002af c00a rjmp _DECREASE_HYST
0002b0 c011 rjmp _SHOW_HYST
_INCREASE_HYST:
0002b1 d128 rcall DEBOUNCE_SW
0002b2 9110 006d lds r17, SETTING_HYST
0002b4 3c18 cpi r17, MAX_HYST
0002b5 f009 breq PC+2
0002b6 9513 inc r17
0002b7 9310 006d sts SETTING_HYST, r17
0002b9 c008 rjmp _SHOW_HYST
_DECREASE_HYST:
0002ba d11f rcall DEBOUNCE_SW
0002bb 9110 006d lds r17, SETTING_HYST
0002bd 3011 cpi r17, MIN_HYST
0002be f009 breq PC+2
0002bf 951a dec r17
0002c0 9310 006d sts SETTING_HYST, r17
_SHOW_HYST:
0002c2 94e8 clt
0002c3 930f push dd8u
0002c4 931f push dv8u
0002c5 9100 006d lds dd8u, SETTING_HYST
0002c7 e01a ldi dv8u, 10
0002c8 de31 rcall div8u
0002c9 2f80 mov DISP_NUM_L, dres8u
0002ca 2799 clr DISP_NUM_H ; гистерезис 8 битный так что ноль пишем в старший байт
0002cb 92f0 0066 sts DIGITS+3, drem8u
0002cd 911f pop dv8u
0002ce 910f pop dd8u
0002cf c06e rjmp _REPROGRAM_SETTINGS_END
//</editor-fold>
_S3_JMP: ; просто прыжок на _STEP_3
0002d0 c047 rjmp _STEP_3
//<editor-fold defaultstate="collapsed" desc="Настройка: шаг 2">
_STEP_2:
0002d1 d0c0 rcall DISPLAY_UPD_DIGITS
_S2_CHECK_PLUS:
0002d2 9bb2 sbis SW_PIN, SW_PLUS_PIN
0002d3 c004 rjmp _INCREASE_TEMP
0002d4 c000 rjmp _S2_CHECK_MINUS
_S2_CHECK_MINUS:
0002d5 9bb3 sbis SW_PIN, SW_MINUS_PIN
0002d6 c013 rjmp _DECREASE_TEMP
0002d7 c021 rjmp _SHOW_TEMP
_INCREASE_TEMP:
0002d8 d101 rcall DEBOUNCE_SW
0002d9 9110 006c lds r17, SETTING_TEMP_L
0002db 9120 006b lds r18, SETTING_TEMP_H
0002dd 3b10 cpi r17, MAX_TEMP_L
0002de e034 ldi r19, MAX_TEMP_H
0002df 0723 cpc r18, r19
0002e0 f031 breq PC+7
0002e1 e03a ldi r19, 10
0002e2 0f13 add r17, r19
0002e3 2733 clr r19
0002e4 1f23 adc r18, r19
0002e5 9310 006c sts SETTING_TEMP_L, r17
0002e7 9320 006b sts SETTING_TEMP_H, r18
0002e9 c00f rjmp _SHOW_TEMP
_DECREASE_TEMP:
0002ea d0ef rcall DEBOUNCE_SW
0002eb 9110 006c lds r17, SETTING_TEMP_L
0002ed 9120 006b lds r18, SETTING_TEMP_H
0002ef 301c cpi r17, MIN_TEMP_L
0002f0 ef3e ldi r19, MIN_TEMP_H
0002f1 0723 cpc r18, r19
0002f2 f011 breq PC+3
__DECREASE:
0002f3 501a subi r17, 10
0002f4 4020 sbci r18, 0
0002f5 9310 006c sts SETTING_TEMP_L, r17
0002f7 9320 006b sts SETTING_TEMP_H, r18
_SHOW_TEMP:
0002f9 930f push dd16uL
0002fa 931f push dd16uH
0002fb 932f push dv16uL
0002fc 933f push dv16uH
0002fd 9100 006c lds dd16uL, SETTING_TEMP_L
0002ff 9110 006b lds dd16uH, SETTING_TEMP_H
000301 2f21 mov r18, dd16uH
000302 7820 andi r18, (1<<7)
000303 f411 brne _NEGATE_SET_TEMP
000304 94e8 clt
000305 c005 rjmp _DIVIDE_SET_TEMP
_NEGATE_SET_TEMP:
000306 9468 set
000307 9500
000308 9510
000309 5f0f
00030a 4f1f com16 dd16uL, dd16uH
_DIVIDE_SET_TEMP:
00030b e02a ldi dv16uL, LOW(10)
00030c e030 ldi dv16uH, HIGH(10)
00030d ddd9 rcall div16u
00030e 2f80 mov DISP_NUM_L, dres16uL
00030f 2f91 mov DISP_NUM_H, dres16uH
000310 e00a ldi r16, 10
000311 9300 0066 sts DIGITS+3, r16 ; значок градуса
000313 913f pop dv16uH
000314 912f pop dv16uL
000315 911f pop dd16uH
000316 910f pop dd16uL
000317 c026 rjmp _REPROGRAM_SETTINGS_END
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Настройка: шаг 3">
_STEP_3:
000318 94e8 clt
_S3_CHECK_PLUS:
000319 9bb2 sbis SW_PIN, SW_PLUS_PIN
00031a c004 rjmp _SET_HEAT_MODE
00031b c000 rjmp _S3_CHECK_MINUS
_S3_CHECK_MINUS:
00031c 9bb3 sbis SW_PIN, SW_MINUS_PIN
00031d c006 rjmp _SET_COOLING_MODE
00031e c009 rjmp _SHOW_MODE
_SET_HEAT_MODE:
00031f d0ba rcall DEBOUNCE_SW
000320 e011 ldi r17, HEAT_MODE
000321 9310 006e sts SETTING_MODE, r17
000323 c004 rjmp _SHOW_MODE
_SET_COOLING_MODE:
000324 d0b5 rcall DEBOUNCE_SW
000325 e010 ldi r17, COOLING_MODE
000326 9310 006e sts SETTING_MODE, r17
_SHOW_MODE:
000328 2711 clr r17
000329 2f81 mov DISP_NUM_L, r17
00032a 2f91 mov DISP_NUM_H, r17
00032b e01e ldi r17, 14
00032c 9310 0063 sts DIGITS, r17
00032e 9310 0064 sts DIGITS+1, r17
000330 9310 0065 sts DIGITS+2, r17
000332 9120 006e lds r18, SETTING_MODE
000334 2322 tst r18
000335 f009 breq _SHOW_COOLING
000336 c004 rjmp _SHOW_HEATING
_SHOW_COOLING:
000337 e01c ldi r17, 12
000338 9310 0066 sts DIGITS+3, r17
00033a c003 rjmp _REPROGRAM_SETTINGS_END
_SHOW_HEATING:
00033b e01d ldi r17, 13
00033c 9310 0066 sts DIGITS+3, r17
//</editor-fold>
_REPROGRAM_SETTINGS_END:
00033e 914f pop r20
00033f 913f pop r19
000340 912f pop r18
000341 911f pop r17
000342 910f pop r16
000343 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Реализация интерфеса 1-Wire">
//<editor-fold defaultstate="collapsed" desc="1-Wire: опрос присутствия">
; **** ОПРОС ПРИСУТСТВИЯ УСТРОЙСТВА ******************************
OW_PRESENCE:
000344 94f8 cli
000345 9ab9 ow_pull
000346 e033
000347 eb4e
000348 d0a1 DELAY16 480
000349 98b9 ow_release
00034a e030
00034b e84a
00034c d09d DELAY16 70
00034d d005 rcall OW_CHECK_PRESENCE
00034e e033
00034f e342
000350 d099 DELAY16 410
000351 9478 sei
000352 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="1-Wire: проверка наличия устройства">
; **** ПРОВЕРКА НАЛИЧИЯ УСТРОЙСТВА *******************************
; Если подчиненное устройство притянет шину, то устанавливаем флаг OWPRF в единицу в регистре флагов
;
OW_CHECK_PRESENCE:
000353 9bb1 sbis OW_PIN, OW_LINE
000354 6071 sbr OWFR, (1<<OWPRF)
000355 c002 rjmp _EXIT
000356 99b1 sbic OW_PIN, OW_LINE
000357 7f7e cbr OWFR, (1<<OWPRF)
_EXIT:
000358 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="1-Wire: отправка байта">
OW_SEND_BYTE:
000359 94f8 cli
00035a 930f push r16
00035b 931f push r17
00035c 2d08 mov r16, OW_CMD_r
00035d e018 ldi r17, 8
_OW_SEND_BYTE_LOOP:
00035e 9506 lsr r16
00035f f408 brcc _OW_SEND_0
000360 f048 brcs _OW_SEND_1
_OW_SEND_0:
000361 9ab9 ow_pull
000362 e030
000363 e746
000364 d085 DELAY16 60
000365 98b9 ow_release
000366 e030
000367 e142
000368 d081 DELAY16 10
000369 c008 rjmp _OW_SEND_BYTE_END
_OW_SEND_1:
00036a 9ab9 ow_pull
00036b e030
00036c e04a
00036d d07c DELAY16 6
00036e 98b9 ow_release
00036f e030
000370 e74e
000371 d078 DELAY16 64
_OW_SEND_BYTE_END:
000372 951a dec r17
000373 f751 brne _OW_SEND_BYTE_LOOP
000374 911f pop r17
000375 910f pop r16
000376 9478 sei
000377 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="1-Wire: чтение байта">
OW_RD_BYTE:
000378 94f8 cli
000379 930f push r16
00037a 931f push r17
00037b 2700 clr r16
00037c e018 ldi r17, 8
_OW_RD_BYTE_LP:
00037d 9506 lsr r16
00037e 9ab9 ow_pull
00037f e030
000380 e04a
000381 d068 DELAY16 6
000382 98b9 ow_release
000383 e030
000384 e140
000385 d064 DELAY16 9
000386 99b1 sbic OW_PIN, OW_LINE
000387 6800 sbr r16, (1<<7)
000388 e030
000389 e64c
00038a d05f DELAY16 55
00038b 951a dec r17
00038c f781 brne _OW_RD_BYTE_LP
00038d 930c st X, r16
00038e 911f pop r17
00038f 910f pop r16
000390 9478 sei
000391 9508 ret
//</editor-fold>
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: обновление ячеек в SRAM для индикатора">
; **** ПОЛУЧЕНИЕ ЦИФР ИЗ 16-ТИ БИТНОГО ЧИСЛА *********************
; Описание: Перемещает цифры числа в соответствующие ячейки памяти в SRAM
; путем деления этого числа несколько раз
DISPLAY_UPD_DIGITS:
000392 930f push r16
000393 935f push r21
000394 e053 ldi r21, 3
; инициализация указателя (за каждый проход цикла будет инкрементироваться)
000395 e6a3 ldi XL, LOW(DIGITS)
000396 e0b0 ldi XH, HIGH(DIGITS)
.equ dividend = SRAM_TEMP_1 ; число которе будем делить
.equ divisor = 10 ; на что делим
; загружаем число которое хотим поделить в адрес SRAM делимого
000397 9380 0061 sts dividend, DISP_NUM_L
000399 9390 0062 sts dividend+1, DISP_NUM_H
; четыре раза производим деление для получения остатков
DIV_LOOP:
; заполняем нужные регистры
00039b 9100 0061 lds dd16uL, dividend
00039d 9110 0062 lds dd16uH, dividend+1
00039f e02a ldi dv16uL, LOW(divisor)
0003a0 e030 ldi dv16uH, HIGH(divisor)
0003a1 dd45 rcall div16u ; делим
0003a2 92ed st X+, drem16uL ; сохраняем остаток в ячейку по указателю и увеличиваем его
; обновляем делимое
0003a3 9300 0061 sts dividend, dres16uL
0003a5 9310 0062 sts dividend+1, dres16uH
0003a7 955a dec r21 ; декрементируем счетчик цикла
0003a8 f791 brne DIV_LOOP ; делим еще раз если не 0
0003a9 915f pop r21
0003aa 910f pop r16
0003ab 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: получение символа для индикатора">
; **** ЗАГРУЖАЕТ НУЖНЫЙ АДРЕС СИМВОЛА В R0 ***********************
DISPLAY_DECODER:
0003ac 930f push r16
0003ad 931f push r17
0003ae eee6 ldi ZL, LOW(2*DISPLAY_SYMBOLS)
0003af e0f7 ldi ZH, HIGH(2*DISPLAY_SYMBOLS)
0003b0 2711 clr TEMP_REG_B
0003b1 0fe0 add ZL, TEMP_REG_A
0003b2 1ff1 adc ZH, TEMP_REG_B
0003b3 9004 lpm r0, Z
0003b4 9100 0067 lds r16, CURRENT_DIGIT
0003b6 3002 cpi r16, 2
0003b7 f009 breq _DOT_ON
0003b8 c010 rjmp _DISPLAY_DECODER_EXIT
_DOT_ON:
0003b9 2d00 mov r16, r0
0003ba 770f cbr r16, (1<<7)
0003bb 2e00 mov r0, r16
0003bc 2d06 mov r16, REPROGRAM_STEP_r
0003bd 3002 cpi r16, 2
0003be f42c brge _DOT_OFF
0003bf 9100 0060 lds r16, MCU_STATE
0003c1 3002 cpi r16, MCU_STATE_ERROR
0003c2 f029 breq _ERR_DOT_OFF
0003c3 c005 rjmp _DISPLAY_DECODER_EXIT
_DOT_OFF:
0003c4 2d00 mov r16, r0
0003c5 6800 sbr r16, (1<<7)
0003c6 2e00 mov r0, r16
0003c7 c001 rjmp _DISPLAY_DECODER_EXIT
_ERR_DOT_OFF:
0003c8 cffb rjmp _DOT_OFF
_DISPLAY_DECODER_EXIT:
0003c9 911f pop r17
0003ca 910f pop r16
0003cb 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: короткий писк">
BEEP_SHORT:
0003cc 9ac5 sbi BUZZER_PORT, BUZZER_PIN
0003cd e053
0003ce ea39
0003cf e74d
0003d0 d01d DELAY24 150000
0003d1 98c5 cbi BUZZER_PORT, BUZZER_PIN
0003d2 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: длинный писк">
BEEP_LONG:
0003d3 9ac5 sbi BUZZER_PORT, BUZZER_PIN
0003d4 e05c
0003d5 e334
0003d6 ef4d
0003d7 d016 DELAY24 500000
0003d8 98c5 cbi BUZZER_PORT, BUZZER_PIN
0003d9 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: устранение дребезга кнопки">
DEBOUNCE_SW:
0003da 930f push r16
0003db 931f push r17
0003dc 932f push r18
0003dd e02a ldi r18, 10
_loop_2:
0003de ef1f ldi r17, 255
_loop_0:
0003df ef0f ldi r16, 255
_dec_0:
0003e0 950a dec r16
0003e1 f7f1 brne _dec_0
_loop_1:
0003e2 951a dec r17
0003e3 f7d9 brne _loop_0
_loop_3:
0003e4 952a dec r18
0003e5 f7c1 brne _loop_2
0003e6 912f pop r18
0003e7 911f pop r17
0003e8 910f pop r16
0003e9 9508 ret//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: задержка (16бит макс число)">
DELAY_LOOP_16:
0003ea 5041 subi DELAY_8_r, 1
0003eb 4030 sbci DELAY_16_r, 0
0003ec f7e8 brcc DELAY_LOOP_16
0003ed 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Подпрограмма: задержка (24бит макс число)">
DELAY_LOOP_24:
0003ee 5041 subi DELAY_8_r, 1
0003ef 4030 sbci DELAY_16_r, 0
0003f0 4050 sbci DELAY_24_r, 0
0003f1 f7e0 brcc DELAY_LOOP_24
0003f2 9508 ret
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Символы для индикатора">
DISPLAY_SYMBOLS:
; HGFEDCBA HGFEDCBA
0003f3 f9c0 .DB 0b11000000, 0b11111001 ; 0, 1
0003f4 b0a4 .DB 0b10100100, 0b10110000 ; 2, 3
0003f5 9299 .DB 0b10011001, 0b10010010 ; 4, 5
0003f6 f882 .DB 0b10000010, 0b11111000 ; 6, 7
0003f7 9080 .DB 0b10000000, 0b10010000 ; 8, 9
0003f8 bf9c .DB 0b10011100, 0b10111111 ; °, -
0003f9 89c6 .DB 0b11000110, 0b10001001 ; C, H
//</editor-fold>
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Сегмент EEPROM">
; **** СЕГМЕНТ EEPROM ********************************************
.ESEG
.ORG 0x30
000030 41
000031 56
000032 52
000033 20
000034 54
000035 68
000036 65
000037 72
000038 6d
000039 6f
00003a 73
00003b 74
00003c 61
00003d 74
00003e 2e
00003f 20
000040 57
000041 72
000042 69
000043 74
000044 74
000045 65
000046 6e
000047 20
000048 62
000049 79
00004a 20
00004b 53
00004c 65
00004d 72
00004e 67
00004f 65
000050 79
000051 20
000052 59
000053 61
000054 72
000055 6b
000056 6f
000057 76 INFO: .DB "AVR Thermostat. Written by Sergey Yarkov"
;</editor-fold>
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 : 8 r1 : 2 r2 : 0 r3 : 16 r4 : 16
r5 : 12 r6 : 7 r7 : 0 r8 : 6 r9 : 0 r10: 2 r11: 2 r12: 2
r13: 2 r14: 5 r15: 11 r16: 232 r17: 121 r18: 53 r19: 59 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: 29 out of 35 (82.9%)
"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 : 17 brge : 5 brhc : 0
brhs : 0 brid : 0 brie : 0 brlo : 0 brlt : 0 brmi : 0
brne : 23 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 : 5 cln : 0 clr : 18 cls : 0 clt : 4
clv : 0 clz : 0 com : 6 cp : 2 cpc : 4 cpi : 23
cpse : 0 dec : 11 eor : 0 icall : 0 ijmp : 0 in : 6
inc : 4 ld : 0 ldd : 0 ldi : 118 lds : 51 lpm : 2
lsl : 4 lsr : 11 mov : 63 movw : 0 neg : 1 nop : 0
or : 1 ori : 0 out : 26 pop : 56 push : 55 rcall : 88
ret : 28 reti : 3 rjmp : 66 rol : 6 ror : 9 sbc : 2
sbci : 7 sbi : 17 sbic : 5 sbis : 10 sbiw : 0 sbr : 3
sbrc : 0 sbrs : 2 sec : 2 seh : 0 sei : 5 sen : 0
ser : 2 ses : 0 set : 2 sev : 0 sez : 0 sleep : 0
spm : 0 st : 2 std : 0 sts : 48 sub : 5 subi : 6
swap : 0 tst : 7 wdr : 0
Instructions used: 56 out of 105 (53.3%)
"ATtiny2313A" memory use summary [bytes]:
Segment Begin End Code Data Used Size Use%
---------------------------------------------------------------
[.cseg] 0x000000 0x0007f4 2002 14 2016 2048 98.4%
[.dseg] 0x000060 0x000072 0 18 18 128 14.1%
[.eseg] 0x000030 0x000058 0 40 40 128 31.3%
Assembly complete, 0 errors, 21 warnings