/* Eigentliche Messung - Mittelwert aus 'average' aufeinanderfolgenden Wandlungen */
44
result=0;
45
46
for(uint8_ti=average;i>0;i--){
47
ADCSRA|=(1<<ADSC);// eine Wandlung "single conversion"
48
while(1);// auf Abschluss der Konvertierung warten
49
result+=ADC;// Wandlungsergebnisse aufaddieren
50
}
51
52
result/=average;// arithmethischer Mittelwert
53
return(uint16_t)result;
54
}
55
56
57
58
/* Beispielaufrufe: */
59
60
61
62
voidmain(void)
63
{
64
65
66
DDRD=0xff;/* PortD als ausgang defnieren*/
67
68
uint16_tadcval;
69
ADC_Init();
70
adcval=ADC_Read_Avg(1,4);// Kanal 1, Mittelwert aus 4 Messungen
71
72
PORTD&=~(1<<PD0);/* PD0 auf 0 setzen */
73
PORTD&=~(1<<PD1);/* PD1 auf 0 setzen */
74
75
if(adcval<314)/* 314 entspricht 1.5V*/
76
77
{
78
PORTD|=(1<<PD1);/* PD1 high wenn adcval größer 314 rot */
79
}
80
81
82
if(adcval>314)
83
84
{
85
PORTD|=(1<<PD0);/* PD1 high wenn adcval kleiner 314 grün */
86
}
87
88
}
Hallo zusammen,
hat jemand ne idee warum mein adc immer nur 5V misst und nicht die
Spannung die über den Widerstand R5 abfällt?
Die Schaltung an sich soll so funktionieren dass die Rote Led leuchtet
wenn der ADC eine Spannung unter einem bestimmten Wert misst und Grün
wenn sie über einem bestimmten Spannung liegt Rot leuchtet. Für den
Anfang würd es mir aber mal reichen das der ADC überhaupt mal was misst
;).
ADCSRA|=(1<<ADSC);// eine Wandlung "single conversion"
3
while(1);// auf Abschluss der Konvertierung warten
4
result+=ADC;// Wandlungsergebnisse aufaddieren
5
}
was macht die Endlosschleife da drinnen?
Du hast eine ADC_Read Funktion. Warum benutzt du sie nicht um damit auch
die mittelnde Version aufzubauen, sondern programmierst dort wieder
alles aus? Klassisches Beispiel dafür, wie man es nicht macht.
ADCSRA|=(1<<ADSC);// eine Wandlung "single conversion"
3
while(ADCSRA&(1<<ADSC));// auf Abschluss der Konvertierung warten
4
result+=ADC;// Wandlungsergebnisse aufaddieren
5
}
Besser? Hab da was versucht und hab wohl vergessen das wieder zu ändern.
Mein Fehler misst aber immer noch 5 V.
Karl heinz Buchegger schrieb:> Du hast eine ADC_Read Funktion. Warum benutzt du sie nicht um damit auch> die mittelnde Version aufzubauen, sondern programmierst dort wieder> alles aus?
Weil es in meinem Beispielcode auch so gemacht wurde und ich nicht
soviel ändern wollte. Aber eigentlich müsste das doch kein Problem
sein?
Wie sieht deine Aussenbeschaltung aus?
Hast du am Optokoppler was angeschlossen?
Hast du mit einem Voltmeter kontrolliert, welche Spannung tatsächlich am
ADC Eingang anliegt?
Beim schnellen Drüberschauen über den Code hab ich so jetzt erst mal
nichts mehr gesehen. IMHO ist die Konfiguration des ADC vernünftig.
An ADC 1 liegen 1,5V sprich Opto ist beschalten der Transistor schaltet
es leuchtet.
hmm hab ich den Eingangskanal richtig eingestellt mir kommts sovor uC
ihrgendwas anderes misst.
Stimmt es das dass register beim Atmega 32 ADC heißt und nicht ADCW?
ADCSRA|=(1<<ADSC);// eine Wandlung "single conversion"
6
while(ADCSRA&(1<<ADSC));
7
// auf Abschluss der Konvertierung warten
8
returnADC;// ADC auslesen und zurückgeben
9
main=ADC;
10
}
change to
uint16_t ADC_Read(uint8_t channel)
{
// Kanal waehlen, ohne andere Bits zu beeinflußen
ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
while (ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung
warten
return ADC; // ADC auslesen und zurückgeben
}
Ich mess aber immer noch 5 V
>> Datenblatt Seite 214>> Hast du nicht 2,56V Intern als Referenz?>>
1
ADMUX=(1<<REFS0)|(1<<MUX1);// AVCC als Referenzspannung
2
>nutzen
3
>
>> so sollte das doch aussehen wenn ich mich nicht irre?!
Ist egal.
Kommt aufs selbe raus. 0<<REFS1 ist eine glatte 0 und stört somit
nicht weiter beim verodern der Einzelterme.
Man kanns raus nehmen oder man kanns drinnen lassen um zu dokumentieren,
dass man REFS1 absichtlich auf 0 haben will.
> Datenblatt Seite 214>> Hast du nicht 2,56V Intern als Referenz?
REFS1 REFS0 Voltage Reference Selection
0 0 AREF, Internal Vref turned off
0 1 AVCC with external capacitor at AREF pin
1 0 Reserved
1 1 Internal 2.56V Voltage Reference with external
capacitor at AREF pin
ADMUX = (0<<REFS1) | (1<<REFS0) | (1<<MUX1);
ähm Ich wäle doch AVCC aus. Das 0 REFS1 ist zur doku
Laut Datenblatt muss es ADC heißen ADCW taucht nicht einmal auf.
Hans Wurst schrieb:>> Datenblatt Seite 214>>>> Hast du nicht 2,56V Intern als Referenz?>>> REFS1 REFS0 Voltage Reference Selection> 0 0 AREF, Internal Vref turned off> 0 1 AVCC with external capacitor at AREF pin> 1 0 Reserved> 1 1 Internal 2.56V Voltage Reference with external> capacitor at AREF pin>> ADMUX = (0<<REFS1) | (1<<REFS0) | (1<<MUX1);> ähm Ich wäle doch AVCC aus. Das 0 REFS1 ist zur doku>>> Laut Datenblatt muss es ADC heißen ADCW taucht nicht einmal auf.
In dem Fall gilt ausnahmsweise nicht das Datenblatt, sondern die
Compilerdoku. Hauptsächlich deshalb, weil der gcc eine Erweiterung für
alle Pseudo-16 Bit Register enthält, auf die mit dem Registernamen in
einem Rutsch (anstelle von HighByte/LowByte) zugegriffen werden kann.
ADCW wurde gewählt, weil sonst Verwechslungsgefahr mit der
Assembler-Anweisung ADC (Add with Carry) besteht. Es ist aber beides
definiert: ADC und ADCW. Und beide bezeichnen im gcc auch dasselbe: das
Pseudo-16 Bit Register mit dem Ergebnis der Wandlung.
Wie ist der momentane Zustand
* GND durchverbunden
* neues Hauptprogramm
Karl heinz Buchegger schrieb:> Ich vermisse in deiner main() die obligatorische while(1) Hauptschleife.> Dein ADC misst einmal und das wars dann auch.
hmmm das stimmt aber wenn ich Schleife einfüge (der Vorschlag von dir)
leuchtet gar nix mehr. Sehr komisch
pschober schrieb:> Wenn die Schaltung so gebaut ist wie auf dem Schaltplan, kann das gar> nicht funktionieren.> Gnd (Pin31) hängt in der Luft
Ja die Masse hängt in der Luft das stimmt und ist beabsichtigt die
Schaltung wird mit 180V betrieben. Das geht nicht und anderst und
funktioniert, ich bekomm eine saubere 1.5 V Spannung. Sei auch mal dahin
gestellt es geht um den ADC
Ok das habe ich nicht gewusste danke für die Erklärung.
Aktueller Stand:
ADC in ADCW geändert
Hauptprogramm geändert.
An Pin 31 hab ich nichts geändert kann ich den einfach an GND des uC
anschließen?
Misst 5V
Da die beiden GND Anschlüsse Chipintern höchst wahrscheinlich irgendwo
zusammengeführt sind, wird sich die fehlende Verbindung erst mal nicht
grossartig auswirken. Nichtsdestotrotz muss sie gemacht werden.
Ich hatte in meinem Hauptprogramm weiter oben noch einen Fehler. Hast du
den gesehen (Ich hatte die ~ bei den Verundungen vergessen)?
Denn das hier:
> aber wenn ich Schleife einfüge (der Vorschlag von dir)> leuchtet gar nix mehr.
kann dann nur mehr sein, wenn der ADC von anfang an und ständig 317
liefert. Ich hab diese Möglichkeit nicht ausgebaut, weil ich dachte dass
eine kleine Hysterese nicht schaden kann. Aber seis drum
1
while(1){
2
adcval=ADC_Read_Avg(1,4);// Kanal 1, Mittelwert aus 4 Messungen
3
4
if(adcval<314){/* 314 entspricht 1.5V*/
5
PORTD&=~(1<<PD0);
6
PORTD|=(1<<PD1);/* PD1 high wenn adcval größer 314 rot */
7
}
8
9
else{
10
PORTD|=(1<<PD0);/* PD1 high wenn adcval kleiner 314 grün */
11
PORTD&=~(1<<PD1);
12
}
13
}
eine der beiden LEDMUSS leuchten!
Ich würde mir zum testen ehrlich gesagt auch die Auswerteschaltung
abklemmen und durch ein stink normales Poti als Spannungsteiler
ersetzen. Dann kann ich am Poti drehen und einfach sehen ob die
Umschaltung klappt. Ausserdem bin ich dann nicht darauf angewiesen, dass
diese Eingangsbeschaltung auch tatsächlich funktioniert.
hmm ich glaup ich hab die Ursache gefunden egal was ich anschließ es wir
mir aus 5 V hochgezoegn. Vorher hab ich das nicht gemessen weil der uC
aus war und die Maße nicht verbunden. wenn ich an den ADC1 und GND 1 V
anschließ zieht es die auf 5V hoch warum hab ich noch nicht gefunden.
Hmm ich hab die Schaltung jetzt über nen Spannungsteiler Widerstand+
Poti gemacht. Aber der ADC misst immer noch ihrgend nen mist. An PIn 1
liegt 1,5 V.
Au man . Jemand nen Vorschlag?
Irgendwelche Pullups etc. noch aktiviert auf dem Eingang? Eingang
explizit als Eingang Definieren und alles was interne Pullups/downs
betrifft nochmal festnageln.