Hallo Leute,
ich versuche schon seit einiger Zeit eine SW-PWM mit einem Attiny2313 zu
erzeugen.
Ich möchte damit RGB-Leds ansteuern. Leider hat dieser Mc nur zwei
16-Bit-Timer, wesshalb ich das ganze in Software umsetzen möchte. Ich
denke aber, dass ich bei der Initialisierung einen Fehler gemacht habe.
Sobald ich die Zeile "init_pwm();" hinzufüge, werden die Variablen in
der main-Funktion nicht mehr initialisiert ( egal ob volantile oder
nicht).
Ich kann einfach den Fehler nicht finden.
Könnt ihr mir dabei bitte helfen?
hier noch der gesammte Code
1
/*
2
ATtiny2313 @ 8 MHz
3
*/
4
5
// Defines an den Controller und die Anwendung anpassen
6
7
//#define F_CPU 8000000L // Systemtakt in Hz
8
9
#define PWM_STEPS 1024 // PWM-Schritte pro Zyklus(1..256)
10
#define PWM_PORT PORTB // Port für PWM
11
#define PWM_DDR DDRB // Datenrichtungsregister für PWM
12
13
// includes
14
15
#include<stdint.h>
16
#include<string.h>
17
#include<avr/io.h>
18
#include<avr/interrupt.h>
19
#include<avr/wdt.h>
20
21
// globale Variablen
22
23
volatileuint16_tpwm_setting[3];// Einstellungen für die einzelnen PWM-Kanäle
24
volatileuint16_tpwm_R=0;// Einstellungen für die einzelnen PWM-Kanäle
Hallo Karl,
PWM_STEPS ist ganz oben definiert mit 1024 ( 10 Bit)
wenn pwm_cnt (wird bei jedem Aufruf der ISR um eins hochgezählt) =
PWM_STEPS (1024), also bei "Überlauf"->pwm_cnt=0
Christian S. schrieb:> ich versuche schon seit einiger Zeit eine SW-PWM mit einem Attiny2313 zu> erzeugen.> Ich möchte damit RGB-Leds ansteuern. Leider hat dieser Mc nur zwei> 16-Bit-Timer
Hat er nicht. Er hat nur einen 16Bit-Timer. Allerdings besitzt dieser
zwei PWM-Kanäle...
> wesshalb ich das ganze in Software umsetzen möchte.
Das ist ein sinnvoller Ausweg.
> Ich kann einfach den Fehler nicht finden.
Vielleicht einfach mal den Simulator benutzen?
mmhhh mit dem Ty2313 schafft man es zumindest alle 3 farben einer RGB
Led anzusteuern mit Timer2 = 1x8bit Kanal und Timer 1 = 2x16Bit Kanäle.
Wenn du noch verrätst wie du die LED's ansteuern willst könnte man
weiter helfen
c-hater schrieb:>> ich versuche schon seit einiger Zeit eine SW-PWM mit einem Attiny2313 zu>> erzeugen.>> Ich möchte damit RGB-Leds ansteuern. Leider hat dieser Mc nur zwei>> 16-Bit-Timer>> Hat er nicht. Er hat nur einen 16Bit-Timer. Allerdings besitzt dieser> zwei PWM-Kanäle...
Stimmt, mein Fehler, aber das ist genau das, was ich meinte,
mir geht ein dritter 16-Bit-pwm-Kanal ab.
>> wesshalb ich das ganze in Software umsetzen möchte.>> Das ist ein sinnvoller Ausweg.
Da sonst nicht viel laufen sollte und ich ein paar von den Controllern
rumliegen habe, denk ich, passt das schon
>> Ich kann einfach den Fehler nicht finden.>> Vielleicht einfach mal den Simulator benutzen?
Ja, ich habe den Protheus Professional 8 noch verwendet...Hab aber
leider keine weiteren Erkenntnisse rausgefunden, ausser dass eben, wenn
ich den Interrupt aktiviere, die Variablen in der main nicht
initialisieren kann (siehe Bild vom ersten Beitrag).
chris schrieb:> mmhhh mit dem Ty2313 schafft man es zumindest alle 3 farben einer RGB> Led anzusteuern mit Timer2 = 1x8bit Kanal und Timer 1 = 2x16Bit Kanäle.> Wenn du noch verrätst wie du die LED's ansteuern willst könnte man> weiter helfen
Ja genau, aber 8 Bit sind etwas zu wenig...( ergibt max 255 Abstufungen
und das ergibt eine nicht so schöne Abstufung)
Hab zum Ansteuern BC547 (oder so) Transistoren, jeweils für eine Farbe)
verwendet.
Also der Mc wird nicht damit belastet.
Die Ansteuerung läuft in der Realität. Das hab ich schon getestet.
Mein Problem ist, dass wenn ich die PWM initialisieren möchte, keine
Variablen mehr beschrieben werden.
Leider kann ich mir keinen Reim daraus machen, wieso das so ist.
Christian S. schrieb:> Ja genau, aber 8 Bit sind etwas zu wenig...( ergibt max 255 Abstufungen> und das ergibt eine nicht so schöne Abstufung)
HÄääää aber habe selber was mit RGBs vor kurzem gebaut und mit 8bit
kommste schon recht weit. Die Frage ist welche Grundfrequenz du zu
Grunde legst ? Mir fiel mir auf das man die Abstufung deutlicher wahr
nimmt wenn man die Grundfrequenz unter einen bestimmten Wert hat/nimmt.
Zusätzlich musst du beachten das ab einer gewissen Abstufung das Auge
keine Farbänderung mehr wahr nimmt. ;)
> Hab zum Ansteuern BC547 (oder so) Transistoren, jeweils für eine Farbe)> verwendet.
Wie lautet der Name deiner RGB LED?
> Die Ansteuerung läuft in der Realität. Das hab ich schon getestet.
gut
> Mein Problem ist, dass wenn ich die PWM initialisieren möchte, keine> Variablen mehr beschrieben werden.
Moment, von welcher Variablen reden wir die im SRAM angelegt sind oder
die OCRxy Register ???
Damit OCRxy kann zu jeder Zeit beschrieben werden aber wann der Wert
wirklich als Referenz genutzt wird hängt vom Timermode ab.
Komme vom ASM aber
> uint16_t vglB = 78; //Vergleichswert A> OCR1AH = (vglB>>8);> OCR1AL = (vglB & 0x00FF);
Warum Vergleich von 78 im OCR1AH ? Bzw was macht diese Sache hier ?
Sollte der Vergleich nicht auf dem OCR1AL passieren ??
Christian S. schrieb:> PWM_DDR = 0xFF; // Port als Ausgang für PWM> //init_pwm();
Tut nicht notwendig weil der MOde die volle Funktion der/des Pins
übernimmt.
chris schrieb:> Christian S. schrieb:>> Ja genau, aber 8 Bit sind etwas zu wenig...( ergibt max 255 Abstufungen>> und das ergibt eine nicht so schöne Abstufung)>> HÄääää aber habe selber was mit RGBs vor kurzem gebaut und mit 8bit> kommste schon recht weit. Die Frage ist welche Grundfrequenz du zu> Grunde legst ? Mir fiel mir auf das man die Abstufung deutlicher wahr> nimmt wenn man die Grundfrequenz unter einen bestimmten Wert hat/nimmt.> Zusätzlich musst du beachten das ab einer gewissen Abstufung das Auge> keine Farbänderung mehr wahr nimmt. ;)
Ja, du hast zum Teil recht.
Die Farbänderung wird wohl nicht so wahrgenommen, aber die Helligkeit
schon.
Es wirkt ruhiger, wenn die Zeit einer kompletten PWM langsammer ist. Da
die Helligkeit einer LED aber eine logarithmischen Funktion beschreibt,
ist es von Vorteil, die Abstufung größer zu machen (für den Bereich nahe
um 0 [die 16-Bit-PWM kann mit einer Auflösung von 10-Bit -> 1024
betrieben werden]).
>> Hab zum Ansteuern BC547 (oder so) Transistoren, jeweils für eine Farbe)>> verwendet.>> Wie lautet der Name deiner RGB LED?
Weiß ich nicht genau, es ist eine kleine LED-Leiste von M3. Es besas
eine
Steuerung für mehrere Farben und wurde am USB-Port betrieben.
>> Die Ansteuerung läuft in der Realität. Das hab ich schon getestet.>> gut>>> Mein Problem ist, dass wenn ich die PWM initialisieren möchte, keine>> Variablen mehr beschrieben werden.>> Moment, von welcher Variablen reden wir die im SRAM angelegt sind oder> die OCRxy Register ???
Es geht um alle Variablen im SRAM (aufgefallen ist es mir bei i, j und
volatile uint16_t pwm_setting[3]; // Einstellungen
für die einzelnen PWM-Kanäle)
> Damit OCRxy kann zu jeder Zeit beschrieben werden aber wann der Wert> wirklich als Referenz genutzt wird hängt vom Timermode ab.
Ja, weiß ich.
> Komme vom ASM aber>>> uint16_t vglB = 78; //Vergleichswert A>> OCR1AH = (vglB>>8);>> OCR1AL = (vglB & 0x00FF);>> Warum Vergleich von 78 im OCR1AH ? Bzw was macht diese Sache hier ?> Sollte der Vergleich nicht auf dem OCR1AL passieren ??
Ja, du hast recht.
Hierbei handelt es sich aber nicht um einen Vergleich.
Zur Erklährung: Zuerst wird eine 2x8Bit-Variable geschrieben (vglB)
in der nächsten Zeile wird vglB um 8 Positionen nach rechts geshiftet
und an OCR1AH.
In der letzten Zeile werden die unteren 8 Bit von vglB an OCR1AL
übergeben.
> Christian S. schrieb:>> PWM_DDR = 0xFF; // Port als Ausgang für PWM>> //init_pwm();>> Tut nicht notwendig weil der MOde die volle Funktion der/des Pins> übernimmt.
Ja, aber ich muss doch die jeweiligen Pins als Ausgang setzen?!?.
Christian S. schrieb:> wenn pwm_cnt (wird bei jedem Aufruf der ISR um eins hochgezählt) => PWM_STEPS (1024), also bei "Überlauf"->pwm_cnt=0
Und wie, bitte, soll pwm_cnt bis 1024 zählen? pwm_cnd ist als "uint8_t"
deklariert, geht nur bis 255.
Thomas E. schrieb:> Christian S. schrieb:>> wenn pwm_cnt (wird bei jedem Aufruf der ISR um eins hochgezählt) =>> PWM_STEPS (1024), also bei "Überlauf"->pwm_cnt=0>> Und wie, bitte, soll pwm_cnt bis 1024 zählen? pwm_cnd ist als "uint8_t"> deklariert, geht nur bis 255.
Ja, stimmt.
Mein Fehler :-| kommt wohl vom ewigen ändern/testen. Werd in ändern.
Hallo Christian,
Christian S. schrieb:> PWM_STEPS ist ganz oben definiert mit 1024 ( 10 Bit)> wenn pwm_cnt (wird bei jedem Aufruf der ISR um eins hochgezählt) => PWM_STEPS (1024), also bei "Überlauf"->pwm_cnt=0> Und wie, bitte, soll pwm_cnt bis 1024 zählen? pwm_cnd ist als "uint8_t"> deklariert, geht nur bis 255.
Darin begründet lang auch mein indirekte Frage, somit ist dies nun
geklärt.
Christian S. schrieb:>> Christian S. schrieb:>>> PWM_DDR = 0xFF; // Port als Ausgang für PWM>>> //init_pwm();>>>> Tut nicht notwendig weil der MOde die volle Funktion der/des Pins>> übernimmt.>> Ja, aber ich muss doch die jeweiligen Pins als Ausgang setzen?!?.
NEIN das ist es ja. Das ist mit der Übergabe auf die Zweit/Dritt/Nx
Funktion des Pins Geschichte. Diese Funktion übernimmt die komplette
Steuerung des Pins bis du wieder auf die Normalfunktion des Pin zurück
schaltest. Ausser es ist explizit erwähnt das man händisch in diese
erweiterte Pinfunktion eingreifen kann/muss.
> Weiß ich nicht genau, es ist eine kleine LED-Leiste von M3.
naja zumindest solltest mal in die Daten gucken wieviel Strom die Dinger
bräuchten damit du den Transistor nicht überlastest.
> Die Farbänderung wird wohl nicht so wahrgenommen, aber die Helligkeit> schon.
Die Farbänderung ist doch das Produkt der einzelnen RGB's-LED in ihrer
Helligkeit. Also hört die Wahrnehmung doch dann auf wenn auch der
Bereich erreicht ist, in der die Helligkeit einer Einzelnen nicht mehr
wahrgenommen wird.
> Es geht um alle Variablen im SRAM (aufgefallen ist es mir bei i, j und> volatile uint16_t pwm_setting[3]; // Einstellungen> für die einzelnen PWM-Kanäle)
Da bin ich leider raus Hochsprache ist nicht mein Ding aber aus der
Erfahrung würde ich mich dem was Thomas Elger schrieb anschließen und es
noch erweitern. Heißt das man entweder die falsche Variable hat oder man
schreibt in die richtige Variable nur deren Wirkung hat keine Effekt
weil man sie nicht abruft oder deren Inhalt für die Funktion zu groß ist
weil die Schleife begrenzt (0-5 = Schleife; Variable = 90).
Hi Chris,
wie schon geschrieben, funktioniert alles, ausser dass ich eben die
Variablen der main im SRAM nicht deklarieren kann, wenn ich den Timer
setze.
Hab aber nochmal getestet, wenn ich in die main
1
pwm_setting[0]=10;
2
pwm_setting[1]=0;
3
pwm_setting[2]=0;
schreibe, so funktioniert es.
Was nicht geht, ist z.B.:
1
pwm_setting[0]=i;
da i dann nicht deklariert werden kann. (Warum auch immer)
Ich versteh nicht, was ich beim initialisieren, oder sonst wo falsch
mache.
Hi Leute.
hatte leider die letzte Zeit keine Zeit für dieses Projekt.
Bin nun draufgekommen, dass sich das Array "pwm_setting[]; " nicht mit
den Werten aus einem anderen Array beschreiben ließ (warum auch
immer...) und habe dieses durch drei einzelne Variablen erseetzt. Das
zweite Array war leider recht groß und überschritt den restlichen
Speicher (hab ich erst später bemerkt :-| ). Ausserdem wurde die ISR zu
oft aufgerufen, wesshalb die main zu selten bearbeitet wurde. Nun läuft
aber alles, so wie es soll :-).