Forum: Compiler & IDEs Frage zu PWM


von Jannis C. (kabelwurm)


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

von Lehrmann M. (ubimbo)


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.

von Jannis C. (kabelwurm)


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

von Karl H. (kbuchegg)


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.

von Jannis C. (kabelwurm)


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

von Jannis C. (kabelwurm)


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

von Jannis C. (kabelwurm)


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

von Benjamin U. (utzus)


Lesenswert?

float deinwert = 12.343;
int ohnekomma = deinwert;

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

Grüße

von Jannis C. (kabelwurm)


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

von Jannis C. (kabelwurm)


Lesenswert?

So,
ich habe deinen Vorschlag versucht anzuwenden. Ich glaube aber es ist 
mir nicht richtig gelungen.
Mein Code:
1
/* PWM für Grubensteuerung 
2
/ @ Attiny 24 mit 8MHz
3
 */
4
#include <avr/io.h>
5
#include <stdint.h>
6
#include <avr/interrupt.h>
7
#include <float.h>
8
9
10
#ifndef F_CPU 
11
#define F_CPU 8000000UL
12
#endif
13
#include <util/delay.h>
14
15
16
#define HOCH 1
17
#define RUNTER 0
18
19
uint8_t hoch;
20
uint8_t runter;
21
int vergleichswert11;
22
int vergleichswert21;
23
uint8_t richtung;
24
uint8_t wechsler;
25
26
float vergleichswert1;
27
float vergleichswert2;
28
29
ISR (TIMER0_OFV_vect)
30
{
31
 runter++;
32
 hoch++;
33
 hoch++;
34
}
35
int main (void)
36
{
37
 
38
 DDRA = 0b1100000;
39
 sei();
40
 TCCR0A =0;
41
 TCCR0B = (1<<CS12) | (1<<CS10); // Prescaler 1/1024
42
 TIMSK0 = (1<<TOIE0); 
43
 TCCR1A = (1<<WGM11) | (1<<WGM10)| (1<<COM1A1) | (1<<COM1B1) | (1<<COM1A0) | (1<<COM1B0) ;  //10-Bit PWM invertiert bei beiden Modulen
44
 TCCR1B = (1<<CS12) | (1<<CS10); // Prescaler 1/1024
45
 ICR1 = 0b1111111111;
46
 OCR1A = vergleichswert1; //runter
47
 OCR1B = vergleichswert2; //rauf
48
49
 vergleichswert1 = 255;
50
 vergleichswert2 = 255;
51
 runter = 100;
52
 richtung = RUNTER;
53
 while (1)
54
{ 
55
   if (  (runter ==255) && (richtung ==RUNTER)  ) { //Abfahrt
56
      runter =0;
57
      while (vergleichswert11>4) //Runterfahren /beschleunigen
58
        {
59
         float vergleichswert1 = vergleichswert1/1,07 ;
60
         int vergleichswert11 = vergleichswert1;
61
62
63
        }
64
    return 0;
65
      _delay_ms(1000);
66
    _delay_ms(1000);
67
    _delay_ms(1000);
68
    runter = 0;
69
    vergleichswert1 =4;
70
      while (vergleichswert11<255) //bremsen
71
      {
72
       float vergleichswert1 = vergleichswert1*1,07 ;
73
         int vergleichswert11 = vergleichswert1;
74
    
75
        }
76
      return 0;
77
    vergleichswert1= 255;
78
    _delay_ms(1000);
79
      _delay_ms(1000);//vier Sekunden warten
80
    _delay_ms(1000);
81
    _delay_ms(1000);
82
      while (vergleichswert11>4) //Runterfahren /beschleunigen
83
        {
84
         float vergleichswert1 = vergleichswert1/1,07 ;
85
         int vergleichswert11 = vergleichswert1;
86
        }
87
    return 0;
88
       _delay_ms(1000);
89
      _delay_ms(1000);//sechs Sekunden warten
90
    _delay_ms(1000);
91
    _delay_ms(1000); 
92
      _delay_ms(1000);
93
    _delay_ms(1000);
94
    vergleichswert1 =4;
95
      while (vergleichswert11<255) //bremsen
96
      {
97
       float vergleichswert1 = vergleichswert1*1,07 ;
98
         int vergleichswert11 = vergleichswert1;
99
        }
100
      return 0;
101
    _delay_ms(1000);
102
      _delay_ms(1000);//vier Sekunden warten
103
    _delay_ms(1000);
104
    _delay_ms(1000);
105
      wechsler++;
106
   }else {
107
      runter =0;
108
   }
109
    if ( (richtung ==RUNTER) && (hoch ==244  )  ){ //Aufwärts
110
      
111
      while (vergleichswert21>4) //Hochfahren /beschleunigen
112
        {
113
        float vergleichswert2 = vergleichswert2/1,07 ;
114
         int vergleichswert21 = vergleichswert2;
115
        }
116
    return 0;
117
      _delay_ms(1000);
118
    _delay_ms(1000);
119
    _delay_ms(1000);
120
    runter = 0;
121
    vergleichswert2 =4;
122
      while (vergleichswert21<255) //bremsen
123
      {
124
       float vergleichswert2 = vergleichswert2*1,07 ;
125
         int vergleichswert21 = vergleichswert2;
126
        }
127
      return 0;
128
    vergleichswert2= 255;
129
    
130
      //zwei Sekunden warten
131
    _delay_ms(1000);
132
    _delay_ms(1000);
133
      while (vergleichswert21>4) //Hochfahren /beschleunigen
134
        {
135
       float vergleichswert2 = vergleichswert2/1,07 ;
136
         int vergleichswert21 = vergleichswert2;
137
        }
138
    return 0;
139
       _delay_ms(1000);
140
      _delay_ms(1000);//sechs Sekunden warten
141
    _delay_ms(1000);
142
    _delay_ms(1000); 
143
      _delay_ms(1000);
144
    _delay_ms(1000);
145
    vergleichswert2 =4;
146
      while (vergleichswert21<255) //bremsen
147
      {
148
      float vergleichswert2 = vergleichswert2*1,07 ;
149
         int vergleichswert21 = vergleichswert2;
150
        }
151
      return 0;
152
    _delay_ms(1000);
153
      _delay_ms(1000);//drei Sekunden warten
154
    _delay_ms(1000);
155
156
      wechsler++;
157
   }else {
158
      hoch =0;
159
   }
160
      
161
      
162
     
163
   
164
   if ( (wechsler ==1) && (richtung == RUNTER)  ) {
165
      wechsler = 0;
166
    richtung = HOCH;
167
   }
168
   if ( (wechsler ==1 ) && (richtung == HOCH)  ) {
169
      wechsler = 0;
170
    richtung = HOCH;
171
   }
172
 
173
 }return 0;
174
   
175
}
Ein Fehler ist noch drin vo dem ich weiß. Ich habe die PWM noch nicht 
auf 8-Bit umgestellt.
Gruß Jannis

von Benjamin U. (utzus)


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!

von Jannis C. (kabelwurm)


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

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.