habe einen ATmega16 und würde gerne 4 Spannungen miteinander
vergleichen.und aus die vier spannungen die maximale spannung ermitteln
und damit Led ansteuern.
das problem :microcontroller speichert die maximal wert.und berechnet
nicht neu die maximal wert aus die vier spannungen,sonst bleibt die
maximal spannung gespeichert bis eine spannung höher als die
gespeicherte spanung.
Aus Deinem konfusen Satzbau rate ich, Du möchtest den Max-Wert bei jedem
Durchlauf neu berechnen? Dann setze ein
max = 0;
hinter den Funktionsaufruf in der main().
formatier erst mal deinen Code vernünftig.
Einrückungen konsistent machen!
Ansonsten suchen wir hier Fehler, die in deinem Code überhaupt nicht
existieren.
Oder ist das Absicht, dass deine Hauptschleife leer ist? Da wundert es
mich nicht, dass dein Programm keine Arbeit mehr verrichtet.
1
while(1){// Endlosschleife zur kontinuierlichen
2
//Auswertung der Eingangsspannung (am ADC)
3
4
5
6
}
PS: Das ist mit Abstand die scheuslichste und unübersichtlichste
Code-Formatierung die ich je gesehen habe. Und ich habe schon viel
gesehen. Das du keine Fehler findest wundert mich nicht.
Ist jetzt zwar nicht dein Problem.
Aber: Das geht so nicht
1
unsignedshortmaximum(void)
2
{
3
unsignedchari;
4
unsignedshortmax=adc(0);
5
6
for(i=1;i<4;i++)
7
{
8
if(adc(i)>max)
9
max=adc(i);
10
}
11
12
returnmax;
13
}
Du kannst nicht adc(i) mit max vergleichen und dann zur Zuweisung an max
erneut adc aufrufen. Der zweite Aufruf könnte ein ganz anderes Ergebnis
bringen als der erste!
Danke Karl heinz.jetzt ermittlet die maximal spannung daraus.nun hab
noch ein problem dass LED an den PORTD 0x04 immer an auch wenn ich keine
spannung anlege
smith schrieb:> Danke Karl heinz.jetzt ermittlet die maximal spannung daraus.nun hab> noch ein problem dass LED an den PORTD 0x04 immer an auch wenn ich keine> spannung anlege
Hast du dein Programm bereinigt?
Zeig noch mal den bereinigten Code.
Wie gesagt: Dein ursprünglich geposteter Code konnte nicht
funktionieren, weil sich innerhalb der Arbeitsschleife keine Anweisungen
befinden.
Das kann jetzt natürlich ein Postingfehler sein. Nur das kann ich nicht
raten, das will ich sehen.
PS:
Hat es eigentlich einen speziellen Grund, warum du bei den Vergleichen
Hexadezimalzahlen benutzt?
smith schrieb:> nun hab> noch ein problem dass LED an den PORTD 0x04 immer an auch wenn ich keine> spannung anlege
Dein Problem ist, dass niemand dein konfusen Sätze versteht. Gib dir
wenigstens ein bisschen Mühe beim Formulieren und benutze die
Schift-Tase wo es nötig ist!
So sollte dein Code aussehen!
Eine halbwegs schöne und ansprechende und vor allen Dingen konsistente
Formatierung ist ein Instrument mit dem man Fehler sehen kann!
1
#define LED1 PD0
2
#define LED2 PD1
3
#define LED3 PD2
4
5
6
intmain()
7
{
8
...
9
10
11
while(1)// Endlosschleife zur kontinuierlichen
12
//Auswertung der Eingangsspannung (am ADC)
13
14
{
15
c=maximum();
16
17
if(c<=158)
18
PORTD=(1<<LED1);
19
20
elseif(c<=374)
21
PORTD=(1<<LED2);
22
23
else
24
PORTD=(1<<LED3);
25
}
26
}
Lektionen:
* Achte darauf, dass die schliessende } immer in derselben Spalte steht,
wie die öffnende {
* Mach Leerzeichen rein!
Wenn du Text liest, bist du daran gewöhnt, dass zwischen den Wörtern
ein Leerraum ist. Der Leerraum hilft dir beim Lesen! Nur weil C
grundsätzlich erlaubt, alles in einer Wurst zu schreiben, muss man das
nicht tun!
* In deiner Prüfkette: Prüfe nicht Dinge, die sowieso nicht sein können.
Ein unsigned short Datentyp ist immer größer als 0. Das muss man nicht
prüfen. Wenn ein Wert schon kleiner als 159 ist, dann kann er im
nächsten else if, welches geprüft wird nicht größer sein. Das muss man
daher auch nicht prüfen.
* Sieh zu, dass du auch mit Fehlern arbeiten kannst. Eine if - else if
Kette sollte immer ein abschliessendes else haben, in welchem 'alles
andere' sinnvoll behandlet wird. Genauso wie ein switch immer ein
default haben soll.
* verstecke die Hardwarebelegung der Pins nicht im Code! Benutze #define
um die Hardware im Code zu abstrahieren.
* Nimm das Zahlensystem, welches intuitiv zur Aufgabenstellung passt.
Wenn du konzeptionell mit Dezimalzahlen hantierst, dann benutze auch
Dezimalzahlen und verschleire Werte nicht hinter Hexadezimalzahlen wenn
es keinen Grund dafür gibt.
Ist es Absicht, dass die LEDs zwar an-, aber nirgendwo ausgeschaltet
werden? Könnte immerhin sein, da es eine Maximalwertanzeige ist, auch
wenn ich es nicht vermute.
Hc Zimmerer schrieb:> Ist es Absicht, dass die LEDs zwar an-, aber nirgendwo ausgeschaltet> werden? Könnte immerhin sein, da es eine Maximalwertanzeige ist, auch> wenn ich es nicht vermute.
es wird ja immer nur umgeschaltet...
Sind eigentlich die Editoren, die die Einrückungen selbst
vorschlagen/machen, völlig aus der Mode gekommen? Das ist auch schon
während des Schreibens eine gute Hilfe bei der Fehlererkennung.
Da lob' ich mir doch meinen guten alten Emacs.
Es ist auch immer eine gute Idee, sich auf nichts zu verlassen.
Ehe man da eine Auswertung macht, ist es meistens eine gute Idee, sich
die Messwerte direkt anzusehen.
Eventuell liegt ja auch ein Hardwareproblem vor und vom ADC kommt
tatsächlich ständig ein Messwert von 1024
smith schrieb:> Danke für die Lektionen.> also das hat sich nicht geändert LED3 ist immer an
Dann sieh dir erst mal an, was dein ADC tatsächlich für Werte von sich
gibt.
Nur 1 Kanal auswerten. Den Messwert durch 4 dividieren (damit er von
1024 nach 256 runter kommt) und direkt auf den Port ausgeben. Dann kann
man mal nachsehen, welcher Messwert gemessen wird und ob sich der
überhaupt ändert, wenn sich die zu messende Spannung ändert.
Dasselbe Spielchen dann mit den anderen Kanälen.
Das hier
ADMUX &= ~ (1<<REFS1) | (1<<REFS0);
macht mit einiger Sicherheit nicht das, was du erwartest, was immer das
auch sein mag.
Entweder du wolltest das hier:
ADMUX &= ~ ( (1<<REFS1) | (1<<REFS0) );
Das schaltet auf externe Referenzspannung.
Hast du überhaupt an AREF eine Referenzspannung angeschlossen?
Oder du wolltest das hier
ADMUX &= ~ (1<<REFS1);
ADMUX |= (1<<REFS0);
Das schaltet die Referenzspannung auf AVcc
Also: Welche der beiden Versionen soll es sein?
smith schrieb:> ich will halt interne Referenzspannung nutzen
Welche interne Referenzspannung?
Es gibt 2 davon
AVcc
eine generierte Referenzspannung von 2.56 Volt
> und die AREF und AVCC> sind beide angeschlossen
Wie?
Hör mal:
Du gibst dir keine Mühe beim Schreiben deiner Beiträge
Genauso hingeschludert sehen auch deine Programm aus
Man muss dir jede Kleinigkeit aus der Nase ziehen
Von alleine kommt von dir keine Info, von der du denken könntest
das man die als Helfer eventuell brauchen könnte
Entweder du stellst dein Verhalten um, oder ich bin ganz schnell aus dem
Thread raus.
smith schrieb:> bin verwirtt.hab AVCC und AREF an den externe 5v angeschlossen
Ganz schlecht.
An Avcc kann man per Software als Referenzspannung auswählen.
Von daher gibt es keinen Grund an AREF eine SPannung anzuschliessen.
An AREF gehört im Normalfall einfach nur ein 100nF Kondensator, der ARF
nach GND abblockt.
Steht aber alles auch im Tutorial.
bin halt Anfänger in diesem Bereich und bei jeder Frage muss ich
überlegen und ich bedanke mich für jede Antwort bei dir bzw bei alle
anderen.das hat nix mit Verhalten zu tun
ich hab Aref und AVcc mit 5V angeschlossen.
ich verstehe nicht wraum alles läuft ganz gut nur wenn ich die maximal
funktion benutze dann wird nur LED dauernd angeschaltet
// Den ADC initialisieren und einen sog. Dummyreadout machen
15
ADCSRA|=(1<<ADSC);
16
while(ADCSRA&(1<<ADSC))
17
;
18
19
for(i=0;i<NR_SAMPLES;i++)
20
{
21
ADCSRA|=(1<<ADSC);// eine ADC-Wandlung
22
while(ADCSRA&(1<<ADSC))
23
;// auf Abschluss der Konvertierung warten
24
val+=ADCW;
25
}
26
27
ADCSRA&=~(1<<ADEN);//// ADC wieder deaktivieren
28
29
val/=NR_SAMPLES;
30
returnval;// ADC auslesen und zurückgeben
31
}
Änderungen:
Referenzspannung mit Sicherheit auf AREF eingestellt
val mit 0 initialisiert. Du kannst nicht davon ausgehen, dass eine
lokale Variable irgendeinen vernünftigen Wert hat, wenn die Funktion
betreten wird.
Insbesondere der letzter Punkt könnte für dein Problem verantwortlich
sein.
->An AREF gehört im Normalfall einfach nur ein 100nF Kondensator, der
ARF
nach GND abblockt.
wenn ich das mache dann funktioniert nix mehr auch wenn ich direkt von
adc() lese.
sonst wenn ich das mache wie in Grundschaltung oben tritt wieder gleiche
Problem wenn ich maximum Funktion einsetze
smith schrieb:> sonst wenn ich das mache wie in Grundschaltung oben tritt wieder gleiche> Problem wenn ich maximum Funktion einsetze
AREF hast du jetzt wie bschaltet?
Wie sieht jetzt dein Programm aus?
smith schrieb:> LED3 ist immer an auch wenn ich die spannung ändere 0 bis 5V.
"die Spannung"?
Leider hast du nicht eingezeichnet, was eigentlich an den ADC Eingängen
hängt.
Überprüf mal die Einzelkanäle. Einer davon wird höchst wahrscheinlich
einen hohen Wert liefern.
1
unsignedshortmaximum(void)
2
{
3
unsignedchari;
4
unsignedshortadcValue;
5
unsignedshortmax=0;
6
7
for(i=0;i<4;i++)
8
{
9
adcValue=adc(i);
10
11
if(i==0)
12
{
13
if(adcValue>max)
14
max=adcValue;
15
}
16
}
17
18
returnmax;
19
}
Beim if tauscht du den Vergleich nacheinander gegen 0, 1, 2, 3 aus.
Dadurch kann dann immer nur 1 Kanal zum Maximum beitragen. Die ganze
restliche Programmlogik, inklusive ADC-Kanalwechsel, ändert sich aber
nicht. Und das ist wichtig! Zum Testen wollen wir alles andere möglichst
gleich lassen.
So kannst du jeden Kanal überprüfen, ob er der Übeltäter ist, dessen
Messwert alle anderen überstimmt.
ich Lege an die adc(0) eine spannung von 1v und an adc(1) 5 v
normalweise soll LED3 anleuchten das tut sie nicht sondern wird immer
LED2 an
an adc(2) und adc(3) lass ich halt 0v dran.
ich hab alle kanäle von adc0 bis adc3 überprüft durch änderung von i und
alle funktionieren ganz gut.