www.mikrocontroller.net

Forum: Compiler & IDEs Frage zu PWM


Autor: Jannis C. (kabelwurm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe eine Frage zu PWMs.
Ich benutze einen Attiny24. Dort finde ich in der Pinbelegung OC1A und 
OC1B. Kann ich es so prorammieren, dass ich an beiden zwei verschiedene 
Siganale generieren kann und die nach Bedarf aktivieren?
Gruß Jannis

Autor: Lehrmann Michael (ubimbo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jannis C. schrieb:
> Ich benutze einen Attiny24. Dort finde ich in der Pinbelegung OC1A und
> OC1B. Kann ich es so prorammieren, dass ich an beiden zwei verschiedene
> Siganale generieren kann und die nach Bedarf aktivieren?

Für solche Sachen gibt es ein Datenblatt. Da steht absolut alles drin. 
Sowohl als Anfänger als auch als Fortgeschrittener muss man sich mit dem 
Datenblatt beschäftigen. Auch wenn Anfänger das für gewöhnlich anders 
sehen.

Beitrag #2101550 wurde vom Autor gelöscht.
Autor: Jannis C. (kabelwurm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe versucht, das Datenblatt zu verwenden, was mir auch in 90% der 
Fälle gehofen hat. Ich benutze das Datenblatt, wenn ich ein Problem 
habe.
Das war eine der ersten Dinge die ich in diesem Forum gelernt habe.
Zurück zum Datenblatt.
 In der Registersummery gibt es zu beiden ein High und ein Low Register, 
was bei 16Bit Register ja immer so ist. Ich weiß jetzt aber nicht wie 
ich jeweils einen Pin definiere, wo die PWM rauskommen soll und wie ich 
sie aktivieren und deaktiviren kann. Das bekomme ich aus dem Db nicht 
heraus.
Gruß Jannis

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jannis C. schrieb:

>  In der Registersummery gibt es zu beiden ein High und ein Low Register,
> was bei 16Bit Register ja immer so ist. Ich weiß jetzt aber nicht wie
> ich jeweils einen Pin definiere, wo die PWM rauskommen soll

Der Pin ist dir vorgegeben. Du kannst den nicht frei aussuchen

> und wie ich
> sie aktivieren und deaktiviren kann. Das bekomme ich aus dem Db nicht
> heraus.

Di COMxXx - Bits (zb COM1A1 / COM1A0 für die Kanäle A und B des Timer 1) 
sind dafür zuständig. Bei der "Register Description" des jeweiligen 
Timers (ist immer das letzte Kapitel imjeweiligen Timer Abschnitt des 
Datenblattes) findet sich für jeden PWM Modus immer eine Tabelle, aus 
der man entnehmen kann, wie die Bits stehen müssen, damit der jeweilige 
PWM Ausgang was genau macht.

Der Abschnitt "Register Description" ist bei den meisten 
Datenblattkapitel immer der wichtigste Abschnitt. Dort ist in Kurzform 
für alle Registerbits (oftmals in Tabellenform) aufgeführt, welches Bit 
in welchem Register was bewirkt. Der Rest des Kapitels ist meistens die 
Beschreibung der Funktionalität, damit man auch weiß wie das alles 
funktioniert und was gemacht werden kann. In der Register Description 
findet sich dann die Info wie man die Dinge konfigurieren muss.

Autor: Jannis C. (kabelwurm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
jetzt habe ich mit den von Karl-Heinz genannten Ansätzen die Lösung für 
meine Frage gefunden. Im Datenblatt steht halt alles drin. :))
Gruß Jannis

Autor: Jannis C. (kabelwurm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch eine Frage:
Ich möchte das der Wert der Vergleichswert im Verlauf einer Hyperbel 
entspricht.
Wie schreibe ich das richtig, dass die Nachkommastellen weggelassen 
werden?
In meinem C-Buch steht das man int = float schreibt.
Das funktioniert aber nicht.
Gruß Jannis

Autor: Jannis C. (kabelwurm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
um meine Frage noch einmal zu konkretisieren:
In meinem C-Buch steht für die Umwandlung einer Float-Zahl in eine 
Int-Zahl
int float2int = wertx;
Das möchte ich jetzt anwenden. Und zwar möchte ich einen Float in einen 
8-Bit Integer umwandeln. Wie mache ich das?
Gruß Jannis

Autor: Benjamin Utz (utzus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
float deinwert = 12.343;
int ohnekomma = deinwert;

nun sollte die Variable ohnekomma 12 sein. Achtung, es wird nicht 
gerundet!! Nur abgeschnitten.

Grüße

Autor: Jannis C. (kabelwurm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das weiß ich.
Ist auch Sinn der Sache.
Noch eine Frage:
Der Floatwert ist eine Variable, geht das trotzdem?
Und wie kann ich mit Gleitkommazahlen rechnen ohne den Datentyp float zu 
verwenden? Ich kann das Programm nämlich nicht flashen, weil der 
Compiller sagt, dass der Controller nicht genug Speicher dafür hat.
>The contents of the objectfile exceeds the maximum program memory of the device
Gruß Jannis

Autor: Jannis C. (kabelwurm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So,
ich habe deinen Vorschlag versucht anzuwenden. Ich glaube aber es ist 
mir nicht richtig gelungen.
Mein Code:
/* PWM für Grubensteuerung 
/ @ Attiny 24 mit 8MHz
 */
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include <float.h>


#ifndef F_CPU 
#define F_CPU 8000000UL
#endif
#include <util/delay.h>


#define HOCH 1
#define RUNTER 0

uint8_t hoch;
uint8_t runter;
int vergleichswert11;
int vergleichswert21;
uint8_t richtung;
uint8_t wechsler;

float vergleichswert1;
float vergleichswert2;

ISR (TIMER0_OFV_vect)
{
 runter++;
 hoch++;
 hoch++;
}
int main (void)
{
 
 DDRA = 0b1100000;
 sei();
 TCCR0A =0;
 TCCR0B = (1<<CS12) | (1<<CS10); // Prescaler 1/1024
 TIMSK0 = (1<<TOIE0); 
 TCCR1A = (1<<WGM11) | (1<<WGM10)| (1<<COM1A1) | (1<<COM1B1) | (1<<COM1A0) | (1<<COM1B0) ;  //10-Bit PWM invertiert bei beiden Modulen
 TCCR1B = (1<<CS12) | (1<<CS10); // Prescaler 1/1024
 ICR1 = 0b1111111111;
 OCR1A = vergleichswert1; //runter
 OCR1B = vergleichswert2; //rauf

 vergleichswert1 = 255;
 vergleichswert2 = 255;
 runter = 100;
 richtung = RUNTER;
 while (1)
{ 
   if (  (runter ==255) && (richtung ==RUNTER)  ) { //Abfahrt
      runter =0;
      while (vergleichswert11>4) //Runterfahren /beschleunigen
        {
         float vergleichswert1 = vergleichswert1/1,07 ;
         int vergleichswert11 = vergleichswert1;


        }
    return 0;
      _delay_ms(1000);
    _delay_ms(1000);
    _delay_ms(1000);
    runter = 0;
    vergleichswert1 =4;
      while (vergleichswert11<255) //bremsen
      {
       float vergleichswert1 = vergleichswert1*1,07 ;
         int vergleichswert11 = vergleichswert1;
    
        }
      return 0;
    vergleichswert1= 255;
    _delay_ms(1000);
      _delay_ms(1000);//vier Sekunden warten
    _delay_ms(1000);
    _delay_ms(1000);
      while (vergleichswert11>4) //Runterfahren /beschleunigen
        {
         float vergleichswert1 = vergleichswert1/1,07 ;
         int vergleichswert11 = vergleichswert1;
        }
    return 0;
       _delay_ms(1000);
      _delay_ms(1000);//sechs Sekunden warten
    _delay_ms(1000);
    _delay_ms(1000); 
      _delay_ms(1000);
    _delay_ms(1000);
    vergleichswert1 =4;
      while (vergleichswert11<255) //bremsen
      {
       float vergleichswert1 = vergleichswert1*1,07 ;
         int vergleichswert11 = vergleichswert1;
        }
      return 0;
    _delay_ms(1000);
      _delay_ms(1000);//vier Sekunden warten
    _delay_ms(1000);
    _delay_ms(1000);
      wechsler++;
   }else {
      runter =0;
   }
    if ( (richtung ==RUNTER) && (hoch ==244  )  ){ //Aufwärts
      
      while (vergleichswert21>4) //Hochfahren /beschleunigen
        {
        float vergleichswert2 = vergleichswert2/1,07 ;
         int vergleichswert21 = vergleichswert2;
        }
    return 0;
      _delay_ms(1000);
    _delay_ms(1000);
    _delay_ms(1000);
    runter = 0;
    vergleichswert2 =4;
      while (vergleichswert21<255) //bremsen
      {
       float vergleichswert2 = vergleichswert2*1,07 ;
         int vergleichswert21 = vergleichswert2;
        }
      return 0;
    vergleichswert2= 255;
    
      //zwei Sekunden warten
    _delay_ms(1000);
    _delay_ms(1000);
      while (vergleichswert21>4) //Hochfahren /beschleunigen
        {
       float vergleichswert2 = vergleichswert2/1,07 ;
         int vergleichswert21 = vergleichswert2;
        }
    return 0;
       _delay_ms(1000);
      _delay_ms(1000);//sechs Sekunden warten
    _delay_ms(1000);
    _delay_ms(1000); 
      _delay_ms(1000);
    _delay_ms(1000);
    vergleichswert2 =4;
      while (vergleichswert21<255) //bremsen
      {
      float vergleichswert2 = vergleichswert2*1,07 ;
         int vergleichswert21 = vergleichswert2;
        }
      return 0;
    _delay_ms(1000);
      _delay_ms(1000);//drei Sekunden warten
    _delay_ms(1000);

      wechsler++;
   }else {
      hoch =0;
   }
      
      
     
   
   if ( (wechsler ==1) && (richtung == RUNTER)  ) {
      wechsler = 0;
    richtung = HOCH;
   }
   if ( (wechsler ==1 ) && (richtung == HOCH)  ) {
      wechsler = 0;
    richtung = HOCH;
   }
 
 }return 0;
   
}


Ein Fehler ist noch drin vo dem ich weiß. Ich habe die PWM noch nicht 
auf 8-Bit umgestellt.
Gruß Jannis

Autor: Benjamin Utz (utzus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also, ich weiß nicht wo ich anfangen soll :D
Vielleicht bei dem Spaghetticode?
Wieso können andere Leute es sauber einrücken? Und sag jetzt nicht, das 
kommt vom Forum!

Also, zu beginn schreibst du:
> float vergleichswert1;
> float vergleichswert2;

Und danach schreibst du:
 OCR1A = vergleichswert1; //runter
 OCR1B = vergleichswert2; //rauf

 vergleichswert1 = 255;
 vergleichswert2 = 255;

Was denkst du, welcher Wert steht in OCR1A/B ??

Würde ich erst machen, wenn ich ALLES Initialisiert habe!!
>  sei();

Wenn du diese Schleife verlässst, kannst du glücklich sein.
>       while (vergleichswert11>4) //Runterfahren /beschleunigen
>         {
>          float vergleichswert1 = vergleichswert1/1,07 ;
>          int vergleichswert11 = vergleichswert1;
>         }

Du definierst eine NEU Variable vergleichswert1 und in die schreibst du 
einen zufälligen Wert geteilt durch 1,07! So, wieso kann dein Compiler 
mit Komma rechnen? meiner mag nur Punkte! 1.07
und danach schreibst du diese (zufällige) Zahl in eine wieder neue 
integerzahl. Deine Whileschleife fragt DIESE zahl aber nicht ab. Denn er 
kennt sie nicht! Er kennt nur die "vergleichswert11" von ganz oben 
(welche auch zufällig initialisiert ist!). Diese bearbeitest du aber 
nicht! (bin mir ziemlich sicher mit dieser Aussage!) Da musst du noch 
mal in dein C-Buch schauen, was mit Variablen passiert, die in einem 
Block definiert werden.

Und hier beendest du dein Programm:
>     return 0;
und der Controller macht danach alles mögliche!

Und hierfür
>       _delay_ms(1000);
>     _delay_ms(1000);
>     _delay_ms(1000);
kann man ja auch was anderes schreiben!

So, also hast du noch ne schöne Aufgabe für heut Abend. Deinen ganzen 
Code nochmal überarbeiten, schön formatieren und das C-Buch lesen zum 
Thema variablen und deren Gültigkeitsbereiche!

Es hat mich viel Überwindung gekostet den Code überhaupt anzuschauen! :)

Viel Spaß,
Benni

P.S. Kein Wunder, dass das in Chile passiert ist!

Autor: Jannis C. (kabelwurm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
vielen Dank, dass du dir die Mühe machst. Das mit dem Einrücken übe ich 
noch. Und der Teil mit Float ist mein Problem. Und der Code ist nicht 
aus dem Forum. Solchen Mist mache ich nur selber. /:
Aber von Leuten wie dir lernt man es am besten.
Gruß Jannis

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.