Forum: Compiler & IDEs PWM mit dem ATTINY26


von Matthias W. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen!
Möchte ein PWM-Signal erzeugen. Soweit wie in dem Dateianhang bin ich
schon gekommen, doch es passiert leider nichts an dem Ausgang!
Würde mich freuen, wenn mir jemand weiterhelfen könnte!

Controller: ATTINY26

MFG
Matthias

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Du musst den zugehörigen Pin auch als Ausgang schalten (DDRx-Register).

von Rolf Magnus (Gast)


Lesenswert?

Übrigens spaziert dein Mikrocontroller in die Pampa, sobald deine
main()-Funktion fertig ist. Die muß so geschrieben sein, daß der
Controller da nie rauskommt.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Eigentlich sollte der Compiler da sogar meckern, denn die Funktion ist
nicht void definiert und enthält keine Endlosschleife.

Oder ist es vielleicht so, daß dem Compiler das für main völlig egal
ist? Daß er nicht motzt, wenn hinter einer Endlosschleife ein
 'return 1;' fehlt, kann ich ja noch verstehen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Übrigens spaziert dein Mikrocontroller in die Pampa, sobald deine
> main()-Funktion fertig ist.

Nicht in die Pampa, sondern er macht ein exit(), was letztlich (per
default) eine Endlosschleife ist.  Der PWM sollte trotzdem weiter
PWMen.

> Eigentlich sollte der Compiler da sogar meckern, denn die Funktion
> ist nicht void definiert und enthält keine Endlosschleife.

Ja.  Außerdem definiert man main() nicht void. ;-)

von Matthias W. (Gast)


Angehängte Dateien:

Lesenswert?

Schönen Dank für die schnellen Antworten!
Ich hab das Programm abgeändert (s.o), doch es funzt immer noch nicht.
Der Port OC1A ist jetzt dauer High.

Hat jemand noch ein Vorschlag???

MFG
Matthias

von Rolf Magnus (Gast)


Lesenswert?

> Nicht in die Pampa, sondern er macht ein exit(), was letztlich
> (per default) eine Endlosschleife ist.  Der PWM sollte trotzdem
> weiter PWMen.

Ah, das wußte ich noch nicht. Da hat ja einer mitgedacht. Wer kann denn
sowas ahnen? ;-)

> Außerdem definiert man main() nicht void. ;-)

Ist avr-gcc nach C-Norm eine "hosted implementation" oder
"free-standing"? Bei letzterer ist nicht festgelegt, wie main()
auszusehen hat. Es ist nicht mal festgelegt, daß es die überhaupt geben
muß.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Ich hab das Programm abgeändert (s.o), doch es funzt immer noch
nicht.
> Der Port OC1A ist jetzt dauer High.

Hmm, lies doch mal das Datenblatt ein bisschen...  Der ATtiny26
scheint sich hier um einiges anders zu benehmen als andere AVRs,
d.h. du kannst PWM-Code, der für einen anderen AVR geschrieben worden
ist, nicht 1:1 übernehmen.

M. E. musst du insbesondere OCR1C noch auf einen sinnvollen Wert
setzen (Datenblatt S. 74 unten, Formel für PWM-Frequenz S. 76 unten).

>> Außerdem definiert man main() nicht void. ;-)

> Ist avr-gcc nach C-Norm eine "hosted implementation" oder
> "free-standing"?

It depends.  Mit der Option -ffreestanding wird er letzteres.
Allerdings sollte man sich sehr genau überlegen, ob man das wirklich
will.  Naturgemäß könnte man für einen Controller ja immer erstmal
sagen: ,,Ist doch freestanding, keine Frage!'', aber man hat ja auch
eine Standardbibliothek, auf die man zurückgreifen möchte.  Im hosted
mode (der der Default ist beim GCC) kann der Compiler bestimmte
Optimierungen vornehmen basierend auf impliziten Annahmen über das
Verhalten von Standardfunktionen.  Das ist manchmal gar nicht so
schlecht.  Man kann simpel einen Sack voll Variablen jeweils mit
memcpy() kopieren, wenn diese aber klein genug sind und der Compiler
gerade Register frei hat, kann er stattdessen auch gleich die Kopie
selbst vornehmen.

Falls man C++ machen möchte, hat man eh' keine Wahl, dort ist
-ffreestanding nicht zulässig.

> Bei letzterer ist nicht festgelegt, wie main() auszusehen hat. Es
> ist nicht mal festgelegt, daß es die überhaupt geben muß.

Ja, wo fängt man dann eigentlich an. ;-)

Die avr-libc-Umgebung geht stets davon aus, dass ein main() gerufen
wird.

von Schebahunter (Gast)


Lesenswert?

Der avr-gcc will ein "int main(void)", sonst kommt eine Warnung.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Der avr-gcc will ein "int main(void)", sonst kommt eine Warnung.

Quark.  Erstens hättest du vor dieser Bemerkung ja mindestens mal
versuchen können, der Diskussion zwischen Rolf und mir zu folgen:

$ cat foo.c
#include <avr/io.h>
void main(void)
{
        DDRB = 0xff;
        for (;;)
                PORTB ^= 0xff;
}
$ avr-gcc -W -Wall -mmcu=atmega8 -ffreestanding -O -o foo.elf foo.c
$

(Keine Warnung.)

Zweitens geht auch im hosted mode immer "int main(int, char **)"
als
Prototyp (bzw. ein dazu äquivalenter).

von Dirk (Gast)


Lesenswert?

Hi,

muss das globale Intterruptflag bit nicht gesetzt werden mit sei(); ?

Gruß,

Dirk

von Matthias W. (Gast)


Lesenswert?

Hallo!
Hab es hinbekommen. Hatte es auch fast richtig, nur ich hab
rausgefunden das von dem 8-bit-Counter OCR1C den Wert angibt, bis zu
dem der Zähler zählt und OCR1A gibt an, wann der Ausgang umgeschaltet
wird! Darum muß OCR1C immer größer sein als OCR1A!
Mit eurer Hilfe hab ich mal wieder ein Problem gelöst bekommen!
Wird bestimmt nicht das Letzte sein...

Vielen Dank!

MFG
Matthias

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Das war genau das, was ich mit dem nochmaligen Blick ins Datenblatt
meinte.  Ist übrigens recht ungewöhnlich, die anderen AVRs handhaben
das anders, aber man wollte wohl mit wenigen IO-Registern viele
Features unterbringen hier.

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.