; ; radiotherm_tx.asm ; ; D:\_RNH\_DEV\Thermometer\radio_therm\Firmware\TX\radiotherm_tx.asm ; ; Project: [RadioThermometer] ; Module: [RNH-09_TXTherm026] ; ; ; RomaNets Software, 2007 ; ; ; Description: ; ; Измеряем температуру и передаем результаты в порт ... ; Микроконтроллер ATtiny2313 принимает от термометра DS18S20 данные в виде ; двух байт. Первый байт делит на 2, чтобы получить т-ру в градусах, а не ; в полуградусах. Если второй байт == FF, это значит, т-ра отрицательная, ; и тогда первый байт комплементируем. Выставляем на порт B младшие 4 бита ; первого байта, даем отрицательный импульс _TE кодеру MC145026, который ; передает данные передатчику TX-433. Потом старшему биту первого байта ; присваиваем значение любого бита второго байта - это будет знак т-ры, ; 1-минус, 0 - плюс. Выставляем на порт В и даем отрицательный импульс ; кодеру. В начале посылки передаем 5 (2) ниблов 1111 и один 0000 ; синхронизации, потом два нибла температуры. Старший бит последнего нибла ; является знаком т-ры. Потом пауза. И повторяем посылки. ; ; У uC 1 линия для термометра, 4 линии данных для одной посылки, и 1 VT. ; И три остается для ISP. ; ; Hardware Notes: ; ATmega2313 Running at 500 kHz (using an External Crystal), 100 pF, 100pF ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Hardware Notes: ; AVR2313 Running at 1 MHz (using an External Crystal) ; now 500 kHz ; PB7:0 - Temperature Data Bits (Pins 14:7) ;---------------------------------- ; PD3 - DS1820 Line ; PD4 - PULSE FOR CODER MC145026 ;---------------------------------- .equ BIT_DS1820Line = 3 ; ; Connections: ; ; +12V ; LM2931-TA5 (+5V) ; ATtiny2313 - this ; DS18S20 - Thermometer ; MC145026 - Coder ; TX-433 - Transmiter ; ; PortD.3 to Thermometer.2 data ; PortD.3 4.7 kOm to +5 ; PortD.4 to Coder._TE transmit enable ; ; PortB.0 to Coder.D6 bit 0 ; PortB.1 to Coder.D7 bit 1 ; PortB.2 to Coder.D8 bit 2 ; PortB.3 to Coder.D9 bit 3 .include "tn2313def.inc" ; Register Definitions: .DEF Count = R16 ; Timer Values .DEF Counthi = R17 .DEF DS18Data = R18 ; DS18S20 Output Value ; .DEF DS1 = R28 ; Values Read from DS1820 .DEF DS2 = R29 .MACRO NEGOTIVE_PULSE_TE ; PUSLE TO CODER to _TE CBI PORTD, 4 rcall BigDlay SBI PORTD, 4 rcall BigDlay rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 .ENDMACRO .CSEG .ORG 0 rjmp RESET ; $000 MCU Reset Vector /* rjmp EXT_INT0 ; $001 rjmp EXT_INT1 ; $002 rjmp TIM_CAPT1 ; $003 rjmp TIM_COMP1 ; $004 rjmp TIM_OVF1 ; $005 rjmp TIM_OVF0 ; $006 rjmp UART_RXC ; $007 rjmp UART_DRE ; $008 rjmp UART_TXC ; $009 rjmp ANA_COMP ; $00A EXT_INT0: reti EXT_INT1: reti TIM_CAPT1: reti TIM_COMP1: reti TIM_OVF1: reti TIM_OVF0: reti UART_RXC: reti UART_DRE: reti UART_TXC: reti ANA_COMP: reti */ ;-------------------------------------------------------------------- ;TIM_OVF1: ;-------------------------------------------------------------------- ; in R0, SREG ; ; out SREG, R0 ; reti ;//////////////////////////////////////////////////////////////////// RESET: ;//////////////////////////////////////////////////////////////////// ldi r16, Low(RAMEND) out SPL, r16 ldi R18, $FF ; All portB to Outputs out DDRB, R18 clr R18 out PORTB, R18 ; All portB 0 ldi R18, $70 ; 01110000 Make PortD 5 & 6 Output, and 4 for CODER MC145026 out DDRD, R18 ldi R18, $1C ; 00011100 Enable Pull Up on PD2 for Time Set Button and the DS1820 ; PD4 write 1 out PORTD, R18 ; Initialize the Timers ;ldi R18, 5 ; Start the Timer0 with 1024 Cycle Delay ;ldi R18, 4 ; Start the Timer0 with 256 Cycle Delay ;ldi R18, 3 ; Start the Timer0 with 64 Cycle Delay ;out TCCR0, R18 ;;;;ldi R18, 4 ; Start the Timer0 with 256 Cycle Delay ;ldi R18, 3 ; Start the Timer1 with 64 Cycle Delay ;ldi R18, 2 ; Start the Timer1 with 8 Cycle Delay ;ldi R18, 1 ; Start the Timer1 with CK out TCCR1B, R18 ;ldi R18, $02 ; Enable Timer0 Interrupt ;;;;ldi R18, $80 ; Enable Timer1 Interrupt ;ldi R18, $82 ; Enable TimerS Interrupt ;;;;out TIMSK, R18 ;;;;SEI ; Enable Interrupts Loop: ; Loop Around ldi DS1, $FF ; Send synchro pulses out PORTB, DS1 ; mov low 4 bits to CODER NEGOTIVE_PULSE_TE NEGOTIVE_PULSE_TE ;;NEGOTIVE_PULSE_TE ;;NEGOTIVE_PULSE_TE ;;NEGOTIVE_PULSE_TE ldi DS1, $00 ; Send synchro pulses out PORTB, DS1 ; mov low 4 bits to CODER NEGOTIVE_PULSE_TE ; Check DS1820 rcall DS_Reset ldi DS18Data, $CC ; Start the Temperature Conversion rcall DS_Send ldi DS18Data, $44 rcall DS_Send rcall Dlay160 ; Wait 500+ usec for Temperature Conversion rcall Dlay160 rcall Dlay160 rcall DS_Reset ldi DS18Data, $CC ; Start the Temperature Conversion rcall DS_Send ldi DS18Data, $BE rcall DS_Send rcall Dlay160 rcall DS_Get ; Now, Get the Data Bytes mov DS1, DS18Data rcall Dlay160 rcall DS_Get mov DS2, DS18Data ; Get the Value Register andi DS2, 1 ; Do we Have a Negative Temperature? breq Temp_Out ; No, Output the Temperature neg DS1 ; Now, Make the Temperature Positive Temp_Out: ; Output the Temperature clc ; Divide Temperature by 2 before Outputting ror DS1 mov DS18Data, DS1 out PORTB, DS1 ; mov low 4 bits to CODER NEGOTIVE_PULSE_TE SWAP DS1 ; get ready for next half byte BST DS2, 0 BLD DS1, 3 out PORTB, DS1 ; mov hi 4 bits to CODER NEGOTIVE_PULSE_TE rcall BigDlay rcall BigDlay rcall BigDlay rcall BigDlay rcall BigDlay rcall BigDlay rcall BigDlay rcall BigDlay rcall BigDlay rcall BigDlay ; ;Sleep ; ;ldi r20, $3F ; Power Down Mode ; ldi r20, $2F ; Idle Mode ; out MCUCR, r20 ; sleep rjmp Loop ; Subroutines ;==================================================================== DS_Get: ; Get a Character from the DS1820 ;==================================================================== ldi Count, 8 ; Sending Out 8 Bits DSG_Loop: ; Loop Around Here sbi DDRD, BIT_DS1820Line ; DS1820 Line as Output cbi PORTD, BIT_DS1820Line ; Pull Down DS1820 Line rjmp DSG_Dlay1 ; Delay 4 Cycles for DS1820 to Recognize Low DSG_Dlay1: cbi DDRD, BIT_DS1820Line ; Let the Line Go High sbi PORTD, BIT_DS1820Line ; Enable Internal Pull Up clc ; Make Sure the Carry is Clear sbic PIND, BIT_DS1820Line ; Is the Bit Gone High? sec ; Yes, It's a one ror DS18Data ; Rotate the LSB into Carry ldi Counthi, $14 ; Delay 60 Cycles To the Next Bit DSG_Loop2: dec Counthi brne DSG_Loop2 dec Count ; Have we Send out 8 Bits? brne DSG_Loop ret ;==================================================================== DS_Send: ; Send a Character to the DS1820 ;==================================================================== ldi Count, 8 ; Receiving 8 Bits DS_Loop: ; Loop Around Here sbi DDRD, BIT_DS1820Line ; DS1820 Line as Output cbi PORTD, BIT_DS1820Line ; Pull Down DS1820 Line rjmp DSS_Dlay1 ; Delay 4 Cycles for DS1820 to Recognize Low DSS_Dlay1: rjmp DSS_Dlay2 DSS_Dlay2: ror DS18Data ; Rotate the LSB into Carry brcc DS_Zero ; Sending a Zero sbi PORTD, BIT_DS1820Line ; Make the Line High DS_Zero: ldi Counthi, $0A ; Now, Delay 30 Cycles for "0" DSS_Loop1: dec Counthi brne DSS_Loop1 sbi PORTD, BIT_DS1820Line ; Bring the Line High cbi DDRD, BIT_DS1820Line ; Have the Line High ldi Counthi, $14 ; Delay 60 Cycles To the Next Bit DSS_Loop2: dec Counthi brne DSS_Loop2 dec Count ; Have we Send out 8 Bits? brne DS_Loop ret ;==================================================================== DS_Reset: ; Reset the DS1820 ;==================================================================== sbi DDRD, BIT_DS1820Line ; Make PortD.0 an Ouput cbi PORTD, BIT_DS1820Line ; Put it Low ldi R16, $78 ; Loop 600 / 5 Cycles ldi R17, $01 DS_Loop1: dec R16 ; Decrement the Low 8 Bits brbc 1, DS_Skip1 ; Skip the Next if Zero is Clear dec R17 ; Decrement the High 8 Bits DS_Skip1: brne DS_Loop1 ; Loop if the Zero Flag Isn't Set sbi PORTD, BIT_DS1820Line ; Make Sure Pull Up is Enabled cbi DDRD, BIT_DS1820Line ; Now, Bring the Line High ldi R16, $DC ; Loop 1,100 / 5 Cycles ldi R17, $01 DS_Loop2: ; dec R16 ; Decrement the Low 8 Bits brbc 1, DS_Skip2 ; Skip the Next if Zero is Clear dec R17 ; Decrement the High 8 Bits DS_Skip2: brne DS_Loop2 ; Loop if the Zero Flag Isn't Set ret ;==================================================================== Dlay160: ; Delay 160 Cycles ;==================================================================== ldi R16, 53 ; Loop xxx/3 Cycles D160_Loop: dec R16 brne D160_Loop ; Two Cycles for this Jump ret ;==================================================================== Dlay5: ; Delay 5000 Cycles ;==================================================================== ldi R16, $E8 ; Loop x,000 / 5 Cycles ldi R17, $04 D5_Loop: ; dec R16 ; Decrement the Low 8 Bits brbc 1, D5_Skip ; Skip the Next if Zero is Clear dec R17 ; Decrement the High 8 Bits D5_Skip: brne D5_Loop ; Loop if the Zero Flag Isn't Set ret BigDlay: rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 rcall Dlay5 ret