Moin,
Ich versuche einen kleinen Regler für Bürstenmotoren zu bauen.
RC-Signal einlesen, PWM raus.
Das RC-Signal lese ich mit PCint ein und messe das Signal mit einem
freilaufendem Timer.
Funktioniert.
Nun die PWM auf Timer1, mit einem Tiny85 auf einem Arduino-Board hat das
auch prima funktioniert.
Das Ding ist mir aber zu klobig, also habe ich das auf einem Breakout
mit einem Tiny45 gemacht und die PWM geht nicht.
Die Hardware ist Ok. Ich kann den Pin toggeln lassen, das RC-Signal
einlesen geht, PWM aber nicht.
Dann habe ich den dokumentierten Bug im Tiny45 bzgl. OC1B gefunden, der
Workaraound hat aber auchch nicht funktioniert.
Also alles umgebaut, PWM nun auf OC0A. Und auch da funktioniert es
nicht!
Mag mal einer drüber schauen?
1
Tccr0b.cs01 = 1 'Prescaler 8 = 4khz @ 8Mhz
2
3
Tccr0a.com1a1 = 1 'OC0A set on Ovf, clear on match in fast PWM
Norbert S. schrieb:> Tccr0a.com1a1 = 1 'OC0A set on> Tccr0a.com1a0 = 0
Du nimmst die Bit-masken von timer1 für register von timer0....
Lad am besten mal das Originale Programm (das für timer1) hier hoch...
Norbert S. schrieb:> Das Ding ist mir aber zu klobig, also habe ich das auf einem Breakout> mit einem Tiny45 gemacht und die PWM geht nicht.
Also wenn das Teil mit nem Arduino-Board mit dem Tiny45 funktioniert wie
gewünscht, auf einem extra angefertigten Board dann aber nicht dann kann
Norbert S. schrieb:> Die Hardware ist Ok.
definitiv nicht stimmen.
Ansonsten: Anmerkungen von Max stimme ich zu: Du verwendest Bezeicher
für fremde Register. So etwas kann klappen, muss aber auch nicht.
Moin,
Ok, der Tippfehler mit com1an war es natürlich. Jetzt läuft es mit
Timer0, allerdings mit Phase correct PWM weil 0A mit Fast PWM diese
blöde Angewohnheit hat, immer entweder nie 100% oder 0% ausgeben kann,
je nach Polung. Egal, läuft.
Das ursprüngliche Problem: Es lief mit OC1B auf dem Arduinoboard mit
einem Tiny85!
Das eigene Board hat einen Tiny45 und der hat(te) wohl genau da einen
Bug:
-----------------
Timer Counter 1 PWM output generation on OC1B – XOC1B does not work
correctly
Timer Counter1 PWM output OC1B-XOC1B does not work correctly. Only in
the case when the control bits, COM1B1 and COM1B0 are in the same mode
as COM1A1 and COM1A0, respectively, the OC1B-XOC1B output works
correctly.
Problem Fix/Work around
The only workaround is to use same control setting on COM1A[1:0] and
COM1B[1:0] control bits, see table 14-
4 in the data sheet. The problem has been fixed for Tiny45 rev D.
-----------------
Nur leider funktionierte der Workaround auch nicht.
Ich konnte den Pin manuell toggeln, also war der offensichtlich ok und
nur nicht am Timer drangeklöppelt.
So geht es jetzt erstmal und der letzte verbleibende frische Tiny45
kommt in die Tonne.
Naja, danke für den Hinweis mit dem com1an, so hatte ich das gehofft.
Daß das Bascom ist sieht man vielleicht. Da kann man wirklich jeden
Bitbezeichner mit jedem Register unterjubeln, ist nur die Bitnummer. Ich
denke bei C-Compilern wird das aber nicht anders sein, oder?
Gruß,
Norbert
Norbert S. schrieb:> Ich denke bei C-Compilern wird das aber nicht anders sein, oder?
korrekt, C-Compiler können solche Fehler ebenfalls nicht erkennen.
Bei STM32 enthalten die Konstanten immer den namens des Registers. Zum
Beispiel:
Register: RCC->CR
Ein Bit davon heisst: RCC_CR_PLLON
Schreibzugriff: SET_BIT(RCC->CR, RCC_CR_PLLON);
Da kann man leicht erkennen, wenn Register- und Bit-Namen durcheinander
gewürfelt wurden. Nur tut es leider nicht der Compiler erkennen.
Norbert S. schrieb:> Das eigene Board hat einen Tiny45 und der hat(te) wohl genau da einen> Bug:
[...]
Das muss dann aber ein seeeehr gut abgehangener Tiny gewesen sein...
Dieser Bug betraf die Revisionen B..C. Aktuell ist F. Und seit Rev. D
gibt es lt. DB keine known errata mehr. Da liegen sicher viele Jahre
dazwischen...
Fazit: Man muss auch mal den Mut aufbringen, etwas wegzuwerfen. Das
fällt zumindest dann eigentlich sehr leicht, wenn der Ersatz weniger
kostet als ein Besuch auf'm Bahnhofsklo nur zum Pinkeln...
Moin,
Nunja, falsches Bit zum Register ist ja nun nicht so ein gängiger
Fehler. Wobei das wirklich einfach für den Compliler wäre...
Ja, der Tiny ist alt. Mit "0934" als Datecode wohl gut 10 Jahre. Lag
hier noch so rum...
Wie gesagt, der Zweite den ich noch habe/hatte ist soeben in die Tonne
gewandert.
Gruß,
Norbert
Moin,
Vorrausgesetzt, die Bitbezeichner sind eindeutig, also Bit abc01 gibt es
nur in einem Register, steht das zumindest bei Bascom als Kommentar in
der Definitionsdatei des µC drin.
Dummerweise nur als Kommentar, z.B. so:
---------------
; TCCR0A - Timer/Counter Control Register A
WGM00 = 0 ; Waveform Generation Mode
WGM01 = 1 ; Waveform Generation Mode
COM0B0 = 4 ; Compare Output Mode, Fast PWm
COM0B1 = 5 ; Compare Output Mode, Fast PWm
COM0A0 = 6 ; Compare Output Mode, Phase Correct PWM Mode
COM0A1 = 7 ; Compare Output Mode, Phase Correct PWM Mode
---------------
Da muss der Compiler doch nur erkennen, daß das Bit nicht zum Register
passt.
Allerdings denke ich, daß der Leidensdruck da nicht gegeben ist.
Da fielen mir wirklich ärgerlichere Dinge ein, die auch nicht so
schwierig sein können und wo man sich an den Kopf packt. Sei es C,
Bascom oder sonstwas.
Gruß,
Norbert
Zumindest bei C dürfte das ziemlich unmöglich sein. Für den Compiler ist
so ein Register nur eine Speicheradresse wie jedes andere Byte
(inklusive RAM) auch.
Bei AVR gibt es zwar die spezielle IO-Adressierung, aber bis der
Compiler anfängt über solche Sachen auch nur nachzudenken hat der
Präprozessor jeglichen Namensbezug der Werte schon lange entsorgt.
Da muss einfach Brain 2.0 aktiv werden und die richtigen Knöpfe drücken.
Max D. schrieb:> Zumindest bei C dürfte das ziemlich unmöglich sein. Für den Compiler ist> so ein Register nur eine Speicheradresse wie jedes andere Byte> (inklusive RAM) auch.
Also vorweg: Ich sehe da auch keinen Handlungsbedarf.
Aber woher hat der Compiler die Speicheradresse von TCCR1A oder so?
Und die Nummer von Bit Com1a0? Richtig, aus der Definitionsdatei.
Der Compiler findet TCCR1A, kramt in der Def. und findet Adresse XY. Da,
die Bitschieberei in diesem TCCR1A, Com1a0 steht ... such... ah, ne 3
muss ich nehmen.
Wenn in der Def. nun steht:
TCCR1A = Adresse XY
bla..
bla
.
Com1a0 = 5
..
...dann kann das ja nicht so schwierig sein.
Das könnte man als reine Syntaxprüfung vorab machen.
Ok, Ppipfax, braucht man nicht.
Da nerven andere Dinge viel mehr.
Daß Bascom immer noch nur eine Operation pro Zeile kann (A = A + B + C
geht nicht) oder daß C es nicht selber blickt, daß eine Variable
vielleicht in einer ISR verändert werden könnte. Nein, ich möchte die
Argumente eigentlich nicht hören/lesen, warum Letzteres so sein muss.
Ich werde es aber gleich vermutlich doch erfahren... ;-)
Gruß,
Norbert
Norbert S. schrieb:> Moin,>> Ok, der Tippfehler mit com1an war es natürlich. Jetzt läuft es mit> Timer0
Ich hatte ja deinen Ausgangspost so gelesen, dass es mit Timer1 auf dem
Breakout-Board nicht lief und du darauf hin auf Timer0 umgebaut hattest
und auch damit lief es nicht. Aber auf dem Arduino Board lief es wie
erwartet.
Norbert S. schrieb:> Da muss der Compiler doch nur erkennen, daß das Bit nicht zum Register> passt...dann kann das ja nicht so schwierig sein.
Der Compiler sieht nur Adressen und Bit-Nummern. Jedes Register hat 8
Bits. Solange du nicht versuchst, das neunte Bit zu ändern, ist aus
Sicht des Compilers alles Ok.
Bedenke, dass der Compiler nicht intelligent ist. Er hat keinen blassen
Schimmer, was Namen bedeuten. Er kennt nur eine Hand voll
Schlüsselwörter wie "if", "else", "for", ...
Um dieses Verhalten zu ändern, müsste man eine neue Programmiersprache
erfinden. Es wird ja auch alle paar Monate eine neue Programmiersprache
als die Lösung der IT Probleme angepriesen. Ich kenne allerdings im
Mikrocontroller Umfeld keine C-Ähnliche Sprache, die sich lange gehalten
hat.
Es nicht nicht immer gut, Dinge zu ändern, weil man es kann. Man sollte
schon einen guten Grund haben und daran denken, dass jede Änderung neue
Probleme erzeugt. Manchmal ist es besser, den alten Gaul alt sein zu
lassen und sich an seine Eigenarten zu gewöhnen.
Stefan F. schrieb:> Der Compiler sieht nur Adressen und Bit-Nummern. Jedes Register hat 8> Bits. Solange du nicht versuchst, das neunte Bit zu ändern, ist aus> Sicht des Compilers alles Ok.
Man könnte eine Structur aus Bitfeldern auf das SFR legen, bei dem die
existierenden Bits passende Namen haben. Dann liefert der Compiler einen
Fehler, wenn nicht existierende Bits oder Bits im falschen Register
angesprochen werden sollen.
MfG Klaus