Forum: Mikrocontroller und Digitale Elektronik Multichannel PWM bei Atmega128


von Gerhard H. (oderlachs)


Lesenswert?

Hallo Kenner des Fachs !

Ich weiss ich nerve, aber ich komme einfach nicht weiter, 2 Tage habe 
ich schon im Web und in den ATmel Chip Unterlagen recherchiert und 
probiert.
Ich bekomme einfach mit dem 16-Bit Timer 1 beim ATM128 kein PWM 
gebacken.

Ja es rächt sich die Arduinozeit, wo schon alles fast "Vorgebacken" ist.

Mein Ziel ist es 4 Motoren unabhängig von einander per PWM anzusteuern.
Mit dem Timer0 u.2 (8-Bit) bekomme ich es ja hin, aber ich brauche ja 4 
PWM Ausgänge .

Ich habe dafür  so ein LC-MCU-Board extra mit dem Atm128 gekauft ...

Es kann sein das ich die ganze Sache etwas dumm angegangen bin , bzw 
ganz falsch. Ich weiss es nicht wie ich es richtig angehen soll, da ich 
mit der Chip Doku auch nicht so ganz richtig zu Rande komme.

Ich möchte OC1A, OC1B, OC1C, und OC3A später nutzen .

Habe meinen Anfang mal in eine HTML Datei gelegt und sie hoch geladen:

http://oderlachs.de/forum/code/pwm128.html

