Forum: Mikrocontroller und Digitale Elektronik AVR PWM Pulsbreite ändern


von Christian (Gast)


Lesenswert?

Hallo zusammen,

ich bin grad an PWM dran, und möchte mit meinem ATmega88 ein Signal 
erzeugen (1kHz, verwendung von 16Bit Timer, ICR1 = 1024 da ich die 
Pulslänge über den 10Bit Wert einer ADWandlung ändern will).

Nur leider steh ich grad total auf der Leitung und deshalb meine Fragen:

1.Wie muss ich den Prescaler des Timers einstellen?

2.Wie mache ich es, dass ich die Pulsdauer ändere?
  (nicht invertierter Modus, Fast PWM 10Bit)
   Wäre dieser ansatz richtig, wenn ich den ADCWert in OCR1 übergebe.
   Natürlich erst wenn der Timer wieder auf 0 gesetzt wird.

Ich habe eine 16 Bit Variable für die ADC mit dem Namen ADC_Wert.

Wenn ich irgend einen Fehler gemacht hab, bitte Nachsicht, bin noch 
Anfänger.

von Christian (Gast)


Lesenswert?

Kann mir denn niemand helfen?

von m.n. (Gast)


Lesenswert?

Da Du es nicht abwarten kannst, such Dir etwas aus.
http://www.mino-elektronik.de/Generator/takte_impulse.htm

von Axel S. (a-za-z0-9)


Lesenswert?

Christian schrieb:
> Hallo zusammen,
>
> ich bin grad an PWM dran, und möchte mit meinem ATmega88 ein Signal
> erzeugen (1kHz, verwendung von 16Bit Timer, ICR1 = 1024 da ich die
> Pulslänge über den 10Bit Wert einer ADWandlung ändern will).

Schön. Hast du das AVR-Tutorial: PWM schon gelesen?

> 1.Wie muss ich den Prescaler des Timers einstellen?

So groß, daß die Überlauffrequenz des Timer die gewünschte PWM-Frequenz 
ergibt.

> 2.Wie mache ich es, dass ich die Pulsdauer ändere?

Indem du den gewünschten Wert ist das zur jeweiligen PWM-Betriebsart und 
dem gewünschten Ausgabepin passende OCR-Register schreibst.

>   (nicht invertierter Modus, Fast PWM 10Bit)
>    Wäre dieser ansatz richtig, wenn ich den ADCWert in OCR1 übergebe.
>    Natürlich erst wenn der Timer wieder auf 0 gesetzt wird.

Der ATmega88 hat bereits einen 10 Bit PWM-Modus. Bzw. genau genommen 
sogar zwei: Mode 3 und 7. Es gibt also keinen Grund, die Zählweiten- 
beschränkung per ICR1 manuell vorzunehmen. Auch um das zeitrichtige 
Update des Vergleichsregisters kümmert sich der ATmega88 selber.

Lies einfach mal das Datenblatt. Abschnitt 16.9.3 "Fast PWM Mode"


XL

von Christian (Gast)


Lesenswert?

Danke für die Antworten

Ich habe die PWM 10Bit über die WGM Register eingestellt. Das einstellen 
durch ICR1 ist also überflüssig. Daran hab ich nicht gedacht.

Das mit dem Prescaler versteh ich aber noch nicht?

Und wie mache ich das mit dem Wert des ADCs?

Wie gesagt ich bin noch Anfänger.

von Christian (Gast)


Lesenswert?

Bitte, brauche dringen Hilfe.

von Eumel (Gast)


Lesenswert?

Christian schrieb:
> Bitte, brauche dringen Hilfe.

Was ist denn deine Aufgabe? Wer das einfach so aus Spaß macht braucht 
nicht dringend Hilfe.

von Christian (Gast)


Lesenswert?

Ich bin eben sehr ungeduldig :)

Ich möchte eine LED dimmen mit einem Poti Basis.
Das ganze möchte ich dann ausbauen um einen Motor anzusteuern.

von tictactoe (Gast)


Lesenswert?

Weil ich nicht so bin und ich letzte Woche gerade mit was Ähnlichem 
rumexperimientiert habe, hier ein bisschen Code:
1
int main(void)
2
{
3
  /* Set as output: */
4
  DDRD |= _BV(PD6);  // OC0A pin
5
6
  TCCR0A = _BV(COM0A1)|  // non-inverting mode
7
    _BV(WGM01)|_BV(WGM00);  // FastPWM
8
  TCCR0B = _BV(CS00);  // enable Timer 0, no prescaler
9
  TIMSK0 = _BV(TOIE0);
10
  // ADC
11
  ADCSRA = _BV(ADEN)|
12
    _BV(ADPS1)|_BV(ADPS0);    // prescaler 8
13
  ADMUX = _BV(REFS0)|_BV(ADLAR)|3;  // ADC3
14
  DIDR0 = _BV(ADC3D);
15
16
  while (1) {
17
    // start AD conversion
18
    ADCSRA |= _BV(ADSC);
19
    // wait for completion
20
    while (ADCSRA & _BV(ADSC))
21
      ;
22
    OCR0A = ADCH;
23
  }
24
25
  return 0;
26
}
Aber Achtung: (1) Das ist für einen ATmega328P, und (2) ich brauche nur 
8 Bit PWM-Genauigkeit (daher Timer0, nicht Timer1) und nutze daher auch 
nur die höherwertigen 8 Bit der AD-Konvertierung, (3) der Atmel läuft 
mit 1MHz (Auslieferungszustand). Also: Umsetzung auf deine Anforderungen 
bitte selber machen mithilfe des Datenblattes.

