Dag mensen,
Ik ben al langere tijd programmeur en ben daarnaast wel eens wat aan het knutselen met elektronica (alleen heb ik nooit de 2 dingen gecombineerd)
Nu zou ik graag een klein projectje willen doen en een aantal rgb leds aansturen, ik heb hiervoor de ATMega168 gekozen.
Ik heb AVR Studio geinstalleerd, een programmer gemaakt en dergelijke. en ik ben al wat code aan het schrijven in C. Maar nu is het probleem: ik lijk geen duidelijke informatie te kunnen vinden over hoe ik nu eigenlijk 6 verschillende pwm signalen 0%-%100 op 6 pinnen kan krijgen.
Dus mijn vraag; hoe zou ik dit kunnen doen?
Alvast heel erg bedankt.
Roland van Leusden
It's the rule that you live by and die for It's the one thing you can't deny Even though you don't know what the price is. It is justified.
http://www.narobo.com/articles/squarewave.html en
http://www.ermicro.com/blog/?p=580
[Bericht gewijzigd door Roland van Leusden op (31%)]
@Roland van Leusden:
hoe heb ik die pagina over het hoofd kunnen zien!
, ziet er duidelijk uit, bedankt!.
@LED-Maniak:
had ik al op gezocht maar dit waren veel te algemene artikelen.
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Je vult wat registers in, en het werkt...
void PWM0_init(void)
{ // Initialiseer Timer0 voor fast PWM
TCNT0 = 0;
TCCR0A = _BV(WGM00) | _BV(WGM01) | _BV(COM0A1) | _BV(COM0B1);
TCCR0B = _BV(CS02); // Prescaler = 256
OCR0A = 32; // PWM = 1/8
OCR0B = 32;
DDRD |= _BV(PD5) | _BV(PD6); // PWM-uitgangen vrijgeven
}
void PWM1_init(void)
{ // Initialiseer Timer1 voor 8-bit fast PWM
TCNT1 = 0;
TCCR1A = _BV(WGM10) | _BV(COM1A1) | _BV(COM1B1);
TCCR1B = _BV(WGM12) | _BV(CS12); // Prescaler = 256
OCR1A = 32; // PWM = 1/8
OCR1B = 32;
DDRB |= _BV(PB1) | _BV(PB2);
}
void PWM2_init(void)
{ // Initialiseer Timer2 voor fast PWM
TCNT2 = 0;
TCCR2A = _BV(WGM20) | _BV(WGM21) | _BV(COM2A1) | _BV(COM2B1);
TCCR2B = _BV(CS22); // Prescaler = 256
OCR2A = 32; // PWM = 1/8
OCR2B = 32;
DDRD |= _BV(PD3); // PD3 = PWM-uitgang
DDRB |= _BV(PB3); // PB3 = PWM-uitgang
}
Door de OCRxy-registers aan te passen stel je de puls/pause-verhouding in.
@pros:
Bedankt voor het voorbeeld ik snap het bijna behalve,
- Dit is voor 3 kanalen , ik wil er graag 6
- Ik wil de snelheid graag koppelen aan de kloksnelheid van de microcontroller (dus dezelfde frequentie) hoe zou ik dat moeten doen?
- Hoe kan ik de duty cycle van 0%-100% (8bit) instellen via een functie?
als je me daar nog mee kan helpen is het me duidelijk 
@Ronald van Leusden:
De eerste link bleek niet bruikbaar te zijn ivm. allerlei dependencies op andere bestanden.
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Je kent de systeemklok. Laten we zeggen 8000000Hz.
Je wil een PWM-frequentie van bv. 200Hz.
Bij 8-bit PWM moet de klok voor het PWM kanaal dus (200 x 256) = 51200Hz bedragen.
Deel de systeemklok door de PWM-klok: 8000000 / 51200 = 156.
Kijk nu in de datasheet naar mogelijke waarden voor de prescaler.
Bij Timer2 kan je bv. 128 als prescaler nemen. Dan is de PWM-frequentie iets hoger dan gewenst.
Bij Timer1 heb je minder keus. Ofwel 64, ofwel 256. Dat wordt dus 64.
Wil je de maximale snelheid, zet dan de prescaler op 1:
TCCR0B = _BV(CS00);
TCCR1B = _BV(WGM12) | _BV(CS10);
TCCR2B = _BV(CS20);
Nu maakt dat voor het aansturen van LED's niet zoveel uit. Zolang je ze niet ziet flikkeren is het OK.
Moet het wèl precies, dan kan je bij sommige timers instellen tot waar ze moeten tellen.
Timer1 geeft bij de ATmegaxx8 de meeste mogelijkheden. Je kan hem --in Phase and Frequecy Correct mode-- laten tellen van 0 tot de waarde van ICR1 (1 ... 65535), en daarbij ook de puls/pause-verhouding instellen met een 16-bits getal.
Hoe kan ik de duty cycle van 0%-100% (8bit) instellen via een functie?
unsigned char duty_cycle = 12;
OCR0A = (duty_cycle * 2) + (duty_cycle / 2); // Vermenigvuldigen met 2.5
Op die manier haal je maximaal 250. Voor de meeste toepassingen is dat OK. Bij een LED zie je echt het verschil niet tussen 250 en 254 (en zelfs niet tussen 240 en 254).
Op 4 december 2010 18:55:49 schreef Mervin:
- Dit is voor 3 kanalen , ik wil er graag 6
Toch niet, elke teller stuurt 2 PWM kanalen aan. De pulsbreedte stel je in door OCRxA en OCRxB in te stellen.