Ik ben op zoek naar een manier om een master te maken voor 3 PWM kanalen. Ik gebruik hiervoor een Atmega88 met hardware PWM in ASM.
Ik krijg vier waardes binnen CH1, CH2, CH3 en CH4. Waarvan CH4 de master moet worden. De drie andere kanalen worden momenteel direct naar de hardware PWM gestuurd worden. Ik ben hier al even mee aan het klooien maar het lukt me maar niet om een goede eenvoudige manier te vinden.
Hoe kan ik dit het beste aanpakken?
Videomodulator
AKA Naftebakje @Tweakers.net --- Zonder dwarsliggers geen spoor
Wat moet de master doen?
-een minimale PWMwaarde opgeven: tel de master bij de kanaalwaarde (let op voor het maximum).
-een maximale PWMwaarde opgeven: trek de master af van de kanaalwaarde (let op voor het minimum).
Bij beide bovenstaande manieren krijgt de grafiek een knik ( _/ ) en heb je onder/boven een bepaalde waarde geen verschil in dimming,maar dit is waarschijnlijk wat je wil.
-de dimming lineair scalen naar een beperkt gebied, hierbij zal je nog de volledige range van de 3 kanalen kunnen gebruiken, maar reken je dit om naar een beperkt bereik (bepaald door de master). Dit zuipt rekenkracht, is moeilijker te implementeren maar geeft een mooiere gebruikerservaring. Hiervoor zal je de master moeten vermenigvuldigen met de kanaalwaarde, en weer delen door 255 (als je 8-bits werkt).
Ik zal graag een master willen maken die met een vermenigvuldigingsfactor werkt. Dus als CH1_in op 50% staat en master op 50% dan moet CH1_out op 25% staan.
Ik zat daarom eerst te denken om CH1_in te vermenigvuldigen met een 0 tot 1 factor. Maar door inderdaad eerst CH1 * master / 255 te doen kom je er ook. Enige probleem waar ik dan tegen aan loop is de 8/16 bit omschakeling die je dan krijgt. En hoe ik kan delen in ASM.
Videomodulator
AKA Naftebakje @Tweakers.net --- Zonder dwarsliggers geen spoor
Vermenigvuldigen is en blijft een pijnpunt bij simpele µC die hier geen module voor heeft, maar het is haalbaar.
Je zal in ASM een vermenigvuldigingsmodule moeten maken, door op te tellen (3*50 = 50+50+50), waarin je rekening houdt met de overflow-bit (in een PIC zit die in het status-register), om zo een 16 bits getal (2 bytes) te bekomen, en daarvan gebruik je dan de hoogste byte.
Je mag het gerust proberen met een kommagetal tussen 0 en 1, maar floating point getallen zijn nauwelijks te doen in een µC.
Delen in een µC die enkel + of - kan zou je kunnen doen met de klassieke staartdeling, maar daar ga je hoofdpijn van krijgen. Gebruik beter de truuk van bitshiften, daarmee kan je factoren van 2 vermenigvuldigen of delen.
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
De ATmega88 beschikt over een aantal multiply-instructies, die twee 8-bit registers met mekaar vermenigvuldigen en het resultaat in een 16-bit registerpaar plaatsen.
Delen is er niet bij. Daar zal je zelf het nodige voor moeten bedenken.
Programmeren in C is ook een optie. Dan neemt de compiler al dat vervelend werk uit je handen.
Het is me gelukt om een master in te bouwen. Ik heb hiervoor de MUL instuctie gebruikt.
mul ch1,master ;ch1 x master
out OCR0A, r1 ;Product High naar uitgang
Eigenlijk een hele simpele code maar werk wel. Er word eerst vermenigvuldigd en daarna het bovenste byte product naar de uitgang geschreven.
Bedankt voor jullie reacties.
Toepassing:
Ik heb in ASM een DMX code geschreven met interrupts op een Atmega88. Voor 3 kanalen PWM met 1 master. Deze werkt nu en heb ik ook op mijn site gepost. Zie hier: http://www.renebiemans.nl/page.php?al=DMXAVR