PDA

View Full Version : 18F4431 - Complementary mode PWM



AndrewC
- 29th April 2009, 19:41
I'm using the power control module of a PIC18F4431 to control some Constant current sources for some high power leds. For these CCS devices a "1" = "off" so I though to myself why not use the complementary mode on the PWM module then on my even channels I'll get 1's and on the odds 0's. Wrote a little code to ramp the leds up and down but the even channels are staying at full power while the odds are ramping as expected. If i put it into independent mode all leds ramp together so it isn't something I've snafu'd on the ccs connections.

Here's the code, any idea where I'm going wrong ?

define OSC 20
Duty Var Word

PORTB = 0 ' clear port
TRISB = %11000000 ' PWM0,1,2,3,4,5 outputs

' set up PWM
DTCON = 0 ' 0 dead-time
PTCON0 = %00001000 ' 1:1 postscale, 1:16 prescale, free running mode
PTCON1 = %10000000 ' PWM time base is ON, counts up
PTPERL = $E8 '
PTPERH = $07 ' PTPER = $07E8
PWMCON0 = %01000011 ' PWM 0 to 5 outputs enabled , complementary
PWMCON1 = 1 ' updates enabled and overrides sync
OVDCOND = %11111111

RAMP:
For Duty = 2024 To 0 STEP-1 '
PDC0L = Duty.LowByte
PDC0H = Duty.HighByte
PDC1L = Duty.LowByte
PDC1H = Duty.HighByte
Pause 5
Next Duty

For Duty = 0 To 2024 '
PDC0L = Duty.LowByte
PDC0H = Duty.HighByte
PDC1L = Duty.LowByte
PDC1H = Duty.HighByte
Pause 5
Next Duty

GoTo RAMP

End

Thanks, Andrew

Dave
- 29th April 2009, 21:02
AndrewC, It looks like its time for an inverter or transistor...

Dave Purola,
N8NTA

AndrewC
- 29th April 2009, 21:19
AndrewC, It looks like its time for an inverter or transistor...

Dave Purola,
N8NTA

... or even just calculate new_duty= period-old_duty but I'd like to figure out how to make it work ;)

Darrel Taylor
- 29th April 2009, 21:26
Hi Andrew,

I'm not very familiar with the PWM modules on those chips.
But Bruce did an example with a scope image of the output, and the waveform looks like what you want. But the register settings look completely different.

using the pwm's in pic18f2431-2331-4331-4431
http://www.picbasic.co.uk/forum/showthread.php?p=43820#post43820
<br>

Bruce
- 29th April 2009, 21:46
If you set a fixed duty cycle of 50% it should work pretty much the same in either mode.

But if you're going to cycle through changing the duty cycle, you're better off using it with
independent mode for driving LEDs.

Look at the attached graphic. Note how signal 0 & signal 1 would make it look like one LED
was on all the time, while the other was off all the time. Complementary mode is for driving
N channel & P channel motor drivers. It's a lot different than standard PWM.

If the duty cycle was say 70%, one pin would be high for 70%, the other would be low for
70% since they're complementary.

Signals 2 & 3 are in independent mode, so the high duty cycle is the same for each pin.

AndrewC
- 29th April 2009, 22:51
Thanks for the answers.

Darrel: thanks for the pointer to Bruce. I've got the registers set for a much lower frequency than Bruce's example - my CCS can only work at 200Hz max so I should be running at 154Hz with the values I've picked. Also I made sure with OVDCOND that nothing is over riding the PWM. Well, that's what I think I was doing :)

Bruce: so what I want is the behaviour you show for 0 and 1, I want to output the inverse of the programmed duty cycle. What I see is PWM.1 ramping up and down while PWM.0 seems to stay constant. If i put them into independent mode (PWMCON0 = %01000011) then PWM.0 and PWM.1 ramp up and down together - same as your signals 2 and 3 - which sanity checks my wiring.

Alas I don't have a logic analyser (until a parcel arrives from Saleae) to check so I'm basing my judgement on the led intensity.

