2023-06-15 23:41:16 +03:00

1386 lines
88 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 firmware.asm Thu Jun 15 23:21:29 2023
firmware.asm(14): Including file 'tn2313Adef.inc'
firmware.asm(302): Including file 'div16u.asm'
div16u.asm(22): warning: Register r16 already defined by the .DEF directive
firmware.asm(302): 'div16u.asm' included form here
div16u.asm(23): warning: Register r17 already defined by the .DEF directive
firmware.asm(302): 'div16u.asm' included form here
div16u.asm(24): warning: Register r16 already defined by the .DEF directive
firmware.asm(302): 'div16u.asm' included form here
div16u.asm(25): warning: Register r17 already defined by the .DEF directive
firmware.asm(302): 'div16u.asm' included form here
firmware.asm(303): Including file 'usi.asm'
firmware.asm(14): Including file 'tn2313Adef.inc'
firmware.asm(302): Including file 'div16u.asm'
firmware.asm(303): Including file 'usi.asm'
; 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
; Package: SOIC-20W_7.5x12.8mm_P1.27mm
; Assembler: AVR macro assembler 2.2.7
; Clock frequency: 8 MHz External Crystal Oscillator
; Fuses: lfuse: 0xCF, hfuse: 0x9F, efuse: 0xFF, lock: 0xFF
;
; Written by Sergey Yarkov 22.01.2023
.INCLUDE "tn2313Adef.inc"
;***** 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 ******************************************************
.LIST
.DEF TEMP_REG_A = r16
.DEF TEMP_REG_B = r17
.DEF DISP_NUM_L = r24 ; LSB числа которое сейчас на индикаторе
.DEF DISP_NUM_H = r25 ; MSB числа которое сейчас на индикаторе
.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_POWER_PIN = PD6 ; Светодиод, который говорит о том что питание подано
.EQU ONE_WIRE_LINE = PB1 ; Пин шины 1-Wire
.EQU ONE_WIRE_DDR = DDRB
.EQU ONE_WIRE_PIN = PINB
.DEF ONE_WIRE_FLAGS = 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 MCU_STATE_DEFAULT = 0x01 ; Режим измерения температуры и сравнения с заданными параметрами
.EQU MCU_STATE_PROGRAM = 0x02 ; Режим настройки параметров в EEPROM
.EQU MCU_STATE_ERROR = 0x03 ; Режим ошибки, например когда не подключен датчик
; **** МАКРОСЫ **************************************************
.MACRO outi
ldi @0, @2
out @1, @0
.ENDMACRO
.MACRO display_load
ldi DISP_NUM_L, LOW(@0)
ldi DISP_NUM_H, HIGH(@0)
.ENDMACRO
.MACRO _1_wire_pull
sbi ONE_WIRE_DDR, ONE_WIRE_LINE
.ENDMACRO
.MACRO _1_wire_release
cbi ONE_WIRE_DDR, ONE_WIRE_LINE
.ENDMACRO
; **** СЕГМЕНТ ДАННЫХ ********************************************
.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 PC_HISTORY: .BYTE 1 ; История изменений состояния кнопок (необходимо для прерываня по изменению состояния пина)
; **** СЕГМЕНТ КОДА **********************************************
.CSEG
.ORG 0x00
000000 c060 rjmp RESET_vect
.ORG 0x000B
00000b c03e rjmp PCINT0_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 reset_digit_idx
000016 c003 rjmp _indicate_1
reset_digit_idx:
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 d0d6 rcall DISPLAY_DECODER
000023 d070 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 d0cc rcall DISPLAY_DECODER
00002d d066 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 d0c2 rcall DISPLAY_DECODER
000037 d05c 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 d0b8 rcall DISPLAY_DECODER
000041 d052 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
; **** ОБРАБОТКА КНОПОК ******************************************
PCINT0_vect:
00004a 930f push r16
00004b 931f push r17
00004c 932f push r18
00004d 933f push r19
00004e b70f in r16, SREG
00004f b316 in r17, SW_PIN
000050 9120 0068 lds r18, PC_HISTORY
000052 2712 eor r17, r18
000053 b336 in r19, SW_PIN
000054 9330 0068 sts PC_HISTORY, r19
_SW_PLUS_CHECK:
000056 ff12 sbrs r17, SW_PLUS_PIN
000057 c003 rjmp _SW_EXIT
000058 c000 rjmp _SW_PLUS_HANDLER
_SW_PLUS_HANDLER:
; rcall DEBOUNCE_SW
000059 9bb2 sbis SW_PIN, SW_PLUS_PIN
00005a 9601 adiw DISP_NUM_L, 1
;exit
; sbis PINB, SW_PLUS_PIN
; rjmp _sw_plus
; sbis PINB, SW_MINUS_PIN
; rjmp _sw_minus
; sbis PINB, SW_SET_PIN
; rjmp _sw_set
; rjmp _sw_exit
; _sw_plus:
; adiw DISP_NUM_L, 1
; rjmp _sw_exit
; _sw_minus:
; adiw DISP_NUM_L, 10
; rjmp _sw_exit
; _sw_set:
; adiw DISP_NUM_L, 63
; _sw_exit:
_SW_EXIT:
00005b bf0f out SREG, r16
00005c 913f pop r19
00005d 912f pop r18
00005e 911f pop r17
00005f 910f pop r16
000060 9518 reti
; **** СТАРТ ПРОГРАММЫ *******************************************
RESET_vect:
000061 ed0f ldi TEMP_REG_A, LOW(RAMEND)
000062 bf0d out SPL, TEMP_REG_A
; **** ПРОЦЕСС ИНИЦИАЛИЗАЦИИ МК **********************************
MCU_INIT:
; **** ИНИЦИАЛИЗАЦИЯ ПИНОВ *************************************
000063 e70e
000064 bb01 outi r16, DDRD, (1<<LED_POWER_PIN) | (1<<DIGIT_1_PIN) | (1<<DIGIT_2_PIN) | (1<<DIGIT_3_PIN) | (1<<DIGIT_4_PIN) | (0<<PD0) | (1<<PD1)
000065 ec01
000066 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)
000067 e10c
000068 bb08 outi r16, PORTB, (1<<SW_PLUS_PIN) | (1<<SW_MINUS_PIN) | (1<<SW_SET_PIN)
; **** ИНИЦИАЛИЗАЦИЯ ПРЕРЫВАНИЙ ********************************
000069 e200
00006a bf0b outi r16, GIMSK, (1<<PCIE0)
00006b e10c
00006c bd00 outi r16, PCMSK0, (1<<PCINT2) | (1<<PCINT3) | (1<<PCINT4) ; прерывание для кнопок на нажатие
; **** ИНИЦИАЛИЗАЦИЯ ТАЙМЕРА 0 **********************************
00006d e002
00006e bf00 outi r16, TCCR0A, (1<<WGM01) ; режим CTC Compare A
00006f e005
000070 bf03 outi r16, TCCR0B, (1<<CS02) | (1<<CS00) ; 1024 делитель
000071 e109
000072 bf06 outi r16, OCR0A, 25 ; число для сравнения. (60Hz)
000073 e001
000074 bf09 outi r16, TIMSK, (1<<OCIE0A) ; включение прерывания по совпадению
; **** ИНИЦИАЛИЗАЦИЯ USART *************************************
; outi r16, UBRRL, LOW(3) ; 9600 БОД
; outi r16, UBRRH, HIGH(3) ; 9600 БОД
; outi r16, UCSRB, (1<<RXEN) | (1<<TXEN) ; Включение приема и передачии
; outi r16, UCSRC, (1<<UCSZ1) | (1<<UCSZ0) ; Асинхронный режим, 8 бит фрейм, 1 стоповый бит
000075 2411 clr r1
000076 9210 0067 sts CURRENT_DIGIT, r1
000078 e080
000079 e090 display_load 0 ; загружаем число, которое нужно показать на индикатор
; rcall _1_WIRE_DETECT_PRESENCE ; проверяем наличие датчика на шине путем выполнения процедуры сброса
00007a 9478 sei
; **** ГЛАВНЫЙ ЦИКЛ **********************************************
LOOP:
00007b d063 rcall DISPLAY_UPD_DIGITS ; получаем из этого числа цифры путем деления и распределяем их по ячейкам в SRAM
; usart_t:
; sbis UCSRA, UDRE
; rjmp usart_t
; ldi r16, 'B'
; out UDR, r16
; usart_r:
; sbis UCSRA, RXC
; rjmp usart_r
; in DISP_NUM_L, UDR
; sbrc ONE_WIRE_FLAGS, OWPRF
; sbi PORTD, PD6
; sbrs ONE_WIRE_FLAGS, OWPRF
; cbi PORTD, PD6
00007c 9a96 sbi PORTD, PD6
00007d d08a rcall DEBOUNCE_SW
00007e 9896 cbi PORTD, PD6
00007f d088 rcall DEBOUNCE_SW
000080 cffa 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:
000081 24ee clr drem16uL ; clear remainder Low byte
000082 18ff sub drem16uH,drem16uH ; clear remainder High byte and carry
000083 e141 ldi dcnt16u,17 ; init loop counter
d16u_1:
000084 1f00 rol dd16uL ; shift left dividend
000085 1f11 rol dd16uH
000086 954a dec dcnt16u ; decrement counter
000087 f409 brne d16u_2 ; if done
000088 9508 ret ; return
d16u_2:
000089 1cee rol drem16uL ; shift dividend into remainder
00008a 1cff rol drem16uH
00008b 1ae2 sub drem16uL,dv16uL ; remainder = remainder - divisor
00008c 0af3 sbc drem16uH,dv16uH
00008d f420 brcc d16u_3 ; if result negative
00008e 0ee2 add drem16uL,dv16uL ; restore remainder
00008f 1ef3 adc drem16uH,dv16uH
000090 9488 clc ; clear carry to be shifted into result
000091 cff2 rjmp d16u_1 ; else
d16u_3:
000092 9408 sec ; set carry to be shifted into result
.INCLUDE "usi.asm"
000093 cff0
USI_TRANSMIT:
000094 930f push r16
000095 b80f out USIDR, r0 ; Байт для отправки всегда находится в регистре r0. Помещаем данные в регистр USIDR.
; Enable USI Overflow Interrupt Flag (will be 0 if transfer is not compeleted)
000096 e400 ldi TEMP_REG_A, (1<<USIOIF)
000097 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)
000098 e10b ldi TEMP_REG_A, (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC)
_USI_TRANSMIT_LOOP: ; Execute loop when USIOIF is 0
000099 b90d out USICR, TEMP_REG_A ; Load settings from temp register into USI Control Register
00009a 9b76 sbis USISR, USIOIF ; If transfer is comleted then move out of loop
00009b cffd rjmp _USI_TRANSMIT_LOOP
; Send pulse into LATCH pin.
; This will copy byte from 74hc595 shift register into 74hc595 storage register
00009c 9ac0 sbi PORTB, USI_LATCH_PIN
00009d 98c0 cbi PORTB, USI_LATCH_PIN
00009e 910f pop r16
00009f 9508
; **** ОПРОС ПРИСУТСТВИЯ УСТРОЙСТВА ******************************
_1_WIRE_DETECT_PRESENCE:
0000a0 94f8 cli ; Шаг 1. выключаем глобальные прерывания
; 62 тика
0000a1 e000
0000a2 bd0c outi r16, TCNT1L, 0
0000a3 e30c
0000a4 bd0a outi r16, OCR1AL, 60 ; 480 мкс
0000a5 e405
0000a6 bd08 outi r16, OCR1BL, 69 ; 72 мкс
; предделитель 64
0000a7 e003
0000a8 bd0e outi r16, TCCR1B, (1<<CS11) | (1<<CS10)
0000a9 9ab9 _1_wire_pull ; Шаг 2. притягиваем шину
S1:
0000aa b708 in r16, TIFR
0000ab ff06 sbrs r16, OCF1A ; Шаг 3. ждем минимум 480мкс
0000ac cffd rjmp S1
0000ad 98b9 _1_wire_release ; Шаг 4. отпускаем шину
0000ae b708 S2: in r16, TIFR
0000af ff05 sbrs r16, OCF1B ; Шаг 5. ждем +- 70мкс
0000b0 cffd rjmp S2
0000b1 d00d rcall _1_WIRE_CHECK_PRESENCE ; Шаг 6. проверяем есть ли устройство на шине, и если есть то устанавливаем флаг
0000b2 e000
0000b3 bd0c outi r16, TCNT1L, 0
0000b4 e304
0000b5 bd0a outi r16, OCR1AL, 52 ; 416 мкс
S3:
0000b6 b708 in r16, TIFR
0000b7 ff06 sbrs r16, OCF1A
0000b8 cffd rjmp S3
0000b9 2700 clr r16
0000ba bd0e out TCCR1B, r16
0000bb ef0f ser r16
0000bc bf08 out TIFR, r16
; s3: in r16, TIFR
; sbrs r16, TOV1
; rjmp s3
; rcall TOV1_occured
; ser r16
; out TIFR, r16
0000bd 9478 sei
0000be 9508 ret
; **** ПРОВЕРКА НАЛИЧИЯ УСТРОЙСТВА *******************************
; Если подчиненное устройство притянет шину, то устанавливаем флаг OWPRF в единицу в регистре флагов
;
_1_WIRE_CHECK_PRESENCE:
0000bf 9bb1 sbis ONE_WIRE_PIN, ONE_WIRE_LINE
0000c0 6071 sbr ONE_WIRE_FLAGS, (1<<OWPRF)
0000c1 9508 ret
_1_WIRE_SEND_BYTE:
0000c2 931f push r17
0000c3 e313 ldi r17, DS18B20_CMD_READROM
0000c4 e008 ldi r16, 8
_s_l:
; rol r16
; brcc
0000c5 911f pop r17
0000c6 9508 ret
.DEF TRANSMIT_BIT = r9
_1_WIRE_SEND_BIT:
0000c7 930f push r16
0000c8 94f8 cli
0000c9 6072 sbr ONE_WIRE_FLAGS, (1<<OWSB)
0000ca e000
0000cb bd0c outi r16, TCNT1L, 0
0000cc e001
0000cd bd0a outi r16, OCR1AL, 1 ; 8 мкс
0000ce e009
0000cf bd08 outi r16, OCR1BL, 9 ; 64 мкс
0000d0 9ab9 _1_wire_pull
SB_1:
0000d1 b708 in r16, TIFR
0000d2 ff06 sbrs r16, OCF1A
0000d3 cffd rjmp SB_1
0000d4 fc90 sbrc TRANSMIT_BIT, 0
0000d5 98b9 _1_wire_release
SB_2:
0000d6 b708 in r16, TIFR
0000d7 ff05 sbrs r16, OCF1B
0000d8 cffd rjmp SB_2
0000d9 2700 clr r16
0000da bd0e out TCCR1B, r16
0000db 7f7d cbr ONE_WIRE_FLAGS, (1<<OWSB)
0000dc 9478 sei
0000dd 910f pop r16
0000de 9508 ret
; **** ПОЛУЧЕНИЕ ЦИФР ИЗ 16-ТИ БИТНОГО ЧИСЛА *********************
; Описание: Перемещает цифры числа в соответствующие ячейки памяти в SRAM
; путем деления этого числа несколько раз
DISPLAY_UPD_DIGITS:
0000df 94f8 cli
0000e0 935f push r21
0000e1 e054 ldi r21, 4 ; (4 раза делим) т.к индикатор четырех разрядный
; инициализация указателя (за каждый проход цикла будет инкрементироваться)
0000e2 e6a3 ldi XL, LOW(DIGITS)
0000e3 e0b0 ldi XH, HIGH(DIGITS)
.equ dividend = SRAM_TEMP_1 ; число которе будем делить
.equ divisor = 10 ; на что делим
; загружаем число которое хотим поделить в адрес SRAM делимого
0000e4 9380 0061 sts dividend, DISP_NUM_L
0000e6 9390 0062 sts dividend+1, DISP_NUM_H
; четыре раза производим деление для получения остатков
DIV_LOOP:
; заполняем нужные регистры
0000e8 9100 0061 lds dd16uL, dividend
0000ea 9110 0062 lds dd16uH, dividend+1
0000ec e02a ldi dv16uL, LOW(divisor)
0000ed e030 ldi dv16uH, HIGH(divisor)
0000ee df92 rcall div16u ; делим
0000ef 92ed st X+, drem16uL ; сохраняем остаток в ячейку по указателю и увеличиваем его
; обновляем делимое
0000f0 9300 0061 sts dividend, dres16uL
0000f2 9310 0062 sts dividend+1, dres16uH
0000f4 955a dec r21 ; декрементируем счетчик цикла
0000f5 f791 brne DIV_LOOP ; делим еще раз если не 0
0000f6 915f pop r21
0000f7 9478 sei
0000f8 9508 ret
; **** ЗАГРУЖАЕТ НУЖНЫЙ АДРЕС СИМВОЛА В R0 ***********************
DISPLAY_DECODER:
0000f9 930f push r16
0000fa 931f push r17
0000fb e4ec ldi ZL, LOW(2*DISPLAY_SYMBOLS)
0000fc e0f2 ldi ZH, HIGH(2*DISPLAY_SYMBOLS)
0000fd 2711 clr TEMP_REG_B
0000fe 0fe0 add ZL, TEMP_REG_A
0000ff 1ff1 adc ZH, TEMP_REG_B
000100 9004 lpm r0, Z
000101 911f pop r17
000102 910f pop r16
000103 9508 ret
DELAY_68us:
000104 eb03 ldi r16, 179 ; 1
_d1_loop:
000105 950a dec r16 ; 1
000106 f7f1 brne _d1_loop ; 2/1
000107 9508 ret ; 4
DEBOUNCE_SW:
000108 930f push r16
000109 931f push r17
00010a 932f push r18
00010b e025 ldi r18, 5
_loop_2:
00010c ef1f ldi r17, 255
_loop_0:
00010d ef0f ldi r16, 255
_dec_0:
00010e 950a dec r16
00010f f7f1 brne _dec_0
_loop_1:
000110 951a dec r17
000111 f7d9 brne _loop_0
_loop_3:
000112 952a dec r18
000113 f7c1 brne _loop_2
000114 912f pop r18
000115 911f pop r17
000116 910f pop r16
000117 9508 ret
DELAY:
000118 930f push r16
000119 931f push r17
00011a ef0f ldi r16, 255
_DELAY_1:
00011b ef1f ldi r17, 255
_DELAY_2:
00011c 951a dec r17
00011d 0000 nop
00011e 0000 nop
00011f 0000 nop
000120 f7d9 brne _DELAY_2
000121 950a dec r16
000122 f7c1 brne _DELAY_1
000123 911f pop r17
000124 910f pop r16
000125 9508 ret
DISPLAY_SYMBOLS:
; HGFEDCBA HGFEDCBA
000126 f9c0 .DB 0b11000000, 0b11111001 ; 0, 1
000127 b0a4 .DB 0b10100100, 0b10110000 ; 2, 3
000128 9299 .DB 0b10011001, 0b10010010 ; 4, 5
000129 f882 .DB 0b10000010, 0b11111000 ; 6, 7
00012a 9080 .DB 0b10000000, 0b10010000 ; 8, 9
firmware.asm(511): warning: .cseg .db misalignment - padding zero byte
00012b 009c .DB 0b10011100 ; °
; **** СЕГМЕНТ EEPROM ********************************************
; .ESEG
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 : 0 r9 : 1 r10: 0 r11: 0 r12: 0
r13: 0 r14: 5 r15: 5 r16: 89 r17: 23 r18: 11 r19: 7 r20: 14
r21: 8 r22: 0 r23: 3 r24: 3 r25: 2 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 : 1 brcs : 0 break : 0 breq : 0 brge : 1 brhc : 0
brhs : 0 brid : 0 brie : 0 brlo : 0 brlt : 0 brmi : 0
brne : 12 brpl : 0 brsh : 0 brtc : 0 brts : 0 brvc : 0
brvs : 0 bset : 0 bst : 0 cbi : 16 cbr : 1 clc : 1
clh : 0 cli : 3 cln : 0 clr : 6 cls : 0 clt : 0
clv : 0 clz : 0 com : 0 cp : 0 cpc : 0 cpi : 5
cpse : 0 dec : 8 eor : 1 icall : 0 ijmp : 0 in : 9
inc : 1 ld : 0 ldd : 0 ldi : 39 lds : 8 lpm : 2
lsl : 0 lsr : 0 mov : 0 movw : 0 neg : 0 nop : 3
or : 0 ori : 0 out : 27 pop : 18 push : 18 rcall : 13
ret : 11 reti : 2 rjmp : 15 rol : 4 ror : 0 sbc : 1
sbci : 0 sbi : 8 sbic : 0 sbis : 3 sbiw : 0 sbr : 2
sbrc : 1 sbrs : 6 sec : 1 seh : 0 sei : 4 sen : 0
ser : 1 ses : 0 set : 0 sev : 0 sez : 0 sleep : 0
spm : 0 st : 1 std : 0 sts : 8 sub : 2 subi : 0
swap : 0 tst : 0 wdr : 0
Instructions used: 40 out of 105 (38.1%)
"ATtiny2313A" memory use summary [bytes]:
Segment Begin End Code Data Used Size Use%
---------------------------------------------------------------
[.cseg] 0x000000 0x000258 566 12 578 2048 28.2%
[.dseg] 0x000060 0x000069 0 9 9 128 7.0%
[.eseg] 0x000000 0x000000 0 0 0 128 0.0%
Assembly complete, 0 errors, 5 warnings