Forum: Mikrocontroller und Digitale Elektronik Mega644P ADC Ref Change Absturz


von Mr. AVR (Gast)


Lesenswert?

Hallo,

ich habe ein Problem mit dem ADC vom Mega644P. Ich betreibe den Chip bei 
20 Mhz 5V, ADC = 200 kHz (alle Prescalerbits aktiv).

Jetzt ist es so: Wenn ich die Referenzspannung ändere, stürzt der 
Controller ab. Warum? Also das passiert im laufenden Betrieb 
Free-Running. ADC wird vorher angehalten (ADEN Bit gelöscht), dann 
Änderungen an MUX und REFS, dann ADEN wieder anschalten.

Wenn ich REFS nicht ändere, läuft es normal durch. Was mache ich falsch?

von J Zimmermann (Gast)


Lesenswert?

Mr.AVR:
> stürzt der Controller ab
Was verstehst Du unter "stürzt ab" bei einem µC?
Kannst Du mal die source posten?
Vermute, dass beim Reaktivieren des ADC ein Int-Request ausgelöst wird, 
ohne dass die entsprechende ISR vorhanden ist, dann steht in der 
Int-Vektor-Tab der Reset-Vektor.
mfg

von Stefan F. (Gast)


Lesenswert?

> Was mache ich falsch?

Wie soll man das beantworten, wir wissen nicht, was du gemacht hast. 
Dein Text ist schön, enthält aber keinerlei Hinweis auf einen Fehler.

Quelltext Lesen wäre hier angebracht.

von Mr. AVR (Gast)


Lesenswert?

Ich nutze den ADC ohne Interrupt.

von Stefan F. (Gast)


Lesenswert?

Magst du deinen Quelltext wirklich nicht zeigen?

von Mr. AVR (Gast)


Lesenswert?

Doch:
1
inline void get_engine_amp_emf(void)
2
{
3
  if (!decoder.timer.timer_univ[adc_mux_timer])
4
  {
5
    decoder.engine.status.bits.ADC_MODE += 1;
6
7
    if (decoder.engine.status.bits.ADC_MODE == 3)  decoder.engine.status.bits.ADC_MODE = 0;
8
9
    decoder.dcc_round_cnter = NULL;
10
    decoder.dcc_current_times = NULL;
11
    decoder.engine.status.bits.ADC_REINIT = TRUE;
12
    decoder.timer.timer_univ[adc_mux_timer] = (uint16_t)(TI_10ms * 50);
13
  }
14
15
16
  //PA1 (ADC1) = Current, PA0 (ADC0) = gegen EMK, PA5 (ADC5) = Volume
17
  if (decoder.engine.status.bits.ADC_MODE == 0)
18
  {
19
    if (decoder.engine.status.bits.ADC_REINIT)
20
    {
21
      //ADC (PC2) @ 128 prescaler ~ 200khz, @5V  (FCPU/200k == 100); PA1 (ADC1) = CURRENT, PA0 (ADC0) = GEMK
22
      ADCSRA &= ~(1<<ADEN);
23
      ADMUX = (1<<REFS0);  //EMK
24
      ADCSRA |= (1<<ADEN)|(1<<ADSC);
25
26
      decoder.engine.status.bits.ADC_REINIT = FALSE;
27
    }
28
    else
29
    {
30
      //0-5V (vcc as reference), 5V = stop, else prop. voltage drop
31
      if (ADCW > 500)    decoder.dcc_current_times += (1023 - ADCW);
32
      else        decoder.dcc_current_times = NULL;
33
34
      if (++decoder.dcc_round_cnter >= decoder.system.extended.cv119_ADC_TURNS)
35
      {
36
        decoder.dcc_gegenEmk = (uint16_t)(decoder.dcc_current_times / decoder.dcc_round_cnter);
37
        decoder.dcc_round_cnter = NULL;
38
        decoder.dcc_current_times = NULL;
39
      }
40
    }
41
  }
42
  else if (decoder.engine.status.bits.ADC_MODE == 1)
43
  {
44
    if (decoder.engine.status.bits.ADC_REINIT)
45
    {
46
      //ADC (PC2) @ 128 prescaler ~ 200khz, @1V1 int  (FCPU/200k == 100); PA1 (ADC1) = CURRENT, PA0 (ADC0) = GEMK
47
      ADCSRA &= ~(1<<ADEN);
48
      ADMUX = (1<<REFS0)|(1<<MUX0);
49
      ADCSRA |= (1<<ADEN)|(1<<ADSC);
50
51
      decoder.engine.status.bits.ADC_REINIT = FALSE;
52
    }
53
    else
54
    {
55
      //0,03R @ 1V1 internal    (2,5A*0,03R)/(1,1V/1024)  -> ADCW*110/256
56
      //0,03R @ 5V external VCC  (2,5A*0,03R)/(5V/1024)    -> ADCW*350/256
57
      decoder.dcc_current_times += (uint16_t)((ADCW * 350) / 256);
58
59
      if (++decoder.dcc_round_cnter >= decoder.system.extended.cv119_ADC_TURNS)
60
      {
61
        decoder.dcc_current = (uint16_t)(decoder.dcc_current_times / decoder.dcc_round_cnter);
62
        decoder.dcc_round_cnter = NULL;
63
        decoder.dcc_current_times = NULL;
64
      }
65
    }
66
  }
67
  else if (decoder.engine.status.bits.ADC_MODE == 2)
68
  {
69
    if (decoder.engine.status.bits.ADC_REINIT)
70
    {
71
      //ADC (PC2) @ 128 prescaler ~ 200khz, @1V1 int  (FCPU/200k == 100); PA1 (ADC1) = CURRENT, PA0 (ADC0) = GEMK
72
      ADCSRA &= ~(1<<ADEN);
73
      ADMUX = (1<<REFS0)|(1<<MUX0)|(1<<MUX2);  //VOLUME
74
      ADCSRA |= (1<<ADEN)|(1<<ADSC);
75
76
      decoder.engine.status.bits.ADC_REINIT = FALSE;
77
    }
78
    else
79
    {
80
      decoder.dcc_current_times += (ADCW / 4);
81
      
82
      if (++decoder.dcc_round_cnter >= decoder.system.extended.cv119_ADC_TURNS)
83
      {
84
        decoder.dcc_volume = (uint16_t)(decoder.dcc_current_times / decoder.dcc_round_cnter);
85
        decoder.dcc_round_cnter = NULL;
86
        decoder.dcc_current_times = NULL;
87
      }
88
    }
89
  }
90
}

Das ist die Funktion in der Main die das Wechseln der ADC-Kanäle 
übernimmt.


1
DDRA = 0b00001100;
2
  PORTA = (1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4);
3
4
  DDRB = 0xFF;
5
  PORTB = 0;
6
7
  DDRC = 0b01111111;
8
  PORTC = (1<<PC7);
9
10
  DDRD = 0xFF;
11
  PORTD = 0;
12
13
   ADCSRB = NULL;
14
   ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0) | (1<<ADATE);  //ADATE is free running mode, if ADCSRB Bit 0-2 = 000

Das ist die init.

von Mr. AVR (Gast)


Lesenswert?

So wie der Quelltext oben ist funktioniert es. Mache ich bei 
decoder.engine.status.bits.ADC_MODE == 1 aus dem REFS0 ein REFS1 stürzt 
er ab, sobald er das umschalten will.

von Karl M. (Gast)


Lesenswert?

Hallo,

zeigst Du auch einen Schaltplan und den realen Aufbau?

Fehlen 100nF Kondensatoren an den µC Versorgungsspannungen?
Wie sind Aref und AVcc, AGnd beschaltet ?

von Stefan F. (Gast)


Lesenswert?

> stürzt er ab, sobald er das umschalten will.

Ist das sicher, dass er genau an dieser Stelle abstürzt?

Ich fürchte eher, dass der Fehler ganz woanders ist. Womöglich führt das 
Umschalten der Referenz zu anderen ADC Werten, die falsch verarbeitet 
werden und eventuell in einer Endlosschleife oder einem Pufferüberlauf 
oder falscher Pointer-Berechnung führen.

von Mr. AVR (Gast)


Lesenswert?

Schaltplan wir schwierig.

Ich habe Schaltregler (MCP16301H) für 5V Versorgung aus 24V
Vor dem MCP sitzt ein 10n, 100n und als Ausgangscap 22uF.


Beim Controller:
100nF, 22uF.

Am AREF habe ich 22uF
AVCC = VCC = 5V.
AGND = GND

von Karl M. (Gast)


Lesenswert?

Hallo,

warum ? 22uF an ARef, die müssen auch umgeladen werden!
beim umschalten der Referenzspannung.

Was sagt hier eine ADC Application Note dazu?

von Mr. AVR (Gast)


Lesenswert?

Karl M. schrieb:
> Hallo,
>
> warum ? 22uF an ARef, die müssen auch umgeladen werden!
> beim umschalten der Referenzspannung.
>
> Was sagt hier eine ADC Application Note dazu?

Habe ich ehrlich gesagt nichts zu gefunden oder übersehen.
Was ist denn dort ein üblicher Wert?

von Karl M. (Gast)


Lesenswert?

Hallo,

warum wird, wenn eine Zahl =0 erwartet wird, ein NULL == ((void*)0) 
zugewiesen?

von Karl M. (Gast)


Lesenswert?

Mr. AVR schrieb im Beitrag #5423384:
> 20 Mhz 5V, ADC = 200 kHz (alle Prescalerbits aktiv)

Wie dass 200kHz?

Der ADC Takt ergibt sich laut Datenblatt Table 25-5. Input Channel 
Selection zu:
20MHz/128 = 156,25kHz
ist doch klar oder?

von Mr. AVR (Gast)


Lesenswert?

Karl M. schrieb:
> Hallo,
>
> warum wird, wenn eine Zahl =0 erwartet wird, ein NULL == ((void*)0)
> zugewiesen?

Mhm das NULL = 0 das habe ich redefined. Ich lese das besser als eine 0.

von Mr. AVR (Gast)


Lesenswert?

Karl M. schrieb:
> Mr. AVR schrieb im Beitrag #5423384:
>> 20 Mhz 5V, ADC = 200 kHz (alle Prescalerbits aktiv)
>
> Wie dass 200kHz?
>
> Der ADC Takt ergibt sich laut Datenblatt Table 25-5. Input Channel
> Selection zu:
> 20MHz/128 = 156,25kHz
> ist doch klar oder?

Jap ist korrekt. Ist ja fast 200 khz :)

von Mr. AVR (Gast)


Lesenswert?

Ich habe jetzt mal Testweise einen 100 nF für AREF CAP genommen - es 
geht. Tatsächlich lag es an dem großen Kondensator.

Ich habe bis jetzt immer den großen genutzt, hat mir immer sehr gute 
Ergebnisse geliefert, allerdings habe ich auch niemals mehr die REF Bits 
verändert, höchstens mal den MUX.


Allerdings habe ich jetzt ein nächstes Problem:

Ich nutze ja 3 ADC-Kanäle.

1. Strom
2. EMK
3. Poti

Strom geht jetzt, da wo das Poti dran ist (was vorher ging) geht jetzt 
nicht mehr. Sobald ich am Poti drehe, stürzt der Controller wieder ab.

Es ist verflucht.... Woran liegt der Quatsch bitte??
Ist der immer noch zu groß oder gar zu klein jetzt? Mit den 22uF ging es 
dort.

von Karl M. (Gast)


Lesenswert?

Ok noch etwas ungewöhnliches,

warum wird der ADC aus und wieder eingeschaltete und da zwischen der ADC 
Kanal gesetzt?