von Axel S. (a-za-z0-9)


Lesenswert?

Christian schrieb:
> Das mit dem Prescaler versteh ich aber noch nicht?

Der Timer zählt mit jedem Impuls seiner Eingangsfrequenz um eins nach 
oben, bis 1023 (in einem 10-Bit PWM-Modus) und springt von da wieder auf 
0. Bei jedem Durchlauf wird 1 PWM-Impuls erzeugt. Die PWM-Frequenz ist 
also um den Faktor ..... kleiner (Wert bitte selber einsetzen) als die 
Eingangsfrequenz des Timers.

Wenn du nun eine bestimmte PWM-Frequenz willst, muß die Eingangsfrequenz 
des Timers um wieviel größer sein? Und um von der System-Taktfrequenz 
auf diesen gewünschen Wert zu kommen, brauchst du dann welchen 
Vorteiler?

> Und wie mache ich das mit dem Wert des ADCs?

Den ADC-Wert kannst du aus einem Register auslesen. Und den PWM-Wert 
mußt du in ein anderes Register schreiben. Also laß mal überlegen: wie 
könnte man das anfangen, den Wert aus dem ADC Register zu lesen und ins 
OCRx Register zu schreiben?

> Wie gesagt ich bin noch Anfänger.

Das ist doch prima. Desto mehr gibt es für dich zu lernen. Oh. Das 
AVR-Tutorial hat auch was über den ADC.


XL

: Bearbeitet durch User
von Christian (Gast)


Lesenswert?

Danke für die Antworten.

Ich habe bereits den Code für alle Funktionen geschrieben, ich wollte 
nur noch wissen wie ich den Prescaler wählen muss und wie ich den ADC 
Wert als PWM Sollwert einsetze.

von Christian (Gast)


Lesenswert?

Und die Tutorials habe ich auch teilweise gelesen.

von chris (Gast)


Lesenswert?

Datenblatt ATmega8 auf seite 200 steht...... dann weißt du auch wie der 
vorteiler zu wählen ist

von Christian (Gast)


Lesenswert?

Ich habe den Prescaler für den Timer gemeint.
Ich benutze den Atmega88
Liege ich richtig, wenn ich 1kHz PWM haben will und 8MHz CPUTakt habe 
nehme ich einen Prescaler von 8:
8MHz /1023 /8 = 977Hz

Oder bin ich da auf dem Holzweg?

von Christian (Gast)


Lesenswert?

Es handelt sich um den Timer1 im Fast PWM 10Bit modus

von spess53 (Gast)


Lesenswert?

Hi

>Liege ich richtig, wenn ich 1kHz PWM haben will und 8MHz CPUTakt habe
>nehme ich einen Prescaler von 8:
>8MHz /1023 /8 = 977Hz

>Oder bin ich da auf dem Holzweg?

Nein.

MfG Spess

von Christian (Gast)


Lesenswert?

Heißt das ich liege falsch oder ich bin nicht auf dem Holzweg?

Wenn ich falsch liege, könnte mir jemand ein Rechenbeispiel zu meinem 
Fall machen. Offensichtlich komme ich nicht von selbst drauf.

von spess53 (Gast)


Lesenswert?

Hi

Das Nein bezog sich auf:

>Oder bin ich da auf dem Holzweg?

MfG Spess

von chris (Gast)


Lesenswert?

Christian schrieb:
> 8MHz /1023 /8 = 977Hz

kleiner Fehler:

1024 statt 1023

der Timer zählt von 0 bis 1023 -> das sind 1024 Schritte

von sweetsuit (Gast)


Lesenswert?

Also ich bin der Meinung:

0 bis 1 = 1 Schritt
0 bis 2 = 2 Schritte
...
0 bis 1023 = 1023 Schritte

von spess53 (Gast)


Lesenswert?

Hi

>Also ich bin der Meinung:

>0 bis 1 = 1 Schritt
>0 bis 2 = 2 Schritte
>...
>0 bis 1023 = 1023 Schritte

Du hast den Schritt von 1023 nach 0 vergessen.

0 bis 0 = 1024 Schritte

MfG Spess

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.