Forum: Mikrocontroller und Digitale Elektronik ATTiny2313 fast PWM


von Ephraim H. (ephi)


Lesenswert?

Hallo zusammen,

ich krig das mit der PWM an einem ATTiny2313 irgendwie nicht gebacken.
Ich möchte den Timer1 im 16bit fast pwm mode mit direktem CPU Takt (8Mhz 
über externen quarz) betreiben.

Hier mal mein code:
1
// headers
2
#include <avr/io.h>
3
#include <stdio.h>
4
#include <util/delay.h>
5
6
// pwm dimming courve
7
const uint16_t pwmtable[256] = 
8
{0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
9
  2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
10
  4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6,
11
  6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11,
12
  11, 12, 12, 13, 13, 14, 15, 15, 16, 17, 17,
13
  18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
14
  29, 31, 32, 33, 35, 36, 38, 40, 41, 43, 45,
15
  47, 49, 52, 54, 56, 59, 61, 64, 67, 70, 73,
16
  76, 79, 83, 87, 91, 95, 99, 103, 108, 112,
17
  117, 123, 128, 134, 140, 146, 152, 159, 166,
18
  173, 181, 189, 197, 206, 215, 225, 235, 245,
19
  256, 267, 279, 292, 304, 318, 332, 347, 362,
20
  378, 395, 412, 431, 450, 470, 490, 512, 535,
21
  558, 583, 609, 636, 664, 693, 724, 756, 790,
22
  825, 861, 899, 939, 981, 1024, 1069, 1117,
23
  1166, 1218, 1272, 1328, 1387, 1448, 1512,
24
  1579, 1649, 1722, 1798, 1878, 1961, 2048,
25
  2139, 2233, 2332, 2435, 2543, 2656, 2773,
26
  2896, 3025, 3158, 3298, 3444, 3597, 3756,
27
  3922, 4096, 4277, 4467, 4664, 4871, 5087,
28
  5312, 5547, 5793, 6049, 6317, 6596, 6889,
29
  7194, 7512, 7845, 8192, 8555, 8933, 9329,
30
  9742, 10173, 10624, 11094, 11585, 12098,
31
  12634, 13193, 13777, 14387, 15024, 15689,
32
  16384, 17109, 17867, 18658, 19484, 20346,
33
  21247, 22188, 23170, 24196, 25267, 26386,
34
  27554, 28774, 30048, 31378, 32768, 34218,
35
  35733, 37315, 38967, 40693, 42494, 44376,
36
  46340, 48392, 50534, 52772, 55108, 57548,
37
  60096, 62757, 65535};
38
39
40
// pwm init
41
void pwm_init(void)
42
{
43
  DDRB = (1 << PB3);  // output
44
  
45
  TCCR1A = (1 << COM1A1) | (1 << WGM10) | (1 << WGM11);  // fast PWM mode
46
  TCCR1B = (1 << WGM12)  | (1 << WGM13) | (1 << CS10);  // no prescaler      
47
  OCR1A = 0xFFFF;  // 16-bit
48
}
49
50
51
// Hauptfunktion
52
int main(void)
53
{
54
  pwm_init();
55
  
56
  uint8_t i=0;  
57
  
58
    while(1) 
59
  {  
60
    for(i=0;i>255;i++)
61
    {
62
      OCR1B = pwmtable[i];
63
      _delay_ms(10);
64
    }
65
    for(i=255;i<0;i--)
66
    {
67
      OCR1B = pwmtable[i];
68
      _delay_ms(10);
69
    }
70
  };
71
  
72
    return 0;
73
}

Wenn ich es richtig verstanden habe, stelle ich in OCR1A die Auflösung 
ein (0xFFFF für volle 16bit) und OCR1B enthält dann den pwm wert. Zur 
Kontrolle habe ich erstmal eine LED an OC1A gehängt, da tut sich aber 
irgendwie gar nichts. Ich stehe etwas auf dem Schlauch, denn eigentlich 
sollte die LED ja langsam heller und dunkler werden.

Wäre schön, wenn mir jemand helfen kann!

Gruß

von MWS (Gast)


Lesenswert?

Ephraim Hahn schrieb:
> sollte die LED ja langsam heller und dunkler werden

Würde sie vielleicht sogar, wenn sie an OC1B hängen würde.

von MWS (Gast)


Lesenswert?

Und nicht zu vergessen: COM1B1 gesetzt würde.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Ephraim Hahn schrieb:
> Hallo zusammen,
>
...
> Wenn ich es richtig verstanden habe, stelle ich in OCR1A die Auflösung
> ein (0xFFFF für volle 16bit) und OCR1B enthält dann den pwm wert. Zur
> Kontrolle habe ich erstmal eine LED an OC1A gehängt, da tut sich aber
> irgendwie gar nichts. Ich stehe etwas auf dem Schlauch, denn eigentlich
> sollte die LED ja langsam heller und dunkler werden.
>
> Wäre schön, wenn mir jemand helfen kann!
>
> Gruß
>

Hallo,

von der Programmiersprache C hab ich leider keine Ahnung. Ich befasse 
mich gerade mit dem 8-Bit Timer/Counter0 with PWM beim ATtiny13.

Habe das Datenblatt vom ATtiny2313 gerade mal überflogen.
Ich denke Du verstehst die Bedeutung von den Output Compare Registern
( OCRxx ) noch nicht. Ich möchte es Dir nicht erklären, da selber noch 
nicht so fit darin bin und Dir deshalb nichts falsches schreiben möchte.

Eins dürfte jedoch trotzdem interessant sein, das sind nämlich die 
extremwerte von $0000 und $FFFF in den OCRxx-Registern. Dazu steht 
nämlich folgendes im Datenblatt.

The extreme values for the OCR1x Register represents special cases when 
generating a PWM waveform output in the fast PWM mode.
If the OCR1x is set equal to BOTTOM (0x0000) the output will be a narrow 
spike for each TOP+1 timer clock cycle.
Setting the OCR1x equal to TOP will result in a constant high or low 
output (depending on the polarity
of the output set by the COM1x1:0 bits.)

Bernd_Stein

von MWS (Gast)


Lesenswert?

Bernd Stein schrieb:
> von der Programmiersprache C hab ich leider keine Ahnung. Ich befasse
> mich gerade mit dem 8-Bit Timer/Counter0 with PWM beim ATtiny13.
>
> Habe das Datenblatt vom ATtiny2313 gerade mal überflogen.

Überfliegen ist schlecht, wenn dann genau lesen.
Der Code ist nicht gar so verkehrt, falsch ist nur die Verwendung des 
COM1A1 mit Ausgang OC1A, auch daran zu erkennen daß PB3 als Ausgang 
definiert wird.

Beim hier eingestellten Mode 15 wird OCR1A zum TOP-Wert des Timers und 
steht damit für die PWM nicht mehr zur Verfügung.

Und für OCR1B, der richtig im Code eingesetzt wird, muss eben COM1B1..0 
beschrieben, als auch OC1B/PB4 als Ausgang gesetzt werden.

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.