PWM 20Khz with Spin
lardom
Posts: 1,659
I just got an LED to go from dim to bright at 20Khz in 20 stages with Spin. Spin is great! The pwm driver is based on an object written by W.G.Marshall. I have no scope so if flaws are found I'll appreciate it.
Top object:
Pwm driver:
Top object:
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ CPWGV : "CtrPwmFor 20Khz" PUB main | p CPWGV.Start repeat repeat p from 0 to 4_000 step 200 CPWGV.Main (p) waitcnt(clkfreq/20+cnt) repeat p from 4_000 to 0 step 200 CPWGV.Main (p) waitcnt(clkfreq/20+cnt)
Pwm driver:
VAR long tHa, stack[10] word cog PUB Start Stop cog := cognew(TestPwm, @stack) PUB Stop If cog cogstop(cog~ - 1) PUB main(j) tHa := j PUB TestPwm | tc, t, tInc ctra[30..26] := %00100 ' Configure Counter A to NCO ctra[5..0] := 1 ' Set counter output signal to P1 frqa := 1 ' Add 1 to phsa with each clock cycle dira[1]~~ ' P1 → output tInc := 200 ' Determine time increment tC := 4_000 ' Use time increment to set up cycle time tHa := tInc ' define tHa t := cnt ' Mark counter time repeat ' Repeat PWM signal phsa := -tHa ' Set up the pulse t += tC ' Calculate next cycle repeat waitcnt(t) ' Wait for next cycle
Comments
All that just to dim an LED, only one LED?. Plus 20kHz is over the top for this application too and LEDs are quite happy to run at much lower frequencies, at least a couple of hundred Hertz though to reduce flicker. Sorry (think Crocodile Dundee)
I dedicate a cog to PWM too when I need but I get up to 32 8-bit channels at 4.76kHz with it but this does not use the counter at all but rather a tight PASM loop built into Tachyon, and a wave table. With it you can also modify the waveform, at least so that some channels can run at higher frequencies with less resolution, in fact over 122kHz if you only want 16 levels.
I'll combine it with a potentiometer to control DC motors. The LED is my basic testing device. I also recently learned to use a mosfet @ 1Khz for current control so now I want to know if I can get one to work @ 20Khz.
In addition, I am going to have to learn PASM because I want to try building an AM transmitter/receiver pair. I'll take it step by step.
kuroneko, I first commented (+1) because the code still ran so I deleted it. Why do I need it?
Imagine you get no cog (all busy), IOW cog == -1 then you call stop which then kills cog 6 (we pass the if because cog is <> 0 and then stop cog -2 which is the same as 6 because only the least 3 bits are important). So in order to make the if cog work we translate cog IDs 0..7 to 1..8 (-1 would give us 0 == FALSE which is OK) by adding 1 to cognew's result. Another example, you get cog == 4, calling stop then kills cog 3 instead. See the problem here?