;File name: vlfvmtrmg8.asm ;Copyright 2004 Richard Cappels, projects@cappels.org www.project.cappels.org ;How to connect this chip: ;Pin 7 to + 5 V ;Pins 8 and 22 to ground. ;Pin 21 connected to +5V through a decoupling network. For example a 33 uh choke ; from +5V to pin 21 and a 0.22 uf monolithinc capacitor from pin 21 to ground. ;Pin 6 connects to one end of a 22 uh loop antenna in parallel with a .033 uf capacitor. ;Pin 7 the other end of the loop antenna and capcaitor connect to pin 7, Pin 7 is also ; connected to the center tap of a pair of 220 t 1,000 Ohm resistors connected in series ; between +5V to ground. ; ;This code expects the controller, an ATMega8, to operate at 4 Mhz. ; ;The four A/D inputs have an input range of 0 to 5 Volts. ;Pin 23 Analog input A ;Pin 24 Analog input B ;Pin 25 Analog input C ;Pin 26 Analog input D ; ;The output is on-off keyed 182.818181 kHz RF, keyed by serial ASCII ;(1200 baud, 1 start bit, 2 stop bits, no parity, lsb first) ; .include "m8def.inc" ;Include file in same directory as project. ;definition of I/O ;B0 (not assigned - configure as INPUT with weak pullup) ;B1 (not assigned - configure as INPUT with weak pullup) ;B2 (not assigned - configure as INPUT with weak pullup) ;B3 (not assigned - configure as INPUT with weak pullup) ;B4 (not assigned - configure as INPUT with weak pullup) ;B5 (not assigned - configure as INPUT with weak pullup) ;B6 (not assigned - configure as INPUT with weak pullup) ;B7 (not assigned - configure as INPUT with weak pullup) .equ PORTBdata =0b11111111 ;Initial data .equ DDRBdata =0b00000000 ;Initial data ;C0 A/D A configure as INPUT ;C1 A/D B configure as INPUT ;C2 A/D C configure as INPUT ;C3 A/D D configure as INPUT ;C4 (not assigned - configure as INPUT with weak pullup) ;C5 (not assigned - configure as INPUT with weak pullup) ;C6 (not assigned - configure as INPUT with weak pullup) ;C7 (not assigned - configure as INPUT with weak pullup) .equ PORTCdata =0b11110000 ;Initial data .equ DDRCdata =0b000000O0 ;Initial data ;D0 (not assigned - configure as INPUT with weak pullup) ;D1 (not assigned - configure as INPUT with weak pullup) ;D2 (not assigned - configure as INPUT with weak pullup) ;D3 (not assigned - configure as INPUT with weak pullup) ;D4 (not assigned - configure as INPUT with weak pullup) ;D5 (not assigned - configure as INPUT with weak pullup) ;D6 AN0 ;D7 AN1 .equ PORTDdata =0b00000000 ;Initial data .equ DDRDdata =0b00000000 ;Initial data ;The statements below establish I/O pins needed for RF operation. .equ RFSigPort = PORTD ;Port output signal is to appear on. .equ RFSigDDR = DDRD ;Data Direction Register for signal output .equ RFSigPin = 6 ;Pin output signal is to appear on. .equ LEDOutPort = PORTD ;Indicator LED .equ LEDOutDDR = DDRD .equ LEDOutPin = 2 .equ CompPlusPort = PORTB ;Comparitor noninverting input (input 0) .equ CompPlusDDR = DDRB .equ CompPlusPin = 6 .equ BridgePowerPort = PORTB ;Power for voltage devider (bridging resistors) .equ BridgePowerDDR = DDRB .equ BridgePowerPin = 3 .def RFChar = r16 ;RF character I/O buffer (must be a high register) .def temp = r17 ;General purpose scratch register. .def a1 = r18 ;Three byte number .def a2 = r19 ;Three byte number .def a3 = r20 ;Three byte number .def h = r21 ;Binary to decimal conversion. .def t = r22 ;Binary to decmial conversion. .def u = r23 ;Binary to decimal conversion. .cseg .ORG $0000 ;Initializaton code rjmp start .org $0009 rjmp timer0service .org $0010 rjmp comparitorservice .include "vlfcwm8.inc" ;Include file to be in same directory as this file. start: ;Entry point after rest -initialize everything ldi temp,high(ramend) ;Initialize 16 bit Stack Pointer out sph,temp ldi temp,low(ramend) out spl,temp ldi temp,DDRBdata ;Set PORTB. out DDRB,temp ldi temp,PORTBdata out PORTB,temp ldi temp,DDRCdata ;Set PORTC out DDRC,temp ldi temp,PORTcdata out PORTc,temp ldi temp,DDRDdata ;Set PORTD. out DDRD,temp ldi temp,PORTDdata out PORTD,temp ldi temp,0b00010101 ;ITINITALIZE A TO D CONVERTER out ADCSR,temp ;Set control and status register. 4 MHz clock. sei ;Enable interrupts. rcall Typeheader ;Type the header DefaultMain: ;Main Loop ldi RFChar,'A' rcall SendRFByte ldi RFChar,$20 rcall SendRFByte ldi temp,0 rcall measure rcall SendVolts ; rcall crlf ldi RFChar,$20 rcall SendRFByte ldi RFChar,$20 rcall SendRFByte ldi RFChar,'B' rcall SendRFByte ldi temp,1 rcall measure rcall SendVolts rcall crlf ldi RFChar,'C' rcall SendRFByte ldi RFChar,$20 rcall SendRFByte ldi temp,2 rcall measure rcall SendVolts ldi RFChar,$20 rcall SendRFByte ldi RFChar,$20 rcall SendRFByte ldi RFChar,'D' rcall SendRFByte ldi temp,3 rcall measure rcall SendVolts rcall crlf rcall Delaylots rjmp DefaultMain crlf: ;Send Carrige return and line feed ($0D, $0A) ldi RFChar,$0D rcall SendRFByte ldi RFChar,$0A rcall SendRFByte ret Typeheader: ;Type header push ZL push ZH ldi ZH,high(2*hellomessage) ;Load high part of byte address into ZH ldi ZL,low(2*hellomessage) ;Load low part of byte address into ZL rcall typeromstring ;Send it pop ZH pop ZL ret hellomessage: .db $0A,$0D .db $0A,$0D .db "TESTCODE" .db $0A,$0D .db $00,$00 typeromstring: ;Type on RS-232 terminal screen call with location of string in Z. push ZL ;Save Z on stack. push ZH srsa1: lpm ;Load byte from program memory into r0. tst r0 ;Check if we've reached the end of the message. breq finishsendsteringA;If so, return. mov RFChar,r0 rcall SendRFByte ;Sends only via RS-232. adiw ZL,1 ;Increment Z registers rjmp srsa1 finishsendsteringA: pop ZH ;Pop Z from stack. pop ZL ret Measure: ;Measure A/D channel. Enter with channel number in temp. Exit with data in YH:YL ;Allowed range is 0..5 push temp sbi ADCSR,ADEN ;Enable A/D converter. andi temp,0b00000011 ;Mask off upper bits to restrict range of channel selction. ori temp,0b01000000 ;Set reference voltage bit. out ADMUX,temp ;Select channel. sbi ADCSR,ADSC ;Start conversion. wfc: sbis ADCSR,ADIF ;Wait for bit to be set, indicating conversion complete. rjmp wfc sbi ADCSR,ADIF ;Clear interrupt flag. in YL,ADCL ;Get data into Y register. in YH,ADCH pop temp ret SendVolts: ;Enter with input value in YH:YL. YH,YL,a1,a2,a3,temp,H,T,U modified. ;Scale input with range of 0 to 1023 with a digit expression of range ;from 000 to 489. This is for a 5 volt full scale input 10 bit ADC. ;Multiply input by 489 and divide by 1,000 to get answer in tens of ;millivolts. push temp clr a1 ;Clear the 3 byte number clr a2 clr a3 mloop: tst YL brne notzero tst YH brne notzero rjmp countdone notzero: sbiw YL,1 ;Decrement the 10 bit value and add 489 to each time ldi temp,$E9 add a1,temp ;To multiply number in Y by 489 ldi temp,$01 adc a2,temp clr temp adc a3,temp rjmp mloop countdone: ;At this point, the product is in a1,2,3 clr H clr T clr U MoreH: inc H subi a1,$A0 ;Find out how many 100,000's sbci a2,$86 sbci a3,1 brcc MoreH ldi temp,$A0 ;Subtracted one too many, add back on. add a1,temp ldi temp,$86 adc a2,temp ldi temp,1 adc a3,temp dec H MoreT: inc T subi a1,$10 ;Find out how many 10.000's sbci a2,$27 sbci a3,$00 brcc moreT ldi temp,$10 ;Subtracted one too many, add back on. add a1,temp ldi temp,$27 adc a2,temp ldi temp,0 adc a3,temp dec T MoreU: inc U subi a1,$E8 ;Find out how many 10.000's sbci a2,$03 sbci a3,$00 brcc moreT ldi temp,$E8 ;Subtracted one too many, add back on. add a1,temp ldi temp,$03 adc a2,temp ldi temp,0 adc a3,temp dec U ;Convert to ASCII and send subi H,-48 ;Send Hundreds mov RFChar,H rcall SendRFByte subi T,-48 ;Send Tens mov RFChar,T rcall SendRFByte subi U,-48 ;Send Units mov RFChar,U rcall SendRFByte pop temp ret Delaylots: ;Delay 987 ms. All registers saved. push h push t push u ldi h,20 lh: clr t lt: clr u lu: dec u brne lu dec t brne lt dec h brne lh pop u pop t pop h ret .exit