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
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)
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.
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 ;-)
> PWMCounter = ++PWMCounter & 0x1F;
Na, da hat der "Hacker" sich aber verhauen... Wohl eher "& 0x3F"...
>> PWMCounter = ++PWMCounter & 0x1F; > Na, da hat der "Hacker" sich aber verhauen... Wohl eher "& 0x3F"... HARHARHAR! Ich schmeiß mich weg!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.