Das macht man so nicht!
Tipp:
Im Datenblatt Table 25-1. ADC Conversion Time steht dazu auch etwas zum 
ersten Wandelergebnis 25 ADC-Takte zu 13,5 ADC-Takte...

Zur AVcc Beschaltung findet man hier etwas DB Figure 25-9. ADC Power 
Connections.

Zu ARef Beschaltung, siehe DB 25.5.2. ADC Voltage Reference
The reference voltage for the
Bitte komplett lesen.

I.A. Caref = 100nF

von Stefan F. (Gast)


Lesenswert?

> Ich habe jetzt mal Testweise einen 100 nF für AREF CAP genommen -
> es geht. Tatsächlich lag es an dem großen Kondensator.

Wow! Das überrascht mich sehr.

> Sobald ich am Poti drehe, stürzt der Controller wieder ab.

Kann es sein, dass ein (A)VCC Pin nicht wirklich an der Versorgung 
hängt?

von Karl M. (Gast)


Lesenswert?

Die ADC-Eingänge sollen niederohmig sein.

Das kann eine Rin >= 10kOhm || 10nF (Gnd) sein, oder eine zusätzlicher 
OP Amp, der die Quelle von der Last trennt.

Die Auslegung hängt dann wirklich vom realen Aufbau usw. ab.

Bitte sehr gute Bilder anhängen, wenn jetzt ein Steckbrett zu sehen ist, 
dann sein bewusst, dass nicht immer alle Verbindungen Kontakt haben 
mussen!

von Karl M. (Gast)


Lesenswert?

Karl M. schrieb:
> Das kann eine Rin >= 10kOhm || 10nF (Gnd) sein, oder eine zusätzlicher
> OP Amp, der die Quelle von der Last trennt.

Sorry, Fehler.
Korrekt:
Das kann eine Rin <= 10kOhm || 10nF (Quelle-Gnd) sein, oder eine 
zusätzlicher OP Amp, der die Quelle von der Last trennt.

von S. Landolt (Gast)


Lesenswert?

Stefan F. schrieb:

>> Tatsächlich lag es an dem großen Kondensator.
> Wow! Das überrascht mich sehr.

> Ich fürchte eher, dass der Fehler ganz woanders ist.
> Womöglich führt das Umschalten der Referenz zu anderen ADC Werten ...

Die 22 uF werden nur sehr langsam umgeladen und somit werden die 
'gemessenen' Werte stark verfälscht - also ich schließe mich der 
letztgenannten Vermutung an.

von Mr. AVR (Gast)


Lesenswert?

Danke erstmal für die ganzen Bemühungen an euch!!


Mein Verständnis öffnet sich so langsam:


Folgende Ergebnisse:

Vorher, also mit dem 22uF hatte ich das auf 12ms stehen, sodass alle 
12ms die Kanäle umgeschaltet werden (bei 3 genutzten Kanälen war das 
dann 36ms Verzögerung zwischen den Werten). Gerade das Poti ist 
kritisch, da dort Lautstärke drüber geregelt werden soll.

Da 2 Kanäle die 5V Ref nutzen, und nur 1 die 1V1, war das zu schnell, 
sodass es funktioniert hat, jedoch wurde mir immer ein falscher Wert vom 
Strom ermittelt (nämlich der, als wenn ich beim Strom 5V ref nutze). Er 
hat es nicht geschaft das umzuladen.



Dann bin ich hoch auf 500 ms, da ich dachte, ich bin zu schnell. Bei 500 
ms ist er dann immer abgestürzt, weil das umladen dann schaffbar war 
vll. aber zu viel für ihn (kurzschluss effekt denke ich).




Nach euren Ideen habe ich die 100nF genommen. Ging so halb. Problem an 
der Sache, oben im Text stehen auch noch 500 ms, das dürfen max. 12 
sein!! Damit geht das dann gar nicht mehr.

