Forum: Mikrocontroller und Digitale Elektronik Tiny 85: OCR0A kein Pull-Up mgl?


von Klaus R. (klaus2)


Lesenswert?

...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.

von Stefan F. (Gast)


Lesenswert?

Zeige mal einen minimalen kompilierbaren Quelltext, mit dem man das 
nachvollziehen kann.

von S. Landolt (Gast)


Lesenswert?

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.

von Klaus R. (klaus2)


Angehängte Dateien:

Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

Der interne Pull-Up Widerstand eines Eingang wird aktiviert, indem man 
das entsprechende Bit im PORTx Register auf 1 setzt.

von Stefan F. (Gast)


Lesenswert?

> 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.

von Klaus R. (klaus2)


Lesenswert?

"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.

von Stefan F. (Gast)


Lesenswert?

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.

von Klaus R. (klaus2)


Lesenswert?

...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.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von Klaus R. (klaus2)


Lesenswert?

...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.

von Klaus R. (klaus2)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von Klaus R. (klaus2)


Lesenswert?

...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.

von Peter D. (peda)


Lesenswert?

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
  }

von Peter D. (peda)


Lesenswert?

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.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von Klaus R. (klaus2)


Lesenswert?

@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.

von Stefan F. (Gast)


Lesenswert?

> 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.

von TestX (Gast)


Lesenswert?

@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...

von Klaus R. (klaus2)


Lesenswert?

@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.

von Stefan F. (Gast)


Lesenswert?

> 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.

von Äxl (geloescht) (Gast)


Lesenswert?

PUD (PUll-Up disalbe) gesetzt?

Äxl

von Äxl (geloescht) (Gast)


Lesenswert?

wie schreibt man "dissäijbel" OMG

Äxl

von Klaus R. (klaus2)


Lesenswert?

Die Salbe? Aktiv gesetzt sicherlich nicht, aber ick schau ditte mal 
naaach.

Klaus.

von P. P. (Gast)


Lesenswert?

Was für 'ne Raterunde...

"Isch 'abe garkeinen Code..."

von Äxl (geloescht) (Gast)


Lesenswert?

machma

Äxl

von Sascha W. (sascha-w)


Lesenswert?

@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

von Klaus R. (klaus2)


Lesenswert?

#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.

von Stefan F. (Gast)


Lesenswert?

Was willst du uns mit diesem Beitrag mitteilen?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von Klaus R. (klaus2)


Lesenswert?

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
Noch kein Account? Hier anmelden.