Forum: Mikrocontroller und Digitale Elektronik PWM auf ATmega328P


von Sören K. (foxalem)


Lesenswert?

Moin liebes Forum,

zzt. bastel ich an einem LED-Suit und brauche dafür eine PWM (zum dimmen 
der LEDs bzw. der Simulation eines Pulses).

Leider bekomme ich die PWM nun nicht wirklich hin. Die LEDs zeigen fast 
keine reaktion beim Faden, bzw. wenn ich einen Pre-Scaler wähle (z.b. 
64) blinken die LEDs von Dunkel nach hell.

Ich finde den Fehler einfach nicht.

Da ich an die 100LEDs verbaut habe, habe ich ein paar Shiftregister (12 
x 74H595) an den SPI-angeschlossen, worüber ich die Leds dann jeweils 
mit 0xFF einschalte bzw. 0x00 ausschalte.

Rein zum Verständnis möchte ich die LEDs von "aus" bis "ganz an" 
durchdimmen, alles andere kann ich mir dann selbst wieder 
zusammenbasteln, nur muss ich erstmal hinbekommen sie überhaupt 
durchzudimmen.
Ich denke ich habe irgendwo einen Fehler den ich einfach nicht finde.

Mfg
Sören

Anbei der Code:
1
#include <avr/io.h>
2
#define F_CPU 8000000UL // 8 MhZ
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5
6
void spi_send(int wert);
7
8
#define RCK PINB2
9
#define SIN PINB3
10
#define SCK PINB5
11
12
int zahl = 0;
13
int a = 0;
14
int i = 0;
15
16
int main(void)
17
{
18
  //SPI konfigurieren
19
  SPCR = (1<<MSTR); //SPI ist master, MSB first, SCK is high wenn inaktiv
20
  SPSR = (1<<SPI2X);
21
  SPCR |= (1<<SPE);
22
  
23
  DDRB |= (1<<SCK) | (1<<SIN) | (1<<RCK) | (1<<PINB1);
24
    
25
  //Timer auf PWM stellen und initialisieren.
26
  TCCR1A = (1<<WGM11) | (1<<WGM10) | (1<<COM1A1); // 10bit-Counter, nicht invert. PWM
27
  TCCR1B = (1<<CS11) | (1<< CS10); // Pre-Scaler = 64
28
  TIMSK1 = (1<<OCIE1A) | (1<<TOIE1); // Output Compare A + Timer Overflow Interrupt Enable
29
  
30
  sei();
31
    
32
  while(1)
33
    {
34
        OCR1A = a;
35
    a++;
36
    
37
    if (a >= 1024) {
38
      a = 0;
39
    }
40
    
41
    _delay_ms(10);
42
  }
43
}
44
45
void spi_send(int wert)
46
  {
47
    //Durch alle Shiftregister "durchshiften"
48
    for (i = 0; i<12; i++)
49
    {
50
    SPDR = wert;
51
    while (!(SPSR & (1<<SPIF)));
52
    }
53
    
54
    //SPI-Übernahme
55
    PORTB |= (1<<RCK);
56
    _delay_us(1);
57
    PORTB &= ~(1<<RCK);
58
  }
59
    
60
ISR (TIMER1_COMPA_vect)
61
{//Counter erreicht oben, zählt wieder runter
62
  zahl = 0x00;
63
  spi_send(zahl);
64
}
65
66
ISR (TIMER1_OVF_vect)
67
{ //Counter erreicht unten, zählt wieder hoch
68
  zahl = 0xFF;
69
  spi_send(zahl);
70
}

von Gerald B. (gerald_b)


Lesenswert?

Verstehe ich das jetzt richtig, das du PWM übers shiften erreichen 
willst?
Nimm Pin 13 Output Enable aller 595'er auf einen PWM Pin und schalte 
damit zyklisch die Ausgänge der Register ab. Das funktioniert ganz 
wunderbar. Habe ich an einer Uhr zum Dimmen der Anzeigen so gemacht :-)

Gruß Gerald

: Bearbeitet durch User
von Sören K. (foxalem)


Lesenswert?

Jap das vestehst du richtig.

Deine Idee finde ich super, einziges Problem ist nur, diesen PIN hab ich 
auf GND gesetzt weil ich dachte ich brauch ihn nicht. Die Platinen und 
alles sind schon fertig gelötet ;)

Lg

von Mike (Gast)


Lesenswert?

Sören Kleer schrieb:
> einziges Problem ist nur, diesen PIN hab ich auf GND gesetzt weil
> ich dachte ich brauch ihn nicht. Die Platinen und alles sind schon
> fertig gelötet ;)

Dumm gelaufen - schon geht es ab in die nächste Entwicklungsschleife.

von Sören K. (foxalem)


Lesenswert?

Brauchst noch eine Wurst zu deinem Senf Mike? Hauptsache was gesagt...

Ich hab jetzt im Compare-Interrupt-Vector eingetragen das er einfach den 
Wert togglen soll und schon funktionierts.
Ich hab die Interrupts einfach falsch eingesetzt. Aber danke Gerald für 
den Tip mit PIN13, auf dem Steckbrett konnte ich mir nun wenigstens mal 
angucken wie es auszusehen hat und ob meine Initialisierung etc. korrekt 
war ;)

Lg

von Mike (Gast)


Lesenswert?

Sören Kleer schrieb:
> Deine Idee finde ich super, ...
Anscheinend nicht "super" genug, um einen Pin anzulupfen ;-(

von Sören K. (foxalem)


Lesenswert?

Warum sollte ich denn meine Hardware abändern (was wirklich aufwändig 
wäre weil es alles sehr kompakt ist) wenn ich es Softwaremäßig einfacher 
lösen kann?

Ich werde es auf jeden fall für spätere Projekte im Hinterkopf behalten

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.