Ich habe ine kleines versändniss problem mit der bedienung der PWM
kanäle
Dieses beispiel war im tutorial drin
1
DDRD=(1<<PD5);//ATMega16
2
//
3
// Timer 1 einstellen
4
//
5
// Modus 14:
6
// Fast PWM, Top von ICR1
7
//
8
// WGM13 WGM12 WGM11 WGM10
9
// 1 1 1 0
10
//
11
// Timer Vorteiler: 1
12
// CS12 CS11 CS10
13
// 0 0 1
14
//
15
// Steuerung des Ausgangsport: Set at BOTTOM, Clear at match
16
// COM1A1 COM1A0
17
// 1 0
18
19
TCCR1A=(1<<COM1A1)|(1<<WGM11);
20
TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS10);
21
22
//
23
// den Endwert (TOP) für den Zähler setzen
24
// der Zähler zählt bis zu diesem Wert
25
26
ICR1=0x6FFF;
27
28
//
29
// der Compare Wert
30
// Wenn der Zähler diesen Wert erreicht, wird mit
31
// obiger Konfiguration der OC1A Ausgang abgeschaltet
32
// Sobald der Zähler wieder bei 0 startet, wird der
33
// Ausgang wieder auf 1 gesetzt
34
//
35
// Durch Verändern dieses Wertes, werden die unterschiedlichen
36
// PWM Werte eingestellt.
37
38
OCR1A=0x3FFF;
Wen ich jetzt eine funktion schreiben wo ich ein wert zwischen 0 und
1023 angebe und der mir dann ein verhältniss ovn on/off liefert was
diesem wert prozentuell entspricht also 0 ist 0% und 1023 ist 100%
Da müste ich nur dafür sorgen das ICR1 zu OCR1A diesem berhältniss
entspricht, verstehe ich das richtig?
also das obige beispiel wäre 50%
beide auf 0x6FFF wäre 0%
und das obere auf 0x6FFF udn das untere auf 0 wären 100% ???
Wieso wird auch TCCR1B gesetzt ist das nicht füpr einen anderen kanal?
Was ich brauche ist eine funktion wo ich den kanal eines atmega 644 und
das on/off verhältniss angebe und die das dan umsetzt, gibts da was
fertiges?
Trax Xavier wrote:
> Da müste ich nur dafür sorgen das ICR1 zu OCR1A diesem berhältniss> entspricht, verstehe ich das richtig?
Richtig.
> also das obige beispiel wäre 50%
Nicht ganz 0x3FFF ist nicht die Hälfte von 0x6FFF
> beide auf 0x6FFF wäre 0%
eher 100%.
Das hängt ja davon ab, ob der Pin bei einem Timerwert von 0 auf 0 oder
auf 1 gesetzt wird. Dafür zuständig ist das COM1A1 Flag.
> und das obere auf 0x6FFF udn das untere auf 0 wären 100% ???
Welches obere? Bitte benutze die Ausdrücke, so wie sie im Tutorial oder
im Datenblatt benutzt werden und erfinde nicht deine eigene Sprache.
> Wieso wird auch TCCR1B gesetzt ist das nicht füpr einen anderen kanal?
Nein.
In Blick ins Datenblatt hätte dir verraten, dass einige der
Konfigurationsbits im TCCR1A und einige im TCCR1B sind. Erst alle
Konfigurationsbits zusammen (also die in TCCR1A und die in TCCR1B)
bestimmen was der Timer macht.
> Was ich brauche ist eine funktion wo ich den kanal eines atmega 644 und> das on/off verhältniss angebe und die das dan umsetzt, gibts da was> fertiges?
Ah geh. Du wirst doch wohl einen simplen Dreisatz hinkriegen.
(0x6FFF sind dezimal 28671)
100% sind 28671
34% sind x
_________________
x = .........
simples Prozentrechnen halt.
ICR1 lässt du auf 0x6FFF und OCR1A kriegt den errechneten Wert.
Was michverblüfft: Wenn du verstanden hast, wie so ein Timer
funktioniert und wie da eine PWM daraus erzeugt wird, dann hast du ja eh
nur ein einziges Register in dem du Werte verändern kannst um das
Verhältnis einzustellen. Warum probierst du das nicht einfach aus? Das
ist in 3 Minuten erledigt! Statt dessen wartest du 19(!) Stunden lang
auf eine Antwort.
Trax Xavier wrote:
> Wen ich jetzt eine funktion schreiben wo ich ein wert zwischen 0 und> 1023 angebe und der mir dann ein verhältniss ovn on/off liefert was> diesem wert prozentuell entspricht also 0 ist 0% und 1023 ist 100%>> Da müste ich nur dafür sorgen das ICR1 zu OCR1A diesem berhältniss> entspricht, verstehe ich das richtig?
Möglicherweise verstehst Du selber nicht, was Du hier geschrieben
hast...
> also das obige beispiel wäre 50%> beide auf 0x6FFF wäre 0%
Nö, mit Deiner Einstellung (set at bottom, clear on compare) sind das
100 %.
> und das obere auf 0x6FFF udn das untere auf 0 wären 100% ???
Wer ist "das obere" und "das untere"? Haben die auch Namen?
> Wieso wird auch TCCR1B gesetzt ist das nicht füpr einen anderen kanal?
Bitte schau Dir die Bits in den TCCRs an und überlege, was die für eine
Bedeutung haben und ob das irgendwas mit den einzelnen Compare-Kanälen
zu tun hat. Überlege v.a., was passiert, wenn die CS-Bits in TCCR1B
nicht setzt...
Hast Du jemals einen Blick ins AVR-GCC-Tutorial geworfen? Da steht
eigentlich alles drin...
Es macht auch Sinn, sich bei solchen Sachen entweder für die
Hexadezimal- oder für die Dezimaldarstellung zu entscheiden. Beides
durcheinander verwirrt vermutlich v.a. Dich. Und gerade bei Dingen, wo
es um Prozent und Ähnliches geht, ist die Dezimaldarstellung oft
sinnvoller...
> Hast Du jemals einen Blick ins AVR-GCC-Tutorial geworfen?
Jo das code sample aus meinem ersten post stammt ja da her ;)
leider fand ich das ganze eher verwirrent da nihct für alle register
geschrieben steht was die machen.
Also es gibt 1 Timer der alle 6 PWM Kanäle der Atmega644 versorgt der
mit
TCCR1A, TCCR1B ,ICR1 bedient wird,
und für die einzelnen Kanäle gibt es OC0A OC0B OC1A OC1B OS2A OC2B,
also das PWM für ein Kanal wird dadurch aktiviert das der wert da > 0
ist, also ums auszuschalten muss ichs einfach wieder auf 0 setzen, oki,
soweit sogut. oder?
Was machen die bits WGM13 und WGM12 steht im tutorial nicht drin
Also noch was ich jetzt machen werde:
beim start des programms den Timer initialisieren:
TCCR1A = (1<<WGM11) | (1<<WGM10) | (1<<COM1A1); // 10 bi nihct
invertiert
TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10); // ?? ??, Clock divider 1
ICR1 = 0x6FFF; // bis zu diesem wert zählt der timer die ticks der CPu
und dan wieder runter
Dan für jeden kanal wen ich ihn einstellen will
OCRxy = n*0x1C (für n=0 ist alles 0 und de pin ist aus und nciht im PWM
modus, oder? für n=0x3FF also 1023 ist der wert 0x6FFF und der pin ist
an und auf 100%, für n=0xFF also ~25% ist der wert 0x1BE4)
Ist das soweit alles korrent?
1
uint8_tPWMon=0;
2
voidInitPWM()
3
{
4
//
5
// Timer 1 einstellen
6
//
7
// Modus 14:
8
// Fast PWM, Top von ICR1
9
//
10
// WGM13 WGM12 WGM11 WGM10
11
// 1 1 1 1
12
//
13
// Timer Vorteiler: 1
14
// CS12 CS11 CS10
15
// 0 0 1
16
//
17
// Steuerung des Ausgangsport: Set at BOTTOM, Clear at match
18
// COM1A1 COM1A0
19
// 1 0
20
21
TCCR1A=(1<<WGM11)|(1<<WGM10)|(1<<COM1A1);
22
TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS10);
23
24
//
25
// den Endwert (TOP) für den Zähler setzen
26
// der Zähler zählt bis zu diesem Wert
27
28
ICR1=0x6FFF;
29
30
PWMon=1;
31
}
32
33
voidSetVal(intPort,uint16_tVal)
34
{
35
if(PWMon==0)
36
InitPWM();
37
38
if(!(*g_Gpio[Port].pDdr>>g_Gpio[Port].nBit)&1)
39
*(g_Gpio[Port].pDdr)|=(1<<g_Gpio[Port].nBit);
40
41
// der Compare Wert
42
// Wenn der Zähler diesen Wert erreicht, wird mit
43
// obiger Konfiguration der OC1A Ausgang abgeschaltet
44
// Sobald der Zähler wieder bei 0 startet, wird der
45
// Ausgang wieder auf 1 gesetzt
46
//
47
// Durch Verändern dieses Wertes, werden die unterschiedlichen
Trax Xavier wrote:
>> Was machen die bits WGM13 und WGM12 steht im tutorial nicht drin
Schau ins Datenblatt. Das Tutorial ist nur ein Auszug des Datenblatts.
(Sonst könnten wir ja gleich das Datenblatt als Tutorial hier
reinstellen).
Für Details, die du im Tutorial nicht findest, ist IMMER das Datenblatt
deine nächste Anlaufstelle. Es schadet auch nichts, das im Tutorial
gelesene mit dem Datenblatt kreuzzuvergleichen. Im Laufe der Zeit wird
sich das dann umdrehen. Deine erste Informationsquelle wird das
Datenblatt und wenn du dort was nicht verstehst, schaust du im Tutorial
nach, ob hier vielleicht jemand eine nähere Erläuterung geschrieben hat.
Bist du irgendwann das Tutorial nicht mehr brauchst und nur noch mit dem
Datenblatt arbeitest.
Aber egal worum es geht: Es ist immer das Datenblatt, welches
Gesetzeskraft hat. Es und nur es gilt. Wenn sich Datenblatt und Tutorial
widersprechen, gilt das Datenblatt. Wenn was im Tuorial steht, was so
nicht im Datenblatt steht, gilt das Datenblatt. Wenn im Tutorial etwas
nicht steht was im Datenblatt steht, gilt das Datenblatt.
> OCRxy = n*0x1C (für n=0 ist alles 0 und de pin ist aus und nciht im PWM> modus, oder?
Ob der Pin im PWM Modus ist oder nicht, entscheidet doch nicht das
Puls/Pause Verhältnis. Natürlich ist der Pin weiterhin im PWM Modus. Er
ist halt nur dauern Low (oder dauern High)
> Ist das soweit alles korrent?
Schon wieder einer, der Unmengen an Code schreibt, ohne kleinere
Codeteile auch nur ein einziges mal getestet zu haben.
Häng eine Led an einen der PWM Pins an und weise dem zugehörigen OCR
Register einfach mal ein paar verschiedene Werte zu. Dann weist du obs
nicht funktioniert oder aber, wenn die Led reagiert, dass du so daneben
nicht liegen wirst.
Und das beste daran: Es geht schneller als hier die Frage einzutippen
und macht auch noch Spass.
Trax Xavier wrote:
> Also es gibt 1 Timer der alle 6 PWM Kanäle der Atmega644 versorgt
Nein! Es gibt drei Timer, von denen jeder zwei PWM-Kanäle hat!
> TCCR1A, TCCR1B ,ICR1 bedient wird,
Das ist Timer 1! Der hat zwei PWM-Ausgänge.
> und für die einzelnen Kanäle gibt es OC0A OC0B OC1A OC1B OS2A OC2B,
OC heißt Output Compare. Dann kommt die Nummer des Timers. Und dann der
Buchstabe, der den Kanal bezeichnet. OC0A und OC0B gehören also zu Timer
0, OC1A und B zu Timer 1 usw. Zu jeder Compare-Einheit (also zu jedem
OCnx-Pin) gehört ein Compare-Register, in das der jeweilige
Vergleichswert reinkommt.
> also das PWM für ein Kanal wird dadurch aktiviert das der wert da > 0> ist, also ums auszuschalten muss ichs einfach wieder auf 0 setzen, oki,> soweit sogut. oder?
Bitte arbeite an Deiner Formulierung! Das versteht keiner, vielleicht
nicht mal Du selbst!
> Was machen die bits WGM13 und WGM12 steht im tutorial nicht drin
Aber im Datenblatt. Das Tutorial bezieht sich ja auch auf einen ATMega8.
Den Rest hat Karl heinz ja schon weitgehend erläutert...
Noch ne frage zur Sicherheit, sie ports sind den timern fest
zugeschrieben, oder? also man könnte nicht zB PD5 und PD4 mit timer 0
anstelle von timer 1 berteiben, doer?
#include <avr/io.h>
int main(){
unsigned int x;
TCCR1A = (1<<COM1A1) | (1<<WGM11);
TCCR1B = (1<<WGM13) | (0<<WGM12) | (1<<CS10) |(1<<CS11);
//Phase Correct Prescaler 8
ICR1 = 1000;
while(1)
//Ad Wandler liefert den Wert x
OCR1A = x;
}
Meine frage ist.Mein Atmega16 befindet sich im STK500.Ich benutze den
Software generierten Takt.Ich habe den Clock generator im AVRStudio auf
3,686000 Mhz eigenstellt.
Heisst das also mein Pwm frequnz:
Fpwm = F_clock/2.N.TOP (TOP wird dann ICR1)
Am Ausgang soll denn 230 Hz anliegen oder?