Atmega8 und PWM

Gast #537023
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
#537030
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.
Gast #537053
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 ;-)
Gast #537317
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren