Forum: Mikrocontroller und Digitale Elektronik Atmega8 und PWM


von jochen (Gast)


Lesenswert?

Hallo,

für ein kleines Übungsprojekt mit einem Atmega8 möchte ich 4 PWM-
Kanäle zum Regeln der Helligkeit von LEDs verwenden.

Im Datenblatt lese ich von "Three PWM Channels", den vierten Kanal 
möchte ich mit einem Timer realisieren.

Das ganze mit einem CAN-Interface, also benötige ich noch die 
SPI-Schnittstelle und zum Debuggen die UART-Port.

Nun stellt sich mir die Frage: geht das?

Im Datenblatt lese ich von PWM10 und PWM11, zusätzlich zu den drei PWMs 
benötige ich noch einen Timer.

Inwieweit kann ich diese Anfordrungen auf einem Atmega8 kombinieren?

Die Anforderungen an den PWM sind "überschaubar", die kürzesten 
Low/Highzeiten sind 10us; von der Theroie her sollte es also gehen, alle 
10us einen Interrrupt auszulösen und die IOs entsprechend im Pegel zu 
ändern. (gesetz dem Fall, dass keine drei PWMs unabhängig voneinander 
laufen, bzw den vierten PWM mus sich so realisieren).

rätselnde Grüße
jochen

von Ale (Gast)


Lesenswert?

Ich wurde es per soft machen, ein Interrupt je 10 us, 4 IOs als 
Ausgänge, 4 (lo)Register kein push/pop. sher einfach und schnell. Takt 
wurde ich 8 MHz (So du hast Zeit für CAN Prozesse)

von Karl H. (kbuchegg)


Lesenswert?

Ale hat recht.
Da du sowieso mindestens eine PWM in Software realisieren musst,
kannst du auch gleich alle 4 in Software realisieren. Dadurch
werden wenigstens alle 4 PWM identisch angesteuert und der
Programmaufbau vereinfacht sich.

Wenns nur ein Übungsbeispiel sein soll, würde ich
ganz einfach den Timer0 mit einem Overflow Interrupt
betreiben.
1
uint8_t PWMCounter;
2
volatile uint8_t PWM1;      // PWM Wert für LED 1
3
volatile uint8_t PWM2;      // PWM Wert für LED 2
4
volatile uint8_t PWM3;      // PWM Wert für LED 3
5
volatile uint8_t PWM4;      // PWM Wert für LED 4
6
7
ISR( TIMER0_OVF_vect )
8
{
9
  PWMCounter++;
10
11
  if( PWMCounter > 64 )  // oder wieviele PWM Stufen du brauchst
12
    PWMCounter = 0;
13
14
  if( PWM1 < PWMCounter )
15
    // Led 1 einschalten
16
  else
17
    // Led 1 ausschalten
18
19
  if( PWM2 < PWMCounter )
20
    // Led 2 einschalten
21
  else
22
    // Led 2 ausschalten
23
24
  if( PWM3 < PWMCounter )
25
    // Led 3 einschalten
26
  else
27
    // Led 3 ausschalten
28
29
  if( PWM4 < PWMCounter )
30
    // Led 4 einschalten
31
  else
32
    // Led 4 ausschalten
33
}

Durch zuweisen von Werten von 0 bis 63 regelst du dann die
Helligkeit deiner LEDs.

von Ulrich (Gast)


Lesenswert?

Der Hacker schrebit das natürlich so ;-)
1
PWMCounter = ++PWMCounter & 0x1F;


Ist aber genauso effektiv wie:

1
 PWMCounter++;
2
3
  if( PWMCounter > 64 )  // oder wieviele PWM Stufen du brauchst
4
    PWMCounter = 0;

Macht aber keinen so coolen Eindruck ;-)

von johnny.m (Gast)


Lesenswert?

> PWMCounter = ++PWMCounter & 0x1F;
Na, da hat der "Hacker" sich aber verhauen... Wohl eher "& 0x3F"...

von Bastelmensch (Gast)


Lesenswert?

>> PWMCounter = ++PWMCounter & 0x1F;
> Na, da hat der "Hacker" sich aber verhauen... Wohl eher "& 0x3F"...

HARHARHAR! Ich schmeiß mich weg!

von Ale (Gast)


Lesenswert?

Der richtige Hacker wurde es auf asm codieren !!!

PWM Werte auf r2,r3,r4,r5

r6 ergilt PWMCounter
r7 hat 0x3f
r16 scratch

__timer0_ovf_int:
  inc  r6
  and  r6,r7

  in   r16,PORTx
  andi r16,LED_MASK_ALLE_AUS
  cp   r2,r6
  brcc .+2
  ori  r16,LED0_AN
  cp   r3,r6
  brcc .+2
  ori  r16,LED1_AN
  cp   r4,r6
  brcc .+2
  ori  r16,LED2_AN
  cp   r5,r6
  brcc .+2
  ori  r16,LED3_AN

  out  PORTx,r16
  reti

So 20 Takte, nicht so schlecht :-)

Gruß

Ale

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.