Vielleicht sind meine Gedanken ja wirklich irre dazu ich wollte Testen 
ob ich die LEDs an den drei Ausgängen (PB5,PB6,PB7) unterschiedlich hell 
zu leuchten bekomme...
Die LEDs leuchten zwar aber keine Veränderungen machbar... :(

Vielleicht  findet sich ja ein netter Helfer, der mir mal unter die Arme 
hilft und mir einen Denkanstoss weiter gibt.

Gruss und Danke

Gerhard

von Gerhard H. (oderlachs)


Lesenswert?

Hier ist mein funktionierender 2 Port 8 Bit Timer PWM Code:

http://oderlachs.de/forum/code/8bit_pwm.html

Da funktioniert alles wunderbar, was da an dem 16 Bit Timern nicht 
funzt..ich weiss es nicht.

Gruss

Gerhard

von julius (Gast)


Lesenswert?

Was soll denn genau passieren und was passiert?
1
    TCCR1A |= (1<< WGM10);  //Fast PWM 8 Bit
2
    TCCR1B |= (1<< WGM12);   //Fast PWM 8 Bit
3
   
4
    OCR1AH = 0xFF;
5
    OCR1AL = 0xFF;
6
    _delay_ms(1000);
7
    OCR1BH = 0x7F;
8
    OCR1BL = 0xFF;
9
    _delay_ms(1000);
10
    OCR1CH = 0x00;
11
    OCR1CL = 0x00;
12
    _delay_ms(1000);
Im 8-Bit Timer 1 Mode macht nur OCR1xL beschreiben Sinn und würde 
Wirkung zeigen. OCR1A ohne L oder H versteht der Compiler auch und macht 
die Sache einfacher.

von Norbert S. (norberts)


Lesenswert?

Moin,

Mit dem Code ist A dauerhaft high, B dauerhaft high und C dauerhaft low 
(mit einem Spike high von einem Timertick).
Ändern tut sich da ja nix.
Und wie Julius schrieb, bei 8bit PWM geht Deine PWM nur von 0...255.

Gruß,
Norbert

von Gerhard H. (oderlachs)


Lesenswert?

Danke ,
soll das heissen das ich das hier falsch verstanden habe und nur bei den 
8 Bit Timern geht??

Dann muss ich sagen das ich nun da gar nicht mehr durchsehe was im 
Datenblatt steht...

Hätt denn nicht jemand ein Beispiel bitte, für eine 16-Bit-Timer PWM ?

Da würde ich vielleicht erkennen wo mein Fehler liegt. Ich denke schon 
das ich da was Grundlegend falsch mache...

Gerhard

von H.Joachim S. (crazyhorse)


Lesenswert?

Die entsprechenden Ports auch als Ausgänge geschaltet?

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
// Mode: Fast PWM top=0x00FF
// OC1A output: Non-Inverted PWM
// OC1B output: Non-Inverted PWM
// OC1C output: Non-Inverted PWM
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 0,032 ms
// Output Pulse(s):
// OC1A Period: 0,032 ms Width: 0 us
// OC1B Period: 0,032 ms Width: 0 us
// OC1C Period: 0,032 ms Width: 0 us
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | 
(1<<COM1C1) | (0<<COM1C0) | (0<<WGM11) | (1<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | 
(0<<CS11) | (1<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;

von Norbert S. (norberts)


Lesenswert?

H.Joachim S. schrieb:
> Die entsprechenden Ports auch als Ausgänge geschaltet?

Jo, hat er:
 // 3 PWM-Ports als Ausgang schalten
    DDRB |= (1<< PB5)|(1<<PB6)|(1<< PB7);

Er initialisiert genau wie Deine Vorlage.

Gruß,
Norbert

von julius (Gast)


Lesenswert?

Gerhard H. schrieb:
> Dann muss ich sagen das ich nun da gar nicht mehr durchsehe was im
> Datenblatt steht...
1
    TCCR1A |= (1<< WGM10);  //Fast PWM 8 Bit
2
    TCCR1B |= (1<< WGM12);   //Fast PWM 8 Bit

Im Datenblatt steht, daß obige Zeilen den 8-Bit Modus am 16-Bit Timer 
einstellen nämlich den Mode 5.

Wenn du PWM mit 16-Bit Auflösung haben möchtest, dann mußt du das 
entsprechend dem Datenblatt entnehmen und hinschreiben.

> Hätt denn nicht jemand ein Beispiel bitte, für eine 16-Bit-Timer PWM ?

Ich habe keins.

von Norbert S. (norberts)


Lesenswert?

Gerhard H. schrieb:
> Danke ,
> soll das heissen das ich das hier falsch verstanden habe und nur bei den
> 8 Bit Timern geht??
>
> Dann muss ich sagen das ich nun da gar nicht mehr durchsehe was im
> Datenblatt steht...
>
> Hätt denn nicht jemand ein Beispiel bitte, für eine 16-Bit-Timer PWM ?
>
> Da würde ich vielleicht erkennen wo mein Fehler liegt. Ich denke schon
> das ich da was Grundlegend falsch mache...
>
> Gerhard

Hey, Du stellst 8bit PWM ein, was erwartest Du?
Damit zählt er eben nur bis 255.
Fast PWM geht nicht mit 16bit.

Gruß,
Norbert

von H.Joachim S. (crazyhorse)


Lesenswert?

Ich habe mir das Programm nicht angeschaut, sondern einfach den 
Programmgenerator eingeschaltet :-) (hat bis jetzt aber zu 100% 
funktioniert)

Fast-PWM geht auch mit 16bit, top ICR1.

von julius (Gast)


Lesenswert?

Norbert S. schrieb:
> Fast PWM geht nicht mit 16bit.

und was ist mit Mode 14 und ins ICR1 0xFFFF geschrieben?

von Norbert S. (norberts)


Lesenswert?

H.Joachim S. schrieb:
> Fast-PWM geht auch mit 16bit, top ICR1.

Oh, natürlich.

Gerhard:
Guckst Du "Table 20-5 Waveform Generation Mode Bit Description", Seite 
163 im Datenblatt vom 128A.
Dort stehen alle Modi und wie Du die WGM-Bits setzen musst.

16 Bit Fast PWM wäre Mode 14, wenn Du ICR1 auf 0xFFFF setzt.

Edit: julius war schneller...

Gruß,
Norbert

: Bearbeitet durch User
von Gerhard H. (oderlachs)


Lesenswert?

Hallo Freunde !

Habt alle vielen herzlichen dank für Eure Mühen mit mir. Ich gebe ja zu 
das es auch das erste mal ist das ich da was mit mehreren PWM Ausgängen 
machen möchte. Nun ich behersche das english so gut wie gar nicht, nie 
gelernt habe. Darum sind die Datenblätter auch schwer zu lesen, aber es 
ist wirklich nur das mit der PWM  wo ich da nicht mit klar komme.

Nun habe ich wenigstens es soweit gebracht , um einen PWM Port zu 
gebrauchen.
Nur eben es geht nur der eine nicht aber die anderen beiden:
1
#ifndef F_CPU
2
#define F_CPU 8000000UL
3
#endif
4
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
#include <util/delay.h>
8
void pwm_init()
9
{   // Atmega128 16-Bit Counter1
10
  // 3 PWM-Ports als Ausgang schalten
11
     DDRB |= (1<< PB5)|(1<<PB6)|(1<< PB7);
12
     TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11);
13
     TCCR1B = (1<<WGM13)  | (1<<WGM12)  | (1<<CS10);
14
     
15
     ICR1 = 0xFFFF;
16
}  
17
18
19
int main()
20
{  pwm_init();
21
  
22
  while(1){
23
  OCR1A = 0x00ff;  // PB5  aendert sich Helligkeit mit Hexwert
24
  OCR1B = 0x00ff;  // PB6  keine Aenderung !! voll hell
25
  OCR1C = 0x000f;  // PB7  Keine Aenderung !! voll hell
26
}
27
  return 0;
28
}

Mir brummt auch heute schon der Schädel da habe ich nicht mehr solche 
Auffassungsgabe...

Morgen mehr..

Nochmals Vielen Dank Euch allen !!!!

Gerhard

von Norbert S. (norberts)


Lesenswert?

Moin,

Jetzt noch COM1Bx und COM1Cx jeweils setzen und alles wird gut ;-)

