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?
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
> 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.
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.
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.
Hallo, zeigst Du auch einen Schaltplan und den realen Aufbau? Fehlen 100nF Kondensatoren an den µC Versorgungsspannungen? Wie sind Aref und AVcc, AGnd beschaltet ?
> 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.
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
Hallo, warum ? 22uF an ARef, die müssen auch umgeladen werden! beim umschalten der Referenzspannung. Was sagt hier eine ADC Application Note dazu?
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?
Hallo, warum wird, wenn eine Zahl =0 erwartet wird, ein NULL == ((void*)0) zugewiesen?
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?
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.
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 :)
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.
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
> 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?
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!
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.
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.
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.
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.
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.
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!
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
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)...
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.
> 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.
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...
Noch wissen wir gar nicht, ob er überhaupt einen Reset mach oder wo er hängen bleibt. Das gilt es, heraus zu finden.
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.