ATTiny45 PWM

OP #6074911
Lesenswert?

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
4
Tccr0a.com1a0 = 0
5

6
Tccr0a.wgm01 = 1
7
Tccr0a.wgm00 = 1                                            'Fast PWM
8

9
Pout Alias Ocr0a
10

11
Ddrb.0 = 1                                                  'OC0A Output PWM
12

13
Ocr0a = 100
14
Do
15
Loop
#6074968
Lesenswert?

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.
OP #6075863
Lesenswert?

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
Gast #6075870
Lesenswert?

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.
Gast #6075909
Lesenswert?

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...
OP #6075994
Lesenswert?

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
OP #6076084
Lesenswert?

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
#6076115
Lesenswert?

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.
OP #6076121
Lesenswert?

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
Gast #6076281
Lesenswert?

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.
Gast #6076319
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren