mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMega16 Fast PWM


Autor: Michael K. (mmike)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,
Ich arbeit mit einem ATMega16 und will den Timer1 im FastPWM betreiben. 
Ich habs auch schon mit simulieren probiert, aber leider ohne Erfolg. 
Die Init Funktion sieht folgendermassen aus:

void EnableServoTestTimer ()
{
  // External crystal 16 MHz, Prescaler 8
  // Enable fast PWM mode 14 (table 47 page 113 ATMega16 Doc):
  TCCR1A    = (1 << COM1A1) |(1 << WGM11);
  // Set prescaler 8
  TCCR1B    = (1 << CS11) | (1 << WGM13) | (1 << WGM12);
  // Set PWM
  ICR1     = (uint16_t)40000;
  OCR1A    = (uint16_t)3000; // min: 1800, neu.: 3000 max: 4200
}

Der Port PD5 ist als Ausgang geschaltet und wenn ich per "Hand" den Pin 
PD5 toggle, dann funzt es auch wunderbar. Nur wenn ich die Funktion zum 
initialisieren verwende, dann tut sich am Scope leider gar nichts.

Vielleicht sieht jemand den Fehler ....

Grüße,
Michael

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der (richtige) Pin ist auf Ausgang geschaltet?
 Probier mal:
> ICR1     = 40000U; // U fuer unsigned weil >32767,
                     // und/oder L fuer Long/32Bit
statt
> ICR1     = (uint16_t)40000;

hth. Jörg

Autor: Michael K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg,
danke für die schnelle Antwort! Der Pin ist definitiv auf Ausgang (wie 
geschrieben) und Pin toggeln funktioniert auch wunderbar. Dein Vorschlag 
mit dem U bzw. L brachte leider auch keine Abhilfe ... gecast'ed wird ja 
eigentlich ....
Vielleicht noch andere Ideen ?
Grüße,
Michael

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Vielleicht noch andere Ideen ?
Ich sag's mal so: An dem Programm, das du bisher gepostet hast liegt's 
höchstwahrscheinlich nicht ;) (ich kann's nur simulieren, wobei die 
Timer nun mal nicht gehen).

Also: poste mehr Code!
und kürz den Code auf ein Minimum (so ungefähr):
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
void EnableServoTestTimer(void);

int main(void)
{
  DDRD |= (1<<DDD5);
  EnableServoTestTimer();
  
  while(1)
    ;
  return 0;
}


void EnableServoTestTimer ()
{
  // External crystal 16 MHz, Prescaler 8
  // Enable fast PWM mode 14 (table 47 page 113 ATMega16 Doc):
  TCCR1A    = (1 << COM1A1) |(1 << WGM11);
  // Set prescaler 8
  TCCR1B    = (1 << CS10) | (1 << WGM13) | (1 << WGM12);
  // Set PWM
  ICR1     = 100;
  OCR1A    = 50; // min: 1800, neu.: 3000 max: 4200
}

hth. Jörg

Autor: Michael K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg,

ziemlich genau so sieht mein Code auch aus:

// Standard includes
#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>

/*********************************************************************** 
*************************************/
void EnableServoTestTimer ()
{
  // Enable fast PWM mode 14 (table 47 page 113 ATMega16 Doc):
  TCCR1A    = (1 << COM1A1) |(1 << WGM11);
  // Set prescaler 8
  TCCR1B    = (1 << CS11) | (1 << WGM13) |(1 << WGM12);
  // Set PWM
  ICR1     = (uint16_t)40000;
  OCR1A    = (uint16_t)ServoPosition;      // min: 1800, neutral: 3000 
max: 4200
}


/*********************************************************************** 
*************************************/
void DisableServoTestTimer ()
{
  TCCR1A    = 0;
  TCCR1B    = 0;
}


/*********************************************************************** 
*************************************/
// Main loop
/*********************************************************************** 
*************************************/
int main ()
{
  // Port Delta
  DDRD   =     (1 << PD5);      // Output Servo Test

  EnableServoTestTimer ();

  // Init sleep mode
  set_sleep_mode (SLEEP_MODE_IDLE);  //SLEEP_POWER_SAVE

  // Main loop
  for (;;)
  {
    // Set µC to sleep mode
    sleep_mode ();
  }
}

Der einzige Unterschied ist der sleep mode ... kanns daran liegen?

Grüße & Dank,

Michael

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Am sleep-mode 'sollte ' es nicht liegen
Da bin ich auch ratlos :(
Geht's vielleicht besser, wenn erst TOP und COMPARE gesetzt werden, 
BEVOR der Timer los läuft ? (sollte sich aber nur kurz auswirken :( )
  // Enable fast PWM mode 14 (table 47 page 113 ATMega16 Doc):
  TCCR1A    = (1 << COM1A1) |(1 << WGM11);

  // Set PWM
  ICR1     = (uint16_t)40000;
  OCR1A    = (uint16_t)ServoPosition;

  // Set prescaler 8 <-> START TIMER
  TCCR1B    = (1 << CS11) | (1 << WGM13) |(1 << WGM12);
Oder funktionieren andere Modi? (gibt ja noch mehr FastPWMs)
bzw. die andere Compare-Einheit?
Mit welcher Frequenz arbeitet der AVR? (bei 1MHz dauert eine Periode 
schließlich 8*40000/1e6Hz = 0.32s = 320ms!).

hth. Jörg

ps.: brauchst du nicht noch "#include<avr/sleep.h>"? oder fehlt das nur 
hier im Code ...

Autor: Michael K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg,
Die anderen Modi hab ich auch schon ausprobiert, aber leider ohne 
Erfolg. Die anderen Compareeinheiten kann ich leider nicht nehmen, da 
das Ganze schon auf Platine ist und die anderen Ports verwendet werden. 
Ich habe vorhin mal die Compare Ints eingeschaltet und eine Test ISR 
angelegt und in dieser dann das toggeln des Ports "per Hand" ausprobiert 
und das klappt wunderbar ....

> Mit welcher Frequenz arbeitet der AVR? (bei 1MHz dauert eine Periode
> schließlich 8*40000/1e6Hz = 0.32s = 320ms!).
16 MHz externer Quarz.

> ps.: brauchst du nicht noch "#include<avr/sleep.h>"? oder fehlt das nur
> hier im Code ...
Du hast Recht! Ich binde normalerweise ne main.h ein in der ist der 
sleep.h include natürlich drin !

Ich werd' morgen abend noch mal nen bißchen rumbasteln! Vielleicht 
klappts ja mit dem tauschen ....

Grüße und besten Dank,
Michael

Autor: Michael K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habs ....
Der Mega war hin. Warum ?? Keine Ahnung ... Neuer rein und lief ! Danke 
an alles für die Hilfe !
Grüße,
Michael

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.