Forum: Mikrocontroller und Digitale Elektronik ATmega1284P ADC Initialisierung Probleme - Assembler


von Bernhard S. (bernhard)


Lesenswert?

Bitte helft mir,

der ADC soll im "Free Running mode" betrieben werden, aber der ADC

startet nur eine Wandlung und dann ist plötzlich das ADSC-BIT (Bit6)

im ADCSRA-Register gelöscht,

der ADC wandelt nicht mehr, was mache ich falsch ?

1
; Referenz + Vorteiler + INPUT
2
ldi temp,((0<<REFS1)|(1<<REFS0)|(0<<ADLAR)|(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0)) 
3
STS ADMUX, temp
4
5
; ADC Enable
6
ldi temp,((1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADIF)|(0<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0)) 
7
STS ADCSRA,temp 
8
9
; ADCSRA auslesen
10
LDS temp,ADCSRA  ---> Ergebnis: 0b11000110
11
12
; lange Pause  
13
call wait_100ms
14
15
; ADCSRA auslesen
16
LDS temp,ADCSRA  ---> Ergebnis: 0b10010110
17
18
; ADC auslesen
19
LDS temp1,ADCL
20
LDS temp2,ADCH
21
22
; ADIF clear durch "1"
23
LDS temp,ADCSRA
24
STS ADCSRA,temp
25
26
; ADCSRA auslesen
27
LDS temp,ADCSRA  ---> Ergebnis: 0b10000110
28
29
; lange Pause  
30
call wait_100ms
31
32
; und hier liegt das Problem, "Free Running" ist nicht aktiv
33
34
35
; ADCSRA auslesen
36
LDS temp,ADCSRA  ---> Ergebnis: 0b10000110


Danke

Bernhard

von MWS (Gast)


Lesenswert?

Bernhard S. schrieb:
> ldi
> temp,((1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADIF)|(0<<ADIE)|(1<<ADPS2)|(1<< 
ADPS1)|(0<<ADPS0))

> der ADC wandelt nicht mehr, was mache ich falsch ?

ADATE ist 0.

von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Danke MWS (Gast), das war die Ursache.

Doch nun das nächste Problem.

Mehrere ADC-Eingände sollen nacheinander gemessen werden.

Nach der Kanal-Umschaltung ist vermutlich eine längere Pause (ca.1ms) 
nötig, bis sich die interne ADC-Umschaltung beruhigt hat.

Ist das korrekt, muss das so sein?


Ich häng mal den kompletten Programmcode mit an.
1
; ##############################################################################
2
; ##############################################################################
3
; ##############################################################################
4
; OUT: temp1+temp2                                
5
ADC_MESSUNG_TEMP1_TEMP2:
6
7
ADC_MESSUNG_TEMP1_TEMP2_w1:
8
  ; warten bis ADIF-FLAG gesetzt  
9
  LDS temp,ADCSRA    ; auslesen  
10
  sbrs temp, ADIF    ; skip if...
11
  rjmp ADC_MESSUNG_TEMP1_TEMP2_w1
12
13
  ; PAUSE              
14
  call wait_1ms
15
16
  ; ADC-START (ADIF-FLAG löschen durch logisch "1")  
17
  LDS temp,ADCSRA    ; REGISTER auslesen        
18
  STS ADCSRA,temp    ; zurückschreiben        
19
  
20
ADC_MESSUNG_TEMP1_TEMP2_w2:
21
  ; warten bis ADIF-FLAG gesetzt  
22
  LDS temp,ADCSRA    ; auslesen  
23
  sbrs temp, ADIF    ; skip if...
24
  rjmp ADC_MESSUNG_TEMP1_TEMP2_w2
25
26
  ; ERGEBNIS auslesen        
27
  LDS temp1,ADCL    ; zuerst das LOW-Byte  
28
  LDS temp2,ADCH    ; dann das HIGH BYTE  
29
30
ret
31
; ##############################################################################
32
; ##############################################################################
33
; ##############################################################################



Bernhard

von c-hater (Gast)


Lesenswert?

Bernhard S. schrieb:

> Mehrere ADC-Eingände sollen nacheinander gemessen werden.
>
> Nach der Kanal-Umschaltung ist vermutlich eine längere Pause (ca.1ms)
> nötig, bis sich die interne ADC-Umschaltung beruhigt hat.
>
> Ist das korrekt, muss das so sein?

Nein. Solange du die Referenz nicht ändern musst und das MUX-Register im 
korrekten Zeitfenster beschreibst, kannst du jeden ADC-Zyklus sinnvoll 
verwenden.

Die Beschreibung des Zeitfensters zum sinnvolen Setzen der neuen 
Einstellung für ADMUX steht (wer hätte es gedacht...) im Datenblatt.

Was die Einstellung der Referenz betrifft, kann es allerdings 
(mindestens beim M1284P) entgegen der DB-Angaben (die hier dasselbe 
versprechen wie bezüglich der Quellenumschaltung) zu Problemen an völlig 
unerwarteter Stelle kommen, nämlich beim BOD.

Das ist ein echter Hardware-Bug, der von mir bereits vor über zwei 
Jahren an den Atmel-Support gemeldet wurde, aber scheinbar haben die 
Inder den Kram einfach verschlampt. Ich hatte schon bei der 
Kommunikation das Gefühl, dass der Typ auf der anderen Seite einfach 
nicht verstanden hat, worum es eigentlich geht. Mein Englisch ist zwar 
zugegebenermaßen nicht so superprächtig (das typische DB-Englisch halt), 
aber andererseits nun auch wieder nicht so dermaßen Scheiße, dass ein 
wirklich interessierter Leser nicht hätte deuten können, was ich 
schrieb. Also wollte der wohl einfach nicht verstehen, warum auch immer. 
Vermutlich hätte er dadurch eine unbezahlte Mehrarbeit zu leisten 
gehabt...

Der Kern der Sache ist jedenfalls, dass der BOD eine der eingebauten 
Referenzen als Bezugspotential benutzt. Beim Umschalten der 
Referenz-Quellen via ADMUX entstehen offensichtlich kurzzeitig 
"Querverbindungen" zur zuletzt benutzten Referenz, die diese interne 
Referenz dann kurzzeitig stören. Da der BOD bereits nach 1..2ns auslöst, 
führt das genau dann zu einem ungewollten Reset, wenn der Pegel der 
zuletzt genutzten Referenz deutlich über der vom BOD benutzten Referenz 
liegt und das Ziel der Umschaltung eben diese Referenz ist, denn dann 
"sieht" der BOD die Vorsorgungsspannung kurzzeitig (aber leider eben 
lange genug) als zu gering.

Workaround: Umschalten der Referenz auf die vom BOD benutzte immer in 
zwei Etappen, jedenfalls wenn die ursprüngliche Referenzspannung 
deutlich höher war.

Leider gibt es ohne Kenntnis der Beschaltung von AREF in der konkreten 
Applikation keine Möglichkeit, einen gleichzeitig optimalen und 
universellen Workaround für das Problem zu implementieren.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.