;************************************************************
;--------------Lambda-Anzeige mit LEDs---------------
;
; AVR 90S1200, 1 MHz, interner Oszillator
; Eingang Lambda-Sonde auf PIN B1
; RC-Glied 100k, 10nF
;
;      V 1.1 (c) 2001/2002 MDvP       mailto:MDvP@gmx.de
;      Stand 01.12.2002
;************************************************************
; .nolist
.include "1200def.inc"
; .list

.def	temp1	=r15		; Null
.def	temp	=r16		;Scratch register
.def	result	=r17		;Result
.def	sum	=r18
.def	Ad	=r19
.def	c0	=r23
.def	c1	=r24
.def	c2	=r25
.def	XL	=r26
.def	XH	=r27
.def	YL	=r28
.def	YH	=r29
.def	ZL	=r30
.def	ZH	=r31


.cseg

	.org $0000
		rjmp RESET      	; Reset handle
	.org INT0addr		
		reti			; Extern Interrupt0 Vector Addresse
	.org OVF0addr
		rjmp ANA_OVR	  	; Timer0 overflow
	.org ACIaddr
;---------------------------------------
ANA_COMP:       in      result,TCNT0    ; Timer abfragen
		subi	result,7	; Rechenzeit kompensieren
		out     TCCR0,temp1         
		cbi     PORTB,PB2       ; Kondensator entladen
		set			; Flag setzten
		ret			; return, Interrupt gesperrt
;---------------------------------------
ANA_OVR:	ser	result
		out     TCCR0,temp1         
		cbi     PORTB,PB2       ; Kondensator entladen
		set			; Flag setzten
		ret			; return, Interrupt gesperrt
;---------------------------------------
RESET:		ldi	temp,0b10110000 ; PortB LEDs aus
		out	PORTB,temp
		ldi	temp,0b11111100 ; PortB 0,1 Input
		out	DDRB,temp
		ser 	temp
		out	PORTD,temp	; PortD LEDs aus
		out	DDRD,temp	; PortD als Ausgang
		ldi	temp,0b00001110	; Watchdog 1 s
		out	WDTCR,temp
		ldi     temp,$0B   	; Komparator ein
		out     ACSR,temp 	; enable comparator interrupt
		ldi     temp,$02      	; Enable timer interrupt
		out     TIMSK,temp
		clr	temp1
;----------------------------------------------------------------
Main:		wdr			; Watchdog reset
		clr	xl
		clr	xh
		ldi	Ad,128		; 100 mal integrieren	
AD_convert:	ldi 	c0,250		; 1 ms Delay
Delay:		nop
		dec 	c0
		brne 	Delay
		clr	result
		sbic	ACSR,ACO	; für sehr mageren Bereich
		rjmp	Ready		; nix messen, sonst
		out     TCNT0,temp1	; clear Counter
		clt			; Flag löschen
		ldi	temp,$01	; Timer0 mit prescaling 1
		out     TCCR0,temp    
		sbi     PORTB,PB2       ; Kondensator laden
		sei
Wait:		brtc	Wait		; Warte bis Flag
Ready:		add	xl,result	; addieren
		adc	xh,temp1
		dec	Ad		; Integrationszähler
		brne	AD_convert	; Fertig?
		clr	zl
		lsl	xl		; Summe *2
		rol	xh		; der Mittelwert ist nun in xh
		brne	L1		; Wenn Null
		inc	xh		; Dann erhöhen
L1:		rcall	EERead		; Daten lesen
		inc	zl
		cp	xh,r0		; Vergleichen
		brlo	L1		; Weiter?
		dec	zl		; EEProm address
		lsl	zl		; *2
		subi	zl,-22		; +22
		rcall	EERead		; Daten lesen
		mov	yl,r0		; sichern
		inc	zl
		rcall	EERead		; Daten lesen
		mov	yh,r0		; sichern
		com	yl		; invertieren
		com	yh
		andi	yl,0b10110000	; Bits ausblenden
		out	PORTB,yl	; Ausgabe Port B
		out	PORTD,yh	; Ausgabe Port D
		rjmp	Main		; Schleife
;---------------------------------------
EERead:		sbic	EECR,EEWE	; Warten bis Lesen ok
		rjmp	EERead
		out	EEAR,zl		; Addresse laden
		sbi	EECR,EERE	; EEPROM Read strobe
		in	r0,EEDR		; Daten lesen
		ret
;--LED-Daten----------------------------------------
;- Entweder für Dot-Display

.include "Dot.asm"

;- oder für Bargraph

; .include "Bar.asm"
