Ich habe wie schon geschrieben ein Programm erstellt, daß eine Spannung misst und auf 4 LED's ausgeben soll.
Im AVR Simulator läuft das Ganze allerbest. Nun habe ich das Programm in den ATtiny15 geschrieben mit den passenden EEprom-Werten.
Nach dem Einschalten wird auf den LED's zufällig was angezeigt. Wenn man dann von Hand einen RESET macht dann leuchtet die richtige LED. Leider ändert sich aber an den LED's nichts wenn man die Analogspannung variiert. Es wird aber jeweils nach dem RESET die passende LED angezeigt.
Warum wird anscheinend die AD-Wandlung nicht vom Timer aufgerufen???
Auch sollten nach einem RESET die LED's so ca. 1/2 Sekunde lang leuchten. Diese blitzen aber nur kaum merklich auf. Daran ändert sich auch nichts wenn man den Prescaler Wert des Timers ändert.
Ich bin jetzt ziemlich ratlos denn eigentlich sollte das Ganze funktionieren.
Hier das Programm:
Code:
; **********************************************************
; *                    Prozessor Attiny15                  *
; **********************************************************
; *         Temperaturüberwachung über einen NTC           *
; **********************************************************
; * Dazu wird ein Analogsignal über einen AD-Wandler in    *
; * einen Digitalen Zahlenwert übersetzt.                  *
; * Die Abfrage findet in etwa im Sekundentakt statt. Dazu *
; * wird über den Timer0 ein Interrupt generiert.          *
; * Die Vergleichswerte für die einzelnen Temperaturberei- *
; * che werden in der EEprom Sektion des ATtiny15 hinter-  *
; * legt. Dadurch sind Anpassungen einfach an den jeweili- *
; * gen Meßfühler möglich.                                 *
; * Das Ergebnis wird mit 4 LED's verschiedener Farben an- *
; * gezeigt:                                               *
; *                                                        *
; * LED1 (blau) = Temperatur ist niedriger als 60°C        *
; * LED2 (grün) = Temperatur befindet sich 60°C - 100°C    *
; * LED3 (gelb) = Temperatur befindet sich 100°C - 115°C   *
; * LED4 (rot)  = Temperatur ist höher als 115°C           *
; **********************************************************
; * (RESET/ADC0) PB5 = Pin1  Pin8 = Vcc                    *
; *       (ADC3) PB4 = Pin2  Pin7 = PB2 (ADC1/SCK/T0/INT0) *
; *       (ADC2) PB3 = Pin3  Pin6 = PB1 (AIN1/ MISO/OC1A)  *
; *              GND = Pin4  Pin5 = PB0 (AIN0/AREF/MOSI)   *
; **********************************************************

.include "TN15def.inc"			; Prozessor ATtiny15

.eseg							; Kennung für EEprom

; **********************************************************
; *     Temperaturvergleichswerte noch anpassen !!!        *
; **********************************************************

TempKalt:	.dw 0x5555			; Wert für Temperatur bis 60°C
TempWarm:	.dw 0x7777			; Wert für Temperatur 60°C - 100°C
TempHoch:	.dw 0x9999			; Wert für Temperatur 100°C-115°C
TempKrit:	.dw 0xBBBB			; Wert für Temperatur über 115°C

.cseg							; Kennung für Programmcode

.def TMP1      = R16 			; Allgemeine Variable
.def LEDStat   = R17			; LED-Register
.def Prescaler = R18			; Timer0 Startwert
.def ADHigh    = R19			; High-Byte Analogwandler
.def ADLow     = R20			; Low-Byte Analogwandler
.def EEprom    = R21			; EEprom Adresse
.def EEData    = R22			; EEprom Daten
.def TPHigh	   = R23			; Temperaturvergleich High-Byte
.def TPLow     = R24			; Temperaturvergleich Low-Byte	
.def SCount    = R25			; Schleifenzähler
.def Vergleich = R26			; Vergleichsergebnis
.def LEDWert   = R27			; Übergabevariable (Unterprogramm)		  

.org 0x0000						; Programm Startadresse $0000
	
	rjmp Init					; Einsprung ins Hauptprogramm

.org 0x0005						; Interrupt Timer0

	rjmp Led					; Led im Sekundentakt blinken

.org 0x0008						; Interrupt AD-Wandler

	rjmp ADFertig				; Ergebnis von AD holen

.org 0x0009						; Programmstart bei $0009

Init:

	ldi TMP1,0b00010111			; Pin 2,5,6 und 7 auf Ausgabe
	out DDRB,TMP1				; schalten und alle LED's 
	ldi TMP1,0x00
	mov Vergleich,TMP1			; Vergleichsregister löschen
	out PORTB,TMP1				; einschalten.
	sbr LEDStat,0b11000000		; LED-Status (alle an) speichern
	ldi TMP1,0x01	
	rol TMP1
	out TIMSK,TMP1				; Timer0 Interrupt freigeben
	ldi TMP1,0x02				; Teilerfaktor 8
	out TCCR0,TMP1				; für Timer0 einstellen.
	ldi TMP1,0x0				; Timer0 mit Startwert
	out TCNT0,TMP1				; vorladen und Startwert
	mov Prescaler,TMP1			; speichern.
	ldi TMP1,0x82				; Interne Referenzspannung
	out ADMUX,TMP1				; einschalten und Pin3 Analogeingang
	ldi TMP1,0x8F				; AD-Wandler einschalten und
	out ADCSR,TMP1				; Interrupt für AD freigeben.
	ldi TMP1,0x00				; Schleifendurchläufe festlegen	
	mov SCount,TMP1
	sei							; Interrupts freigeben	

