www.mikrocontroller.net

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


Autor: Waldemar K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Kernighan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie manche App Note gibts bei Atmel?

Cheers
Richie

Autor: Andreas W. (geier99)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Waldemar K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

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.