What I'm using this for is LED illumination of a macrophotography stage - in continuous PWM I get what we call modelling light then for an actual shot I'm planning to switch to a single shot so I can get aligned "strobe" pulses of three different lengths from a group of three PWM outputs. There are undoubtedly many different ways to do this but I thought it was an elegant way of using the 18F4431 capabilities, if I can figure out where I've gone wrong.

rgds, Andrew

Bruce
- 30th April 2009, 00:03
Hi Andrew,

I think I see the problem. Give this a shot and let me know how it looks;


DEFINE OSC 20
Duty Var Word

PORTB = 0 ' clear port
TRISB = %11000000 ' PWM0,1,2,3,4,5 outputs

' set up PWM
DTCON = 0 ' 0 dead-time
PTCON0 = %00001000 ' 1:1 postscale, 1:16 prescale, free running mode
PTCON1 = %10000000 ' PWM time base is ON, counts up
PTPERL = $E8 '
PTPERH = $07 ' PTPER = $07E8
PWMCON0 = %01000000 ' PWM 0 to 5 outputs enabled , complementary
PWMCON1 = 1 ' updates enabled and overrides sync
OVDCOND = %11111111

RAMP:
For Duty = 8000 To 0 STEP-1 ' ~3.2% to ~99%
PDC0L = Duty.LowByte
PDC0H = Duty.HighByte
PDC1L = Duty.LowByte
PDC1H = Duty.HighByte
Pause 5
Next Duty

For Duty = 0 To 8000 ' ~99% to ~3.2%
PDC0L = Duty.LowByte
PDC0H = Duty.HighByte
PDC1L = Duty.LowByte
PDC1H = Duty.HighByte
Pause 5
Next Duty

GoTo RAMP

End

AndrewC
- 30th April 2009, 17:52
Hi Bruce, yes that worked (but I would expect nothing less from you :) )

But why ?

- I've got a period of $07E8 which is 2024 in decimal
- I ramp duty to 2024 which is seems is not 100% of a period (led watching was misleading, I guess, because one channel was ramping 0-25% (?) and the other 100-75% which isn't really much of a change in output intensity)
- so why does a duty cycle of 8000 get me 99% ?

Andrew

Bruce
- 1st May 2009, 13:21
0 TO 2024 wasn't giving you enough range.


' At 20MHz, to figure a PWM frequency of 19.455kHz
'
' TPWM = time period of PWM frequency
' PTPER = 12-bit period register PTPERL and PTPERH
' PTMRPS = PWM time base prescaler
'
' (PTPER+1)*PTMRPS 257
' TPWM = ---------------- = ------------ = 0.0000514
' Fosc/4 5000000
'
' Frequency = 1/TPWM = 1/0.0000514 = 19.455kHz
'
' PWM resolution (bits resolution for duty cycle)
'
' log(PTPER+1)*4) 3.01
' Resolution = ------------------ = ----------- = 10 bits
' .301 .301

You have PTPER at 2024. PTMRPS at 16. Plug these into the above, and you get 0.00648.
1/0.00648 = 154.32 so you have a PWM frequency arouund 154hZ.

Your resolution is about 13-bits. %0001111111111111 = 8191.

So 8000 instead of 2024 is just giving you full range duty cycle.

AndrewC
- 1st May 2009, 14:36
Got it now, for some reason I had it in my head that the calculated resolution was just a max you could go to - not the actual max you had to go to for 100% duty cycle.

Thanks for the guidance - where's the book ? :) !!!

Andrew

elbinaz
- 14th December 2011, 20:41
Hi
I am using 18f4431 ,too.I want to run AN900 (microchip).I were unable to send.This program ,it works isis.But I were unable to run 18f4431.
Please help me.
Thanks

mark_s
- 14th December 2011, 22:37
Hi,
Without your code it's hard to say. But if it runs in isis and not in the actual circuit.
The problem is probably in your configuration settings. Did you set the High-side/low-side transistor polarity?
Post your code and configurations and someone will help.

elbinaz
- 15th December 2011, 11:23
Hi Mark_s , I would like to apologize for that I enter conversation between. I am new in the pic issue.I &nbsp;dont know configuration settings.Only do you need to hex file?
https://rapidshare.com/files/854468532/AN900DNM.rar