Start:

; **********************************************
; *   Hauptprogramm für Temperaturauswertung   *
; **********************************************

Schleife:	
 	
	sbrc LEDStat,7
	rjmp Schleife	

LED1:
	ldi EEprom,0x00				; Vergleichswertadresse vorgeben
	rcall LeseEEprom			; und Wert aus EEprom holen.
	cp ADLow,TPLow				; 16-Bit Vergleich vornehmen.
	cpc ADHigh,TPHigh			; Meßwert > Vorgabewert?
	brcc LED2    				; Ja, dann zur nächsten LED
	ldi LEDStat,0b00010110		; sonst LED1 einschalten.	
	rcall LEDAkt
	rjmp LEDEnde

LED2:
	ldi EEprom,0x01				; Vergleichswertadresse vorgeben
	rcall LeseEEprom			; und Wert aus EEprom holen.
	cp ADLow,TPLow				; 16-Bit Vergleich vornehmen.
	cpc ADHigh,TPHigh			; Meßwert > Vorgabewert?
	brcc LED3   				; Ja, dann zur nächsten LED
	ldi LEDStat,0b00010101		; sonst LED2 einschalten.
	rcall LEDAkt
	rjmp LEDEnde

LED3:
	ldi EEprom,0x02				; Vergleichswertadresse vorgeben
	rcall LeseEEprom			; und Wert aus EEprom holen.
	cp ADLow,TPLow				; 16-Bit Vergleich vornehmen.
	cpc ADHigh,TPHigh			; Meßwert > Vergleichswert?
	brcc LED4					; Ja, dann zur nächsten LED
	ldi LEDStat,0b00010011		; sonst LED3 einschalten.
	rcall LEDAkt
	rjmp LEDEnde

LED4:
	ldi EEprom,0x03				; Vergleichswertadresse vorgeben
	rcall LeseEEprom			; und Wert aus EEprom holen.
	cp ADLow,TPLow				; 16-Bit Vergleich vornehmen.
	cpc ADHigh,TPHigh			; Meßwert > Vergleichswert
	;brcc LED4					; Ja, dann LED4 eingeschaltet lassen
	;sbr LEDStat,0b00010111		; sonst alle LED's ausschalten
	;out	PORTB,LEDStat			; und LED4
	;cbr LEDStat,0b00010000		; einschalten
	;out PORTB,LEDStat
	ldi LEDStat,0b00000111
	rcall LEDAkt	


LEDEnde:	
	sbr LEDStat,0b10000000	
	rjmp start					; Hauptprogrammende


; >>>>>>>>>> INTERRUPTPROGRAMME <<<<<<<<<<

; ****************************************
; *     Interrupt LED An/Aus Timer0      *
; ****************************************
 
Led:
	out TCNT0,Prescaler 		; Timer mit Startwert laden
	sbrs LEDStat,6				; Startbit LED löschen gesetzt?
	rjmp Tim0
	cbr LEDStat,6
	andi LEDStat,0b10111111
	ori LEDStat,0b00010111
	out PORTB,LEDStat	

Tim0:
	sbi ADCSR,ADSC				; AD-Wandlung starten.
	reti						; Rücksprung zum Hauptprogramm

; ****************************************
; *        Interrupt AD-Wandler          *
; ****************************************

ADFertig:
	cbr LEDStat,0b10000000		; Kennung (alle Led an) löschen
	in ADHigh,ADCH				; High-Byte AD speichern
	in ADLow,ADCL				; Low-Byte AD speichern
	reti


; >>>>>>>>>> UNTERPROGRAMME <<<<<<<<<<


; ****************************************
; *         EEprom Werte Lesen           *
; ****************************************

LeseEEprom:
	lsl EEprom					; Adresse *2 für 2-Byte Sprung
	out EEAR,EEprom				; Adresse in EEprom schreiben.
	ldi TMP1,0x01				; Dazu Lesefreigabe ins
	out EECR,TMP1				; EEprom-Steuerregister schreiben.
	in TPHigh,EEDR				; EEprom-Daten in High-Byte.
	inc EEprom					; Low-Byte des Vergleichswert 
	out EEAR,EEprom				; aus dem EEprom holen.
	out EECR,TMP1				; Lesefreigabe schreiben und
	in TPLow,EEDR				; EEprom-Daten holen.
	ret

; *****************************************
; *         LED's aktualisieren           *
; *****************************************

LEDAkt:
	mov LEDWert,LEDStat			; Wert übergeben und
	out PORTB,LEDStat			; auf Port ausgeben.
	ret