PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Warum sind AD-Werte auf 0?



rogerberglen
12.08.2007, 22:03
Ich habe mal Zeit gefunden und ein kleines Programm erstellt, daß ca. 0.5s den Pin ADC2 abfrägt und die anliegende Spannung in einen digitalen Wert wandelt. Ich kann aber in AVR-Studio den betreffenden Pin auf 1 setzen so viel ich will. Das Ergebnis in ADCH und ADCL ist grundsätzlich 0.
Habe ich da irgendwas übersehen? Denn der Interrupt für die AD-Wandlung wird korrekt aufgerufen. Um das Anzuzeigen blinkt eine LED jedesmal mit sobald der ADC-Eingang abgefragt wird.
Momentan werden die Werte aus ADCH und ADCL noch nicht ausgelesen! Aber in AVR sieht man schon, daß der Wert immer 0 ist.


.include "TN15def.inc" ; Prozessor ATtiny15

.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

.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,0x01 ; Pin5 auf Ausgabe
out DDRB,TMP1 ; schalten.
rol TMP1
out TIMSK,TMP1 ; Timer0 Interrupt freigeben
ror TMP1
mov LEDStat,TMP1 ; LED-Status speichern.
out PORTB,TMP1 ; LED ausschalten
ldi TMP1,0x02 ; Teilerfaktor 8
out TCCR0,TMP1 ; für Timer0 einstellen.
ldi TMP1,0x0A ; 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,0x88 ; AD-Wandler einschalten und
out ADCSR,TMP1 ; Interrupt für AD freigeben.
sei ; Interrupts freigeben

Start:

; Hier kann ein Hauptprogramm stehen!

rjmp start ; Hauptprogrammende


; ****************************************
; * Interrupt LED An/Aus Timer0 *
; ****************************************

Led:
out TCNT0,Prescaler ; Timer mit Startwert laden
sbic PORTB,PORTB0 ; Led an?
rjmp LedAn ; Nein, dann einschalten
sbi PORTB,PORTB0 ; Ansonsten ausschalten
sbi ADCSR,ADSC ; AD-Wandlung starten
reti ; Interrupt verlassen

LedAn:
cbi PORTB,PORTB0 ; Led einschalten und
sbi ADCSR,ADSC ; AD-Wandlung starten.
reti ; Rücksprung zum Hauptprogramm

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

ADFertig:


reti

linux_80
12.08.2007, 22:56
Hallo,

Du machst das im Simulator? Da müsste man dann jetzt noch genau wissen, ob der das mit dem ADC auch so kann :-k

Soweit würds aber gut ausschauen, bis auf den ADC-Takt, der muss noch etwas runter, schau Dir mal den Prescaler dazu an, in Register ADCSR, der Takt sollte unter 200kHz sein. Du lässt das mit 800 laufen.
Da der T15 mit 1,6MHz läuft, sollte es mit dem Teiler 8 klappen.

rogerberglen
13.08.2007, 08:56
Ich meine mal in einem Beitrag gelesen zu haben, daß man mit dem AVR-Studio den betreffenden Eingang auf 1 schaltet und der ADC halt dann den vollen Wert anzeigt.
Noch eine Gegenfrage: Du schreibst, daß der AT15 mit 1.6MHz läuft. Bei mir zeigt AVR-Studio aber an, daß dieser mit 4MHz laufen würde.
Wo kann man das den einstellen? Sonst stimmen ja meine Timereinstellungen nicht!
Ich habe auch noch das Problem, daß ich keinen genauen Sekundentakt hinbekomme. Gibt es da ein Beispiel für einen genauen Sekundentakt?
In meinem Fall würde dann die AD-Wandlung alle 0,5s stattfinden.

linux_80
14.08.2007, 00:20
Zur Simulator-Frequenz, wenn der Simulator läuft, mit Alt+O die Simulator-Options öffnen (oder im Menü Debug ganz unten)
hier kann man u.a. die Frequenz anpassen.

Die Sache mit dem genauen TimerTakt, erst den Timerwert ausrechnen (incl. Prescaler usw.), bis zu diesem, bzw. von diesem, er wegzählt um diesen Takt zu bekommen, und dann in der ISR am Anfang immer diesen Wert ins Timerregister schreiben, damit es beim nächstenmal wieder genau die gleiche Zeit dauert, danach kann man an der ISR den Rest machen falls gewünscht.

Gibt hier auch irgendwo schon Beispiele, schau auch mal ins Wiki.

The Man
18.08.2007, 08:03
das ist schon richtig so, mit der Sache der ADC Register.
Dann müsste sich das AVR Studio ja Zahlen "ausdenken".
Ich muss das auch so machen, dass ich die per Hand mit Werten beschreibe und dann auch das entsprechene BIT in ADCSRA setzen
muss.

rogerberglen
18.08.2007, 12:44
Gut! Ich kann also zum Testen die Register des AD-Wandlers von Hand beschreiben um den weiteren Ablauf meines Programmes überprüfen zu können.
Kann man dann davon ausgehen, daß die interne Referenzspannung als auch die zugeführte Spannung vom AD in 10 Bit aufgelöst wird?
2,54V = 11 11111111 0V = 00 00000000.
Denn dann könnte ich die entsprechenden Vorgabewerte berechnen bei welcher Eingangsspannung sich dann wie was reagiert in meinem Programm.
Liege ich da richtig?