Jetzt habe ich den Kondensator weggemacht (komplett offen). Jetzt geht 
es mit 10 ms problemlos auf den Kanälen, abgesehen von EMK der liefert 
mir immer 1023.



Ich denke mal, ich schalte das zu schnell um. Der Kap an AREF dient doch 
nur zur Glättung oder wofür ist der genau? Oder wir da die Ref Spannung 
gespeichert zum Samplen?



AVCC hängt wirklich an VCC, habe es gerade nochmal durchgemessen und 
nachgelötet.

von Mr. AVR (Gast)


Lesenswert?

Karl M. schrieb:
> Die ADC-Eingänge sollen niederohmig sein.
>
> Das kann eine Rin >= 10kOhm || 10nF (Gnd) sein, oder eine zusätzlicher
> OP Amp, der die Quelle von der Last trennt.
>
> Die Auslegung hängt dann wirklich vom realen Aufbau usw. ab.
>
> Bitte sehr gute Bilder anhängen, wenn jetzt ein Steckbrett zu sehen ist,
> dann sein bewusst, dass nicht immer alle Verbindungen Kontakt haben
> mussen!

Ist eine gefertigte Platine.

An den ADCs hängt:

1. Poti 5K
2. Shunt 0,03R (ich habe noch eine Z Diode parallel zum Schunt als 5V 
Begrenzung sicher ist sicher) als auch ein 100nF da dort eine PWM drauf 
liegt (DC-Motorsteuerung).
3. Gegen EMK vom Motor, Spannungsteiler aus 2x 10K über Z Diode geführt, 
parallel zur Z Diode 100n und 3k3 als Filter.

von Mr. AVR (Gast)


Lesenswert?

Karl M. schrieb:
> Ok noch etwas ungewöhnliches,
> Das macht man so nicht!
> Tipp:
> Im Datenblatt Table 25-1. ADC Conversion Time steht dazu auch etwas zum
> ersten Wandelergebnis 25 ADC-Takte zu 13,5 ADC-Takte...
>
> Zur AVcc Beschaltung findet man hier etwas DB Figure 25-9. ADC Power
> Connections.
>
> Zu ARef Beschaltung, siehe DB 25.5.2. ADC Voltage Reference
> The reference voltage for the
> Bitte komplett lesen.
>
> I.A. Caref = 100nF

Das mit dem Aus und Einschalten habe ich gemacht, da dann die Wandlung 
beendet wird, sodass ich sicher bin, dass die nächste Wandlung schon die 
umgeschalteten Pinne nutzt (auch wenn diese dann Falsch ist). Ansonsten 
kann es sein, dass noch die alte Konfig genutzt wird.

von Karl M. (Gast)


Lesenswert?

Hallo Mr. AVR schrieb im Beitrag #5423491:
> 1. Poti 5K
> 2. Shunt 0,03R (ich habe noch eine Z Diode parallel zum Schunt als 5V
> Begrenzung sicher ist sicher) als auch ein 100nF da dort eine PWM drauf
> liegt (DC-Motorsteuerung).
> 3. Gegen EMK vom Motor, Spannungsteiler aus 2x 10K über Z Diode geführt,
> parallel zur Z Diode 100n und 3k3 als Filter.

gehe bitte alle meine Beiträge ganz genau durch, speziell die Hinweise 
aus dem Datenblatt und der AVcc Beschaltung.
Die ist dort auch abgebildet.

Was das Programm angeht, hatte ich schon geschrieben, Aus und 
Einschalten des ADC zum Wechsel der Kanäle - ohne Dummy Read des ADC - 
ist fahrlässig.
Selbst im Datenblatt steht etwas zum Quellimpedanz (<=10kOhm) der ADC 
Messstellen. Das muss man beachten!

von Karl M. (Gast)


Lesenswert?

Hallo Mr. AVR ,

deshalb liest man auch immer wieder RTFM Atmega644p.

Dieses habe ich verwendet:
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42744-ATmega644P_Datasheet.pdf

von Mr. AVR (Gast)