Gruß,
Norbert

von julius (Gast)


Lesenswert?

Gerhard H. schrieb:
> Nur eben es geht nur der eine nicht aber die anderen beiden:
>
1
>      TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11);
2
> 
3
>   OCR1A = 0x00ff;  // PB5  aendert sich Helligkeit mit Hexwert
4
>   OCR1B = 0x00ff;  // PB6  keine Aenderung !! voll hell
5
>   OCR1C = 0x000f;  // PB7  Keine Aenderung !! voll hell
6
>

Must auch die anderen COM1xy Bits setzen um die Compareausgänge auf auf 
PB6 und PB7 durchzuschalten.

von Norbert S. (norberts)


Lesenswert?

julius schrieb:
> Gerhard H. schrieb:
>> Nur eben es geht nur der eine nicht aber die anderen beiden:
>>
1
>>      TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11);
2
>>
3
>>   OCR1A = 0x00ff;  // PB5  aendert sich Helligkeit mit Hexwert
4
>>   OCR1B = 0x00ff;  // PB6  keine Aenderung !! voll hell
5
>>   OCR1C = 0x000f;  // PB7  Keine Aenderung !! voll hell
6
>>
>
> Must auch die anderen COM1xy Bits setzen um die Compareausgänge auf auf
> PB6 und PB7 durchzuschalten.

Ätsch, diesmal war ich schneller ;-)

Gruß,
Norbert

von julius (Gast)


Lesenswert?

Norbert S. schrieb:
> Ätsch, diesmal war ich schneller ;-)

Vadammt. Wieviel Sekunden? :-)

von Gerhard H. (oderlachs)


Lesenswert?

Daaaaanke !!!

Super Leute es geht jetzt !!!!

Ja wie gesagt das war ein typisches Fallstrick für einen Einsteiger auf 
dieser Ebene...Hatte ja sonst nur mal mit einem oder zwei PWM Ports 
gearbeitet....

Es hat mich wirklich sehr gefreut, hier soviel Unterstützung zu 
erfahren.

Gerhard

: Bearbeitet durch User
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.