Mega644P ADC Ref Change Absturz

Gast #5423384
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?
Gast #5423398
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
Gast #5423407
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.
Gast #5423427
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.
Gast #5423442
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.
Gast #5423460
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?
Gast #5423464
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 :)
Gast #5423471
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.
Gast #5423475
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
Gast #5423476
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?
Gast #5423480
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!
Gast #5423481
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.
Gast #5423482
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.
Gast #5423485
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.
Gast #5423491
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.
Gast #5423494
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.
Gast #5423498
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!
Gast #5423505
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)...
Gast #5423510
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.
Gast #5423514
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.
Gast #5423819
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...
#5423888
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
Gast #5423901
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren