Datum: 03.05.2008 22:28
Huhu, Habe an meinem AVR ein paar simple Taster angeschlossen, und zwar wie folgt: * an Port B4 (als Input) liegt ein Pull-down (!)-Widerstand * zwischen den Pins von Port C liegen die Taster über Dioden an B4. D.h., bei gedrücktem Taster kriegt Port B4 einen High-Pegel. Das mag zwar etwas ungewöhnlich anmuten, macht aber im Gesamtaufbau der Schaltung Sinn. Beim Abfragen tritt jedoch ein (für mich...) unerklärliches Phänomen auf. Folgender Code schaltet eine LED erwartungsgemäß immer dann ein, wenn der Taster an Port C0 gedrückt wird:
PORTC = _BV(0); if (PINB & _BV(PINB4)) { LED_AN; } /* buttons = 0; for (i = 0; i < 5; i++) { buttons <<= 1; if (PINB & _BV(PINB4)) { buttons |= _BV(0); } PORTC <<= 1; } */ |
Wenn ich den auskommentierten Block oben nun aber einbinde (Kommentarzeichen weglassen, logisch), dann leuchtet die LED immer dann, wenn der Taster an Port C1 (1!) gedrückt ist! Ich rätsel nun schon seit zwei Tagen rum und komm auf keinen grünen Zweig. Wodran hängt das nun? (Taktrate ist 4MHz, hab auch schon reichlich NOP eingebaut^^) Hoffentlich kann mir da jemand helfen -- vielen Dank schonmal! Viele Grüße, Sven
Datum: 03.05.2008 22:36
Mit dem bischen Code lässt sich nix anfangen. Es fehlt mindestens die Initialisierung der Ports und der Code für LED_AN und was sonst nocht alles passiert und vielleicht mitmischt (und von dem du 100% genau sicher garantiert weisst, dass es nichts damit zu tun hat ;-).
Datum: 03.05.2008 22:41
Ich schätze, es liegt an der Verzögerung der äußeren Beschaltung. Du mußt Deiner Schaltung Zeit zur Stabilisierung geben. Das heißt, Port C einstellen, warten, und dann abfragen. Dann erst mit dem nächsten Bit weitermachen. Du "siehst" an der LED immer noch die Wirkung von Port 0.
Datum: 03.05.2008 22:44
Andreas Kaiser wrote:
> Mit dem bischen Code lässt sich nix anfangen.
Hab schon drei Tage den Code isoliert, aber bitteschön:
#include <stdint.h> #include <avr/io.h> #include <avr/interrupt.h> #define LED_AN PORTD |= _BV(PORTD1) ISR(TIMER0_OVF_vect) { volatile uint8_t buttons = 0; uint8_t i; PORTC = _BV(0); if (PINB & _BV(PINB4)) { LED_AN; } /* buttons = 0; for (i = 0; i < 5; i++) { buttons <<= 1; if (PINB & _BV(PINB4)) { buttons |= _BV(0); } PORTC <<= 1; } */ } int main() { cli(); PORTB = 0; DDRB = 0; PORTC = 0; DDRC = 0xFF; PORTD = 0; DDRD = 0xFF; TCCR0 = _BV(CS01); TIMSK = _BV(TOV0); sei(); for (;;) { asm volatile ("nop" ::); } } |
Datum: 03.05.2008 22:46
Schwurbl wrote: > Ich schätze, es liegt an der Verzögerung der äußeren Beschaltung. Du > mußt Deiner Schaltung Zeit zur Stabilisierung geben. Das heißt, Port C > einstellen, warten, und dann abfragen. Dann erst mit dem nächsten Bit > weitermachen. Du "siehst" an der LED immer noch die Wirkung von Port 0. Das kann ja nicht sein. Die Codepassage, die die LED anschaltet, ändert sich ja nicht. Und zwischen den Aufrufen der ISR ist auch genug Zeit über. Ferner hängt ja bis auf die Dioden und die Schalter rein garnix am AVR dran... bis auf den Quarz und die Blockkondis natürlich.
PORTC = _BV(0); if (PINB & _BV(PINB4)) { LED_AN; } |
Datum: 03.05.2008 22:58
Doch, Schwurbl hat schon recht. Wenn man im direkt auf einen Ausgabebefehl folgenden Befehl einen Pin abfragt, der von der Ausgabe beeiflusst wird, dann klappt das nicht wie erwartet. Steht übrigens im Datasheet. Daher hängt das Ergebnis davon ab, was am Port C vorher ausgegeben wurde. Und das wiederum wird vom kommentierten Code bestimmt. Allerdings wäre da nicht C1 zu erwarten, sondern C5.
Datum: 03.05.2008 23:03
Andreas Kaiser wrote:
> Allerdings wäre da nicht C1 zu erwarten, sondern C5.
Hmm, du hast vollkommen Recht, das ist auch C5... muss mal wieder die
Brille putzen :-)
Also, so funktioniert es:
ISR(TIMER0_OVF_vect) {
volatile uint8_t buttons = 0;
uint8_t i;
PORTC = _BV(0);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
asm volatile ("nop" ::);
if (PINB & _BV(PINB4)) {
LED_AN;
}
/*
buttons = 0;
for (i = 0; i < 5; i++) {
buttons <<= 1;
if (PINB & _BV(PINB4)) {
buttons |= _BV(0);
}
PORTC <<= 1;
}
*/
}
|
Entschuldigung (...) Aber selbst mit 8 NOPs wars noch nicht getan... wo kommt denn da bloß die ganzen Leitungskapazität her?!
Datum: 03.05.2008 23:05
Das wäre jetzt eine prima Gelegenheit, die exakt verbaute Hardware zu dokumentieren. Sind die Dioden vielleicht 1N4000 oder ähnlich schnarchlangsame Genossen?
Datum: 03.05.2008 23:10
Ist es denn so, dass PORTC in Wahrheit einen Spaltentreiber schaltet, der eine entsprechende Abschaltverzögerung ausweist? Transistoren sind im Schaltbetrieb echte Low Performer.
Datum: 03.05.2008 23:14
Das kriegen wir auch hin... Anmerkungen: * An J1 (oben) hängen normalerweise noch LEDs, die sind aber testweise abgeklemmt. * Die Chose mit Q10 ist in Arbeit :-) Nachtrag: * Ja, es sind 4148er, die sollten aber bei dem Schnarchtakt, den der MC vorlegt, locker mitmachen. * Und Schwurbl hat auch Recht, es sind Spaltentreiber. Aber wenn der MC in die Basis mal seine 40mA reinfeuert, dann sollte auch das kein Problem darstellen, zumal ja noch 1kOhm dazwischen liegen. Was ich gerade denke: 10kOhm Pull-down sollten eigentlich auch langen, oder?
Datum: 03.05.2008 23:18
Und welchen Wert hat nun der Pulldown für die Taster? Ich denke Du hast 10k verbaut. Reduzieren den mal auf ein 1k.
Datum: 03.05.2008 23:20
Andreas Kaiser wrote:
> Wo ist denn der Pulldown an B4?
Auch das, der wurde nachgerüstet (Designfehler) und liegt unterm PCB...
ich hab ihn hier mal dazugemalt.
Datum: 03.05.2008 23:27
Wie programmierst du den eigentlich? 80-er Jahre Methode: raus/rein/raus/rein/... oder fehlt im Bild auch der ISP-Anschluss? Ich frage deshalb so blöd, weil B4 zum ISP gehört.
Datum: 03.05.2008 23:29
Andreas Kaiser wrote: > Wie programmierst du den eigentlich? 80-er Jahre Methode: > raus/rein/raus/rein/... oder fehlt im Bild auch der ISP-Anschluss? Ich > frage deshalb so blöd, weil B4 zum ISP gehört. Die Frage ist absolut berechtigt :-) Neee, des Rätsels Lösung ist viiiieel einfacher: http://www.trianglemicro.com/TMS-DIP8.jpg
Datum: 03.05.2008 23:30
Jetzt mal grundätzlich gesprochen darfst Du sowieso pro Timerinterrupt genau eine Spalte weiterschalten. Vor dem Weiterschalten, also bei Eintritt in den Interrupt wird der Button abgefragt. Also:
volatile uint8_t buttons = 0; ISR(TIMER0_OVF_vect) { if (PINB & _BV(PINB4)) buttons |= PORTC; if (PORTC == 0x20) PORTC = 0x01; else PORTC <<= 1; } |
Die Weitermeldung/Synchronisation mit main fehlt hier natürlich.
Datum: 03.05.2008 23:32
Sven Pauli wrote: > * Ja, es sind 4148er, die sollten aber bei dem Schnarchtakt, den der MC > vorlegt, locker mitmachen. 1N4148 sind ok. Ich bezog mich auf die 1N400x Serie. Die sind nämlich ein bischen langsam. > Was ich gerade denke: 10kOhm Pull-down sollten eigentlich auch langen, > oder? Hängt davon ab, wie lang die Leitung ist. Daumenregel ist 100pF/m.
Datum: 03.05.2008 23:38
Schwurbl wrote: > Jetzt mal grundätzlich gesprochen darfst Du sowieso pro Timerinterrupt > genau eine Spalte weiterschalten. Vor dem Weiterschalten, also bei > Eintritt in den Interrupt wird der Button abgefragt. Auch das stimmt natürlich. Ich hab das ganze Anzeige-Multiplexing erst einmal entfernt, um das Problem mit den Eingaben zu lösen. Erst wenn das einmal richtig funktioniert, dann kann werde ich auch wieder MUXen :-) Und zwar so: 1. Spalte für Zeit t anschalten 2. Zeilen für Zeit t dunkeltasten (verhindert Schlieren und "Nachleuchten"!) und gleichzeitig die Spalten durchlaufen, um die Taster abzufragen 3. Nächste Spalte anzeigen 4. von vorne Ich werde in jeder Dunkeltastung alle Taster auslesen, um genug Geschwindigkeit für den Encoder vorzulegen... das ist der Hintergedanke dabei.
Datum: 03.05.2008 23:58
Naja, Deine Auflistung fing so gut an und dann dieses Tasterabfragen während Dunkteltastung. Keine Ahnung, was Dein Encoder für Sonderansprüche stellt. Ich denke, Du stellst Dich unnötigen Herausforderungen.
Datum: 04.05.2008 00:06
Schwurbl wrote: > Naja, Deine Auflistung fing so gut an und dann dieses Tasterabfragen > während Dunkteltastung. Keine Ahnung, was Dein Encoder für > Sonderansprüche stellt. Ich denke, Du stellst Dich unnötigen > Herausforderungen. Naja, das warn nur Experimente. Rechne mal durch: Timer läuft mit 4MHz/8 = 500kHz, die ISR wird dann mit 500kHz/256 = knapp 2kHz aufgerufen. Jetzt würde ich noch 6 Stellen mit entsprechender Dunkeltastung dazwischen (die brauchts, wirklich!) multiplexen, also läge ein vollständiger Datensatz der Tasten mit 2kHz/12 = knapp 160Hz vor, das reicht einfach nicht für diesen Pollin-Encoder -- zumindest hat es bei meinen Versuchen nicht gereicht, leider.
Datum: 04.05.2008 00:16
Ja, an der Dunkeltastung zweifle ich nicht. Warum braucht man die? Weil die externen Bauteile so langsam sind? Was war nochmal Dein Problem? Langsam sollte es klingeln ;-) Aber zugegeben: Einen Drehgeber hab ich tatsächlich noch nicht in eine gemultiplexte Matrix gehängt... Für mich bist Du der Evel Knievel unter den Multiplexern.
Datum: 04.05.2008 01:36
Sven Pauli wrote: > knapp 2kHz aufgerufen. Jetzt würde ich noch 6 Stellen mit entsprechender > Dunkeltastung dazwischen (die brauchts, wirklich!) Liegt aber nur an Deiner Schaltung. Emitterschaltung ohne Basisableitwiderstand sättigt richtig fett und sperrt nur ganz langsam. Ich nehme daher lieber Kollektorschaltung, dann brauchts keinerlei Dunkeltastung und spart die Basiswiderstände. Den größeren Spannungsabfall muß man bei der Dimensionierung der Segmentwiderstände berücksichtigen. Peter
Datum: 04.05.2008 08:56
Peter Dannegger wrote: > Liegt aber nur an Deiner Schaltung. > Emitterschaltung ohne Basisableitwiderstand sättigt richtig fett und > sperrt nur ganz langsam. Hmm... ganz langsam ist ja auch der MUX-Takt, also 160Hz sollten die Transen aber mitmachen... Aber trotzdem macht mich das stutzig -- woher soll die Verzögerung denn noch kommen?
Datum: 04.05.2008 09:38
Peter Dannegger wrote: > Emitterschaltung ohne Basisableitwiderstand sättigt richtig fett und > sperrt nur ganz langsam. Sind doch welche drin. Rechne den steuernden Ausgang mit, der ja dann via Basiswiderstand in die Gegenrichtung zieht. Mit niederohmigem Ableitwiderstand geht es zwar noch schneller, aber das ist eher bei 20KHz Schaltfrequenz interessant. Nur im Reset ist die Basis offen, was bei bipolaren Transistoren in dieser Spannungsklasse aber nicht weiter stört (bei Hochspannung wär's was anderes).
Datum: 04.05.2008 09:51
Hab jetzt mal den Pulldown auf ein Zehntel (1kOhm) reduziert -- die Tastenabfrage funktioniert jetzt eindeutig; ich frag mich aber immer noch, wo ich die ganzen parasitären C verbaut hab... Ich schieb die Bits der Tasten jetzt doch gemütlich im MUX-Takt rein, so wie Schwurbl oben mal vorgeschlagen hatte; mit dem Encoder muss ich mir aber noch was einfallen lassen...
Datum: 04.05.2008 09:59
Bedenke, dass die Leitung, die Umgeladen werden muss, an sämtlichen Tastern und Dioden anliegt. Das addiert sich sicherlich zu einer hübschen Gesamtkapazität. Ich hoffe, Du hast ein Oszi.
Datum: 04.05.2008 10:03
Schwurbl wrote: > Bedenke, dass die Leitung, die Umgeladen werden muss, an sämtlichen > Tastern und Dioden anliegt. Das addiert sich sicherlich zu einer > hübschen Gesamtkapazität. Ich hoffe, Du hast ein Oszi. Hab ich... wobei ein Logic hier sinnvoller wäre :-) Ne, die Flanken waren und sind steil.
Datum: 04.05.2008 10:11
Mit einem Scope bewaffnet kannst du ja die zeitliche Differenz zwischen dem C-Ausgang und dem B-Eingang bewundern und nach dem obskuren "Verzögerungsglied" suchen. Und bei der Gelegenheit auch die Kapazität ausrechnen. Es wurde schon mehrfach auf die Länge der Verdrahtung hingewiesen. Wie sieht's da denn aus?
Datum: 04.05.2008 10:48
Andreas Kaiser wrote: > Es wurde schon mehrfach auf die Länge der Verdrahtung hingewiesen. Wie > sieht's da denn aus? 10 cm Litze...
Datum: 04.05.2008 11:16
Andreas Kaiser wrote: > Peter Dannegger wrote: > >> Emitterschaltung ohne Basisableitwiderstand sättigt richtig fett und >> sperrt nur ganz langsam. > > Sind doch welche drin. Rechne den steuernden Ausgang mit, der ja dann > via Basiswiderstand in die Gegenrichtung zieht. Beim Einschalten fallen etwa 4,2V ab, beim Ausschalten nur 0,5V. Der Entladestrom ist also deutlich geringer. > Mit niederohmigem > Ableitwiderstand geht es zwar noch schneller > aber das ist eher bei > 20KHz Schaltfrequenz interessant. Nö. Im Dunkeln sieht man selbst ein LED deutlich aufblitzen, die nur 1µs eingeschalten wird. Ich hatte mal beim STK500 das DDRB-Register einen Zyklus vor dem PORTB gesetzt und mich gewundert, warum die LEDs bei jedem Reset aufblitzten. Peter
Datum: 04.05.2008 11:18
Peter Dannegger wrote: > Im Dunkeln sieht man selbst ein LED deutlich aufblitzen, die nur 1µs > eingeschalten wird. > Ich hatte mal beim STK500 das DDRB-Register einen Zyklus vor dem PORTB > gesetzt und mich gewundert, warum die LEDs bei jedem Reset aufblitzten. Das stimmt... ich hab die Dunkeltastung mal spaßeshalber einfach so realisiert, indem ich direkt hintereinander die Spalte ein- und wieder ausgeschaltet hab (ASM-Listing sagt: 2 Zyklen). Hat schon gereicht, um die Anzeige bei Dunkelheit abzulesen.
Antwort schreiben
Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
- Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
- Aussagekräftigen Betreff wählen
- Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
- Groß- und Kleinschreibung verwenden
- Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
- JPEG-Dateien (.jpg) nur für Fotos verwenden, Schaltpläne, Screenshots usw. als PNG oder GIF anhängen
Formatierung (mehr Informationen...)
- [c]C-Code[/c]
- [avrasm]AVR-Assembler-Code[/avrasm]
- [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
- [math]Formel in LaTeX-Syntax[/math]
- [[Titel]] - Link zu Artikel

