Forum: Mikrocontroller und Digitale Elektronik Probleme Beim PWM erzeugen - AVR Butterfly


von Waldemar K. (Gast)


Lesenswert?

Hallo

ich fange bin ein Anfänger auf dem Gebiet der uController.

Nachdem ich eine LED mit einer einfachen __delay_cycles(500000); 
Anweisung zum blinken gebracht habe also

PORTB = 0x01;
__delay_cycles(500000);

PORTB = 0x00;
__delay_cycles(500000);


möchte ich mit flag und interrupt das Programm "besser" machen.

Scheinbar habe ich es noch nicht verstanden.

Ich habe folgenden Code:


-----------------------

#include <inavr.h>
#include "iom169.h"

void main( void )
{
  ///////////////////////Port ini/////////////////
  DDRB  =   DDRB  | 0x01;                        //  OCCRA  output
  PORTB =   PORTB & 0xFB;                        //  out lvl =0;
  ///////////////////////PWM ini//////////////////


  /////////////////////////////////////////////////////////////
  TCCR0A_Bit0= 1;   // CS00
  TCCR0A_Bit1=0;    // CS01
  TCCR0A_Bit2= 1;   // CS02
                          ///     output modus  clk/1024
  /////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////
  TCCR0A_Bit4=1;                      // COM0A0
  TCCR0A_Bit5=1;                      // COM0A1
  ///      Modus - If one or both bits are set, the OC0A output 
overrides the normal port functionality of the I/O pin it is connected 
to
//////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////
  TCCR0A_Bit3=0;                       // WGM00
  TCCR0A_Bit6=0;                       // WGM01
  ///  bit 7 erzwingt einen toggle  beim setzen, für prog vielleicht 
nötig, jedoch nicht für ini
/////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////
  TCNT0 =  0x00;                        // counter reset
  OCR0A =  0x7F;                        // 8 bit counter max val=  0xFF 
somit  bei 0x7F  ->  gleich 50% tastgad
////////////////////////////////////////////////////////////


  TIFR0 = TIFR0|  0x01;               // interrupt  wird Freigeschalten 
fuer  out compare, fuer blinkende
                                      //LED ist das eigentlich nicht 
nötig
  ////   ini Fertig  ////


  while (1)
  {
    if (OCR0A > 0x7F)
    {  PORTB = 1; }

    if (OCR0A < 0x7F)
    {  PORTB = 0; }



  }   // endlose loop;

}

-------------------------------



Kann mir jemand sagen wo der Fehler liegt.


Mein zweites Problem ist, dass ich keine kleinen und erklärten Beispiele 
für AVR Butterfly (IAR) finden kann wo ich sehe wie Programme 
funktionieren können.

Kennt jemand eine Seite (oder ein gutes Buch) nennen die mir als 
Anfänger weiterhelfen kann. Der Einstieg mit Register vor und Zurück 
ohne Beispielprogramme finde ich ziemlich heftig.


Vielen Dank

von Kernighan (Gast)


Lesenswert?

Wie manche App Note gibts bei Atmel?

Cheers
Richie

von Andreas W. (geier99)


Lesenswert?

Hallo Waldemar,

zu 1)

    if (OCR0A > 0x7F) ........

 OCR0A  ist immer auf 0x7F  gesetzt. Somit kann es nicht gehen.

dies sollte wohl :

    if (TCNT0 > 0x7F) ........ heissen, im 2. If natürlich auch.

 Dann sollte es gehen.

Du weist aber wozu man eine Hardware PWM verwendet und worin deren 
Vorteil liegt? So wie Du es angedacht hast, macht es keinen Sinn.
Lies Dir am Besten nochmal das PWM Kapitel im Datenblatt durch.

Jetzt noch ein paar Tipps:-)

 - IFR0 = TIFR0|  0x01;   // löscht das Interupt Output Compare Flag
   Da Du aber sowie so keinen Intrrupt freigeben hast und verwendest, 
kannst Du es ganz weglassen.

-  Bei einem Systemtakt von 8MHz beträgt die PWM-Frequenz ca. 30Hz.

-  Verwende doch den OC0A-Pin (PB4) als Ausgangspin. Dann musst Ihn 
nicht selbst setzen sondern es funktioniert automatisch und Du brauchst 
Dich nicht drum zu kümmern
==>
  DDRB  =   DDRB  |  (1<<4);   //  OC0A (PB4)  output
  PORTB =   PORTB & ~(1<<4);   //  PB4 löschen

 somit kanns du den Inhalt der while schleife komplett löschen.

Ausserdem muss Du noch :
  TCCR0A_Bit3=1;                       // WGM00
  TCCR0A_Bit6=1;                       // WGM01

setzen damit du Dein gwünschtes Verhalten hast. Somit wird dann PB4 beim
Compare Match gesetzt und beim Zählerstand von 0x00 wieder gelöscht ohne 
dass Du dich darum im Programm selbst kümmern musst


zu 2) Beispiele für AVR Butterfly (IAR) findest Du auf der HP von Atmel.
  Gib einfach mal im Suchfeld: "butterfly" ein. Und lade Dir mal das 
"AVR Butterfly - Application Rev07" - zip-Archiv runter.

Viel Spass beim Lernen :-)

Gruss
 Andy

von Waldemar K. (Gast)


Lesenswert?

Vielen Dank für die ausführliche Antwort.

Ich werde deine Vorschläge gleich morgen früh (heute zu spät O:23) 
ausprobieren.

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.