...gibt es irgend ein Geheimnis, wieso ein Pullup am Pin OCR0A bei einem Tiny85 NICHT funktioniert? Ich habe den OCR0A im Programm mal verwendet (fast PWM) und dann nur das Bit auf 0 gesetzt, also den Timer vom Ausgang abgekoppelt, dann als Eingang verwendet - trotz dass ich den PU einschalte, "gibt" es den nicht, der Pin floatet und macht wilde Sachen - mit externem PU geht's dann 1A. -> Gibt es eine weitere Konfig AUSSER OCR0A Bit, welches die Verwnedung des Pullups unterbindet? Ein weiterer Tiny85 (neu) verhält sich gleich. Ja, ich vermute das Problem sitzt vor dem Rechner :) Danke, Klaus.
Zeige mal einen minimalen kompilierbaren Quelltext, mit dem man das nachvollziehen kann.
Das verstehe ich nicht: zum einen gibt es keinen "Pin OCR0A", sondern nur PB0, welcher auch die Bezeichnung OC0A trägt, wenn er für PWM genutzt wird; zum anderen ist mir unklar, wofür man bei PWM einen Pullup-Widerstand benötigt, der Pin wird ja zwischen GND und Vcc geschaltet.
Hallo Stefan, das Phänomen ergab sich aus deiner DCF Analog Uhr :) Ich habe eine Einzeigervariante und wollte OCR0A als Eingang benutzen, habe das Bit also auf 0 gesetzt und den Pin als Input umkonfiguriert. Ich befürchte aber leider, es gibt wg dem Reuse von Code ein Geheimnis, das ich nicht kenne - eine "from the scratch" Variante a la "if(PIN set) activate LED" habe ich noch nicht probiert... Klaus. PS: Beim delay-Polling der DCF Zeit in der main wird 1 Minute zuviel angezeigt, wieso ist mir unklar - aber natürlich wäre das Ganze interruptbasiert eh viel sauberer, daher habe ich es nicht weiter untersucht, denn -1 hat gereicht.
Der interne Pull-Up Widerstand eines Eingang wird aktiviert, indem man das entsprechende Bit im PORTx Register auf 1 setzt.
> wird 1 Minute zuviel angezeigt
Es ist ein bisschen weniger als 1 Minute. Fehlerursache ist, dass das
Programm nach dem Empfang der Zeit nicht bis zur 0. Sekunde abwartet,
sondern die Zeit sofort ausgibt.
Mir ist das inzwischen auch aufgefallen, ich hatte aber keine Lust,
deswegen ein Faß aufzumachen. Die Korrektur hätte das Programm deutlich
komplexer gemacht. Außerdem kann man die Sekunden auf den billigen
Instrumenten sowieso nicht präzise ablesen.
"Der interne Pull-Up Widerstand eines Eingang wird aktiviert, indem man das entsprechende Bit im PORTx Register auf 1 setzt." - genau das habe ich natürlich gemacht, aber "effektiv" wird der nicht. Aber vll liegt das auch an der Portierung von Tiny13 auf Tiny85. Ich habe eine Linearisierungsfunktion f(OCR0B) in anzeigen() eingebaut, bei mir passt es bis auf 0.5 Winkelgrad genau, quasi perfekt. Die "-1" löst das Problem, da ich auch bei Sekunde=35 den ISR_Timer synce. Klaus.
Zeige mal einen minimalen kompilierbaren Quelltext, mit dem man das
nachvollziehen kann.
> Die "-1" löst das Problem, da ich auch bei Sekunde=35 den ISR_Timer synce.
Cooler Ansatz, das übernehme ich.
...habe ich nicht, war mir zu aufwendig - weiß aber natürlich, dass das der nächste Analyseschritt wäre. Aber vll gibt es hier jmd der sagt "ja, das ist mir auch schon mal passiert, bla bla bla". Es ist eine rein akademische Frage, mit dem externen PU läuft es ja - aber der Grund interessiert mich schon. Vll schaue ich es mir am Sonntag nochmal an. Klaus.
Wenn du den Pullup setzen möchtest, während der Ausgang aktiv ist, funktioniert das nicht. Das klappt nur, wenn der Pin auch als Eingang definiert ist - dann allerdings wird das auch beibehalten, solange der Pin ein Ausgang ist. Schaltest du wieder zurück auf Eingang, ist dann auch der Pullup wieder aktiv.
...zudem habe ich zwei Modi: 24h Anzeige oder alle 20s Wechsel zwischen H M S (und auch die Sekunde geht exakt bei 60 dann wieder auf 0). Dafür brauchte ich auch den Input als Umschalter. Mein Instrument hat eine Nichtlinearität, die von 0...12 stark zu und dann wieder abnimmt - mit etwas Formelei war das aber empirisch schnell ermittelt und ist nun quasi passé. Klaus.
Hallo Matze, Danke - genau das habe ich ja alles getan, aber er will trotzdem nicht. Lassen wir es dabei, ich probiere es am Sonntag nochmal mit einem Minimalprogramm und nehme dann Stück für Stück die Configs von OCR0A/B dazu um zu sehen, ab welcher Zeile das Problem einsetzt. Klaus.
Klaus R. schrieb: > "Der interne Pull-Up Widerstand eines Eingang wird aktiviert, indem man > das entsprechende Bit im PORTx Register auf 1 setzt." - genau das habe > ich natürlich gemacht Und warum schreibst Du erst 2-mal das Gegenteil: Klaus R. schrieb: > dann nur das Bit auf 0 gesetzt Klaus R. schrieb: > habe das Bit also auf 0 gesetzt Wie wärs endlich mal damit: Stefan U. schrieb: > Zeige mal einen minimalen kompilierbaren Quelltext, mit dem man das > nachvollziehen kann. Der ATtiny85 hat doch nur 6 IOs. Wenn es damit Probleme gäbe, hätte das schon längst jemand gemerkt.
...ich habe das OCR0A (!) Bit auf 0 gesetzt, damit der Timer abgekoppelt wird und ich den IO als Input verwenden kann, dann DDRB entsprechned PB0 auf 0 (Input) und PORTB PB0 auf 1 (Pullup an) - der Pullup zeigt sich aber nicht. Ich weiß, dass es an mir liegt. Den Minimal-Code habe ich (noch) nicht, ich suchte eher nach Ideen. Im Datenblatt fand ich keine Hinweise, wieso das nicht gehen soll - aber es wird irgend ein ganz dämliches Problem sein, klar...ohne Code macht das aber wenig Sinn, habe ich verstanden. Klaus.
Klaus R. schrieb: > S: Beim delay-Polling der DCF Zeit in der main wird 1 Minute zuviel > angezeigt, wieso ist mir unklar - aber natürlich wäre das Ganze > interruptbasiert eh viel sauberer Das hat nichts mit Interrupt zu tun, Du hast die Codierung des DCF nicht verstanden. Die Zeitinformation wird immer in der vorherigen Minute gesendet. Was ja auch logisch ist, man kann nur das anzeigen, was man vorher empfangen hat. Du brauchst also noch 2 weitere Bytes für die Anzeige:
1 | if( second == 0 ){ |
2 | minute_display = minute_sample; |
3 | hour_display = hour_sample; |
4 | }
|
Klaus R. schrieb: > ...ich habe das OCR0A (!) Bit auf 0 gesetzt, damit der Timer abgekoppelt > wird Das Bit gibt es nicht, nur ein Register heißt so. Für das Abkoppeln sind COM0A1 und COM0A0 zuständig.
Ich vermute, du wirst versehentlich irgendwo aufs PORTB Register schreiben und damit den Pullup zermanschen. Wenn du daraufhin den Code nochmal durchgehst, wirst du vermutlich fündig. Ein Hardware Bug des Tiny85 ist es sicher nicht.
@Peter: ja, sry, ich meine die beiden Bits COM0A1 und COM0A0, beide sind 0. Der DCF Code stammt von Stefan Us, ich habe ihn also eher nachvollzogen, das Problem bemerkt und behoben. @Matthias: Ja, danach schaue ich nochmal - Danke. Klaus.
> Du brauchst also noch 2 weitere Bytes für die Anzeige
Du hast absolut Recht. Eine Minute zu subtrahieren würde es nur noch
komplizierter machen, weil die Stunden dann auch noch falsch wären.
Ich habe es schon so korrigiert, wie du vorgeschlagen hast.
@Klaus Zeig uns einen minimalen, von dir getesteten, beispielcode... Wie peter schon vermutet hat, hast du wahrscheinlich das falsche register angesprochen und der timer ist weiterhin im pwm mode an dem pin...
@TestX: Ist er nicht, denn mit einem externen pullup geht es ja - aber ohne Beispielcode geht's nichts weiter korrekt. Danke an Peter mit dem Hinweis auf die Stunde, die ist bei Minute 59 dann auch falsch, ja. Klaus.
> ich meine die beiden Bits COM0A1 und COM0A0, beide sind 0 Dadurch wird der Pin zwar zum Eingang, aber der Pull-Up schaltet sich nicht von alleine ein. > dann DDRB entsprechned PB0 auf 0 (Input) > und PORTB PB0 auf 1 (Pullup an) Da es nicht funktioniert, muss irgendwo anders ein Fehler sein. Wir können Dir nicht weiter helfen, solange du nicht das machst: > Zeige mal einen minimalen kompilierbaren Quelltext, mit dem man das > nachvollziehen kann.
Die Salbe? Aktiv gesetzt sicherlich nicht, aber ick schau ditte mal naaach. Klaus.
@Klaus, wie schnell nach dem Umschalten von PWM auf Eingang liest du denn den Zustand des Pis ein? Wenn der Ausgang zuvor Low war und du schaltest auf Eingang dauert es auf Grund der Kapazität der Eingänge und des recht hochohmigen int. Pullup schon einige Zyklen bis der Pegel als High erkannt wird. Sascha
#define SWITCH PB0 ... #define MODE_SWITCH (PINB & (1<<SWITCH)) ... PORTB= (1 << MODE_SWITCH) | (0<<PWM) | (0<<STATUS_LED) | (0<<SIGNAL_LED) | (1<<DCF_INPUT); Ou man. Iwann habe ich mal die defines geändert / rumkopiert - leider beschwert sich GCC (zu Recht) dabei nicht :) Klaus.
Stefan U. schrieb: > Was willst du uns mit diesem Beitrag mitteilen? Nur kurz überlegen. MODE_SWITCH hat da drin nichts zu suchen, stattdessen sollte SWITCH drin stehen:
1 | PORTB= (1 << SWITCH) | (0<<PWM) | (0<<STATUS_LED) | (0<<SIGNAL_LED) |
2 | | (1<<DCF_INPUT); |
Dann klappts.
Kooorrekt - das Problem saß also wie vermutet vor dem Rechner :) Klaus.
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.