Problembeschreibung:
1. Die AD-Wandlung wird nur einmal durchgeführt (nach dem
Build-Vorgang).
Die LEDs Leuchten dann entsprechend der eingestellten Spannung am ADC
korrekt auf.
Ich bin davon ausgegangen, dass der ADC beim nächsten Schleifenumlauf
erneut startet und einen neuen Wert in ADCL und ADCH schreibt?!
2. Beim Drücken vom Taster an:
a) PD0 werden die Ausgänge (PORTB) auf hight gesetzt
(U_LED=0,0V -> LEDs gehen aus).
b) PD1 weden die Ausgägne (PORTB) auf low gesetzt
(U_LED=4,0V -> LEDs gehen aus).
Wenn keine taste gedrückt ist liegt über den LED konstnt eine Spannung
von 0,26V! Also die (richtigen) LEDs leuchten ganz schwach.
3. Ab einer Bestimmten Spannung (U_ADC=50mV) am ADC fängt an mein AVRISP
mkII die Orange LED an zu blinken.
Da dies etwas mit der RESET LINE zutun hat habe ich den Weg von
AVRISP
zum IC geprüft. Alles i.O. Verbindung besteht, Pull-Up liegt an hight
und der Pufferkondensator auf low (wie hier->
https://www.mikrocontroller.net/articles/AVR-Tutorial:_Equipment
beschrieben).
Ich bitte um Rat.
ps: Die Links zu den Tutorials kenn ich ;) . Bei Verweisen dahin bitte
ich um genauere Ausführungen. Danke.
Gratuliere. Du hast dir soeben die restliche Konfiguration in ADCSRA
zerstört.
Sagtest du nicht, du hättest dich an den Tutorial Routinen orientiert?
Warum hast du die denn nicht erst mal einfach 1:1 übernommen (mit
Ausnahme der Referenzspannungseinstellung). Nur so, um zu sehen ob auch
alles so funktioniert wie vorgesehen und ERST DANN eigene Funktionen
geschrieben?
Stefan Gl. schrieb:> Wenn keine taste gedrückt ist liegt über den LED konstnt eine Spannung> von 0,26V! Also die (richtigen) LEDs leuchten ganz schwach.
Wie sind deine Taster angeschlossen?
Es ist ungewöhnlich, dass man Taster so anschliest, dass sie eine 1
liefern, wenn der Taster gedrückt wird. Denn dann braucht man einen
externen Pulldown Widerstand.
Normal wird ein Taster so angeschlossen, dass er eine 0 liefert wenn er
gedrückt wird, denn dann kann man den internen Pullup Widerstand einfach
auf den Portpin zuschalten und hat damit immer einen gesicherten
Port-Pin Zustand.
Also: wie sind deine Taster angeschlossen und hast du externe
Pullup/Pulldown Widerstände verbaut?
Und nein, das ist nicht egal. Denn wenn da kein Pullup/Pulldown
Widerstand ist, der dem Pin bei nicht gedrücktem Taster einen Pegel
aufzwingt, dann ist es zufällig ob der Pin 0 oder 1 liefert. D.h. nicht
ganz zufällig, sondern der Pin fängt sich jedes dahergelaufene
elektromagnetische Feld ein, dass in der näheren Umgebung rumschwirrt.
Und davon haben wir jede Menge rund um uns. Der/die Taster liefern dann
unter Umständen in den Hauptschliefendurchgängen nicht einfach nur 0,
sondern ab und auch mal eine 1. Und die siehst du dann, weil dein Code
ja dann die Ausgänge 'einschaltet' nur um sie ein paar µs später wieder
abzuschalten. Dein Multimeter kann dir so schnelle Vorgänge aber nicht
zeigen, in zeitlichen Mittel ergibt sich aber auf die Art eine kleine
Spannung, nach dem Muster: ist der Pin bei 100 mal nachsehen 98 mal auf
0 (also 0V) und 2 mal auf 1 (also 5V), dann ist das im zeitlichen Mittel
auch eine Spannung von 0.1V
Karl Heinz schrieb:> Gratuliere. Du hast dir soeben die restliche Konfiguration in ADCSRA> zerstört.
Danke XD.
Oh, da fehlt ein | .
Das heißt, dass ich nicht bitweise oder-verknüpft habe. Was habe ich den
jetzt damit bewirkt?
Ist der Schaden irreperabel?
Karl Heinz schrieb:> Warum hast du die denn nicht erst mal einfach 1:1 übernommen (mit> Ausnahme der Referenzspannungseinstellung).
Weil bei 1:1 der Lerneffekt nicht so groß ist. Und wenn der IC futsch
ist, ist das Lehrgeld (1,51€) ;) .
Karl Heinz schrieb:> Es ist ungewöhnlich, dass man Taster so anschliest, dass sie eine 1> liefern, wenn der Taster gedrückt wird. Denn dann braucht man einen> externen Pulldown Widerstand.
Genau da liegt mein Problem nr.2 . Bei anderen Programmen (z.B.Licht n
leuchtet bei Tastendruck n) liefert der Ausgang mir eine 0 beim
Tastendruck.
Karl Heinz schrieb:> wie sind deine Taster angeschlossen und hast du externe> Pullup/Pulldown Widerstände verbaut?
Die Taster sind zwischen PIN und GND, die externen Pull-Ups zwischen PIN
und vcc (dieser ->
https://www.mikrocontroller.net/articles/AVR-Tutorial:_IO-Grundlagen
Quelle nachempfunden).
Karl Heinz schrieb:> Denn wenn da kein Pullup/Pulldown> Widerstand ist, der dem Pin bei nicht gedrücktem Taster einen Pegel> aufzwingt, dann ist es zufällig ob der Pin 0 oder 1 liefert.
...
Klingt nachvollziehbar und logisch. hab den ext. Pull-up geprüft: Er hat
kontakt zu den Pins.
Achso... und kann mir jemand erklären was
Stefan Gl. schrieb:> (void) ADCW;
<-diese Zeile macht?
Ich hätte erstmal auf einen Rückgabewert getippt. Das sieht jedoch meist
so aus: return (Wert);
Wenn ich das richtig verstanden habe ist void ein Platzhalter für den
Fall, dass nichts zurückgegeben werden soll!?
Nach der Korrektur des Codes "ADCSRA |= (1<<ADEN);" ist Problem nr.1
(nur eine Messung pro Build) gelöst. Karl Heinz, danke dafür :).
Den Controller habe ich mit einem einfachen Programm gefüttert:
#include <avr/io.h>
int main (void) {
DDRB = 0xFF;
PORTB = 0xFF;
DDRD = 0x00;
int n;
while(1)
{
for (n=0;n<=3;n++)
{
if (PIND&(1<<n))
PORTB |= (1<<n);
else PORTB &= ~(1<<n);
}
}
return 0;
}
Also der Controller reagiert noch.
Ob ADCSRA unwiederruflich defekt ist kann ich nicht beurteilen.
Ich habe das Programm auch noch mit einem zweiten amega8a getestet
(nachdem ich den Code korregiert habe). Die gleichen Symptome.
Die LEDs glimmen weiter vor sich hin. Mit PD1 Schalte ich alles ein, mit
PD0 aus (sollte ja eigendlich anders herum sein). Und auch der AVRISP
blinkt weiterhin ab 50mV.
Sind denn die Ausgabebefehle korrekt?
Die Spannung am PC0 Messe ich gegen Masse gemessen (da ich gelesen habe,
dass die Spannung am ADC GRND<U_ADC<U_ref sein soll). Sie liegt zwischen
0V<U<4,8V.
Problemlösung:
Karl Heinz schrieb:> Es ist ungewöhnlich, dass man Taster so anschliest, dass sie eine 1> liefern, wenn der Taster gedrückt wird.
Oder anders gesagt: Normaler Weise (kein Pull-down) liefert ein
gedrückter Taster eine 0.
Bei der Taster-Abfrage habe ich jedoch eine 1 abgefragt:
Stefan Gl. schrieb:> if (PIND&(1<<PIND0)) //wenn Taster an PD0=1,> { //> PORTB &= ~low; //PORTB und inv. "low"> } //->LEDs leuchten>>>> if (PIND&(1<<PIND1)) //> { //wenn Taste an PD1=1,> PORTB = 0xFF; //Alle LEDs aus> } //
Dies hat zur Folge, dass sowohl der einschalt Prozess (über PD0) als
auch der ausschalt Prozess (über PD1) dauerhaft durchlaufen.
Wenn ich nun den Taster an PD0 betätige ziehe ich ihn auf 0 und die
erste if Schleife wird ausgeklammert (LEDs werden nur noch
ausgeschaltet). Analog gilt das gleiche für die zweite if Schleife
(PD1).
Das glimmen der LEDs bei ungedrückter Taste lässt sich wie folgt
erklären:
Der ADC unterscheidet nicht mit 100%tiger Genauigkeit darüber ob eine
bestimmte Spannung Bit n oder Bit n+1 ist. Es gibt Übergänge.
Da der Controller mehrmals pro Sek. misst und ein Ergebnis ausgibt
(welches halt nicht genaue grenzen zu dem nächst höheren Wert hat) wird
der ausgang sehr schnell zwischen ein und aus hin und her geschaltet.
Ähnlich wie bei dem Eingang ohne Pull-up/Pull-down oben von Karl Heinz
beschrieben:
Karl Heinz schrieb:> Der/die Taster liefern dann> unter Umständen in den Hauptschliefendurchgängen nicht einfach nur 0,> sondern ab und auch mal eine 1. Und die siehst du dann, weil dein Code> ja dann die Ausgänge 'einschaltet' nur um sie ein paar µs später wieder> abzuschalten. Dein Multimeter kann dir so schnelle Vorgänge aber nicht> zeigen, in zeitlichen Mittel ergibt sich aber auf die Art eine kleine> Spannung, nach dem Muster: ist der Pin bei 100 mal nachsehen 98 mal auf> 0 (also 0V) und 2 mal auf 1 (also 5V), dann ist das im zeitlichen Mittel> auch eine Spannung von 0.1V
Auch hier nochmal vielen Dank. Der oben beschriebene Tipp hat mich auf
die Lösung gebracht!
So muss die Ausgabe aussehen:
if (!(PIND&(1<<PIND0))) //Wenn PD0=0 (Taste gedrückt)
{
PORTB = 0xFF; //Setz alle Ausgangsbits auf 1 (LEDs aus)
PORTB &= ~low; //und dann alle Bits vom ADC in PORTB auf0(LEDs an)
}