Lesenswert?

Karl M. schrieb:
> Hallo Mr. AVR ,
>
> deshalb liest man auch immer wieder RTFM Atmega644p.
>
> Dieses habe ich verwendet:
> http://ww1.microchip.com/downloads/en/DeviceDoc/At...

Ja das habe ich schon gelesen, trzd. überliest man (ich) auch mal was. 
Das mit dem großen Kap ist auch so eine Sache die immer gut funktioniert 
hat (jedoch wurde die RefSpannung auch nie geändert)...

von Karl M. (Gast)


Lesenswert?

Hallo Mr. AVR schrieb im Beitrag #5423505:
> (jedoch wurde die RefSpannung auch nie geändert)

Das passiert im obigen Quelltest auch nicht!
Also RTFM.

Aber das Aus- und Einschalten des ADC ist nicht gewünscht und so kommt 
es zu Problemen.

von Stefan F. (Gast)


Lesenswert?

> Shunt 0,03R (ich habe noch eine Z Diode parallel zum Schunt als 5V
> Begrenzung sicher ist sicher)


Moment mal. 5V / 0,03Ω = 167A

167A * 5V = 835 Watt Verlustleistung. Das klingt phantastisch!

Ich würde diesen Aufbau wirklich mal gerne sehen.

von c-hater (Gast)


Lesenswert?

Mr. AVR schrieb im Beitrag #5423384:

> ich habe ein Problem mit dem ADC vom Mega644P. Ich betreibe den Chip bei
> 20 Mhz 5V, ADC = 200 kHz (alle Prescalerbits aktiv).
>
> Jetzt ist es so: Wenn ich die Referenzspannung ändere, stürzt der
> Controller ab. Warum?

Warum fragst du uns das? Frag' das besser den Controller. Der besitzt 
nämlich ein Register, welches Auskunft über die Ursache eines Resets 
gibt...

Educated guess: Das Register wird anzeigen, dass der BOD den 
unerwarteten Reset ausgelöst hat...

von Stefan F. (Gast)


Lesenswert?

Noch wissen wir gar nicht, ob er überhaupt einen Reset mach oder wo er 
hängen bleibt. Das gilt es, heraus zu finden.

von Oliver S. (oliverso)


Lesenswert?

Karl M. schrieb:
> Was das Programm angeht, hatte ich schon geschrieben, Aus und
> Einschalten des ADC zum Wechsel der Kanäle - ohne Dummy Read des ADC -
> ist fahrlässig.

Man kann den ADC jederzeit aus- und einschalten. Man kann auch nach 
jeder Wandlung den ADC-Wert auslesen, auch den ersten. Davon stürzt 
weder der AVR ab, noch passiert sonst irgend etwas. Fahrlässig ist daran 
überhaupt nichts.

Das einzige, was passieren kann, ist, daß der erste gelesene ADC-Wert 
ungenau ist. Wann das der Fall ist, steht im Datenblatt.

Oliver

von Pandur S. (jetztnicht)


Lesenswert?

Nebenbei. Die Referenz zu verkleinern bringt nicht mehr Genauigkeit fuer 
den Shunt. Dazu solltest du einen Verstaerker verwenden. Ich verwend da 
zB den MCP616 mit einer Verstaerkung von vielleicht 30-50. Und dann 
musst du die Referenz auch nicht umschalten.

von Karl M. (Gast)


Lesenswert?

Hallo Zitronen F. schrieb:
> Nebenbei. Die Referenz zu verkleinern bringt nicht mehr
> Genauigkeit fuer
> den Shunt. Dazu solltest du einen Verstaerker verwenden. Ich verwend da
> zB den MCP616 mit einer Verstaerkung von vielleicht 30-50. Und dann
> musst du die Referenz auch nicht umschalten.

Es wird die Referenz doch gar nicht umgeschaltet.
Aber richtig ist, die Quellimpendanz und evtl. den Messbereich voll 
auszuschöpfen.

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.