Forum: Mikrocontroller und Digitale Elektronik AVR 16Bit PWM flakert unregelmässig


von Markus Gerber (Gast)


Lesenswert?

Guten Tag, ich bin Anfänger und arbeite neu mit einem Atmega 162 und 
möchte 4 verschiedene 16Bit PWM generieren.
Ich habe ein simples Programm geschrieben um die PWM zu testen, ich 
erhöhe die Pulsweite bis ans Maximum, und verkleinere sie dann bis ans 
Minimum und so weiter und sofort. Soweit funktioniert die PWM gut, 
ausser dass sie eine Störung aufweisst. Die LED flakert kurz, wenn die 
PWM an das Maximum gelangt.
Das passiert meistens, jedoch nicht immer, die Störung ist also nicht 
regelmässig.

Ich bin verwirrt..
Habe ich einen Fehler beim Setzen der Register gemacht?
Habe ich sonst etwas übersehen oder nicht korrekt gemacht?

mfg Markus
1
/*******************************************************************************
2
3
4
5
#define F_CPU 4000000L
6
7
8
#include <avr/io.h>
9
#include <util/delay.h>
10
#include <avr/interrupt.h> 
11
12
13
long tab[256]={ 0, 1, 1, 1, 1,   1, 1, 1, 1, 2, 2, 2, 2, 2,
14
2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
15
4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6,
16
6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11,
17
11, 12, 12, 13, 13, 14, 15, 15, 16, 17, 17,
18
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
19
29, 31, 32, 33, 35, 36, 38, 40, 41, 43, 45,
20
47, 49, 52, 54, 56, 59, 61, 64, 67, 70, 73,
21
76, 79, 83, 87, 91, 95, 99, 103, 108, 112,
22
117, 123, 128, 134, 140, 146, 152, 159, 166,
23
173, 181, 189, 197, 206, 215, 225, 235, 245,
24
256, 267, 279, 292, 304, 318, 332, 347, 362,
25
378, 395, 412, 431, 450, 470, 490, 512, 535,
26
558, 583, 609, 636, 664, 693, 724, 756, 790,
27
825, 861, 899, 939, 981, 1024, 1069, 1117,
28
1166, 1218, 1272, 1328, 1387, 1448, 1512,
29
1579, 1649, 1722, 1798, 1878, 1961, 2048,
30
2139, 2233, 2332, 2435, 2543, 2656, 2773,
31
2896, 3025, 3158, 3298, 3444, 3597, 3756,
32
3922, 4096, 4277, 4467, 4664, 4871, 5087,
33
5312, 5547, 5793, 6049, 6317, 6596, 6889,
34
7194, 7512, 7845, 8192, 8555, 8933, 9329,
35
9742, 10173, 10624, 11094, 11585, 12098,
36
12634, 13193, 13777, 14387, 15024, 15689,
37
16384, 17109, 17867, 18658, 19484, 20346,
38
21247, 22188, 23170, 24196, 25267, 26386,
39
27554, 28774, 30048, 31378, 32768, 34218,
40
35733, 37315, 38967, 40693, 42494, 44376,
41
46340, 48392, 50534, 52772, 55108, 57548,
42
60096, 62757, 65535};
43
44
write_16Bit(int i, int j)
45
  {
46
  //cli();
47
  OCR3AH=(tab[i])>>8;
48
  OCR3AL=tab[i];
49
  OCR3BH=(tab[i])>>8;
50
  OCR3BL=tab[i];
51
  OCR1AH=(tab[j])>>8;
52
  OCR1AL=tab[j];
53
  OCR1BH=(tab[j])>>8;
54
  OCR1BL=tab[j];
55
  //sei();
56
  return 0;
57
  }
58
59
60
int main(void){
61
62
int i=0;
63
int j=100;
64
int inc_i=1;
65
int inc_j=1;
66
67
DDRA=0xFF; // Output
68
DDRB=0xFF; // Output
69
DDRC=0xFF; // Output
70
DDRD=0xFF; // Output
71
72
ICR3H=0xFF; // set MAX
73
ICR3L=0xFF; // set MAX
74
ICR1H=0xFF; // set MAX
75
ICR1L=0xFF; // set MAX
76
77
TCCR3A|=(1<<COM3A1 | COM3A0 | 1<<COM3B1 | COM3B0 |1<<WGM31 );
78
TCCR3B|=(1<<CS30| 1<<WGM32| 1<<WGM33);
79
TCCR1A|=(1<<COM1A1 | COM1A0 | 1<<COM1B1 | COM1B0 |1<<WGM11 );
80
TCCR1B|=(1<<CS10| 1<<WGM12| 1<<WGM13);
81
82
cli();
83
84
while(1){
85
  _delay_ms(10);
86
87
  if(inc_i==1)i++;
88
  if(inc_i==0)i--;
89
  if(inc_j==1)j++;
90
  if(inc_j==0)j--;
91
92
93
  if(i>253)inc_i=0;
94
  if(i<1)inc_i=1;
95
  if(j>253)inc_j=0;
96
  if(j<1)inc_j=1;
97
98
  write_16Bit(i,j);        
99
    }
100
return 0;
101
}

von spess53 (Gast)


Lesenswert?

Hi

>TCCR3A|=(1<<COM3A1 | COM3A0 | 1<<COM3B1 | COM3B0 |1<<WGM31 );
>TCCR3B|=(1<<CS30| 1<<WGM32| 1<<WGM33);
>TCCR1A|=(1<<COM1A1 | COM1A0 | 1<<COM1B1 | COM1B0 |1<<WGM11 );
>TCCR1B|=(1<<CS10| 1<<WGM12| 1<<WGM13);

Meinst du nicht, das da noch ein paar Shiftoperatoren fehlen?

MfG Spess

von Markus Gerber (Gast)


Lesenswert?

du meinst, ich habe noch nicht alle notwendigen Bit gesetzt?
Wenn ja, welche müsste man noch setzen?

mfg Markus

von Markus Gerber (Gast)


Lesenswert?

ahh jetzt hab ichs gesehn :) danke!! :)

von Peter D. (peda)


Lesenswert?

Du mußt den Speicher nicht zumüllen, eine "long" Tabelle ist unnötig.
65535 paßt prima in ein "unsigned int" oder besser "uint16_t".


Beim AVR-GCC sind die Timer auch 16-bittig definiert, muß man also nicht 
umständlich aufsplitten.


Peter

von Markus Gerber (Gast)


Lesenswert?

nun ich habe die Fehler korrigiert,

TCCR3A|=(1<<COM3A1 | 1<<COM3A0 | 1<<COM3B1 | 1<<COM3B0 |1<<WGM31 );
TCCR3B|=(1<<CS30| 1<<WGM32| 1<<WGM33);
TCCR1A|=(1<<COM1A1 | 1<<COM1A0 | 1<<COM1B1 | 1<<COM1B0 |1<<WGM11 );
TCCR1B|=(1<<CS10| 1<<WGM12| 1<<WGM13);

dies hatte leider keinen Einfluss auf das Flakern

von Markus Gerber (Gast)


Lesenswert?

dass heisst man könnte das so machen:

OCR3A=tab[i];
OCR3B=tab[i];
OCR1A=tab[j];
OCR1B=tab[j];

ok..


die tabelle habe ich nun auch mit einem unsigned int erstellt

unsigned int tab[256]={....};

leider flakert es immer noch.. danke trotzdem!

von Markus Gerber (Gast)


Lesenswert?

hallo ich bins nochmal, es funktioniert jetzt, so wie es sollte, :) 
danke vielmals für die Tipps!!!

mfg Markus

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.