Guys, I've been working on using Hardware PWM to control the speed of a 12v dc motor connected through a Mosfet. I'm using 2 buttons to speed up and speed down. It works really well with a PWM frequency above something like 4kHz. If I try to go below that frequency, it acts goofy. For example, below is my code for PWM at 3kHz. The way I understand it, I should get 0% - 100% for a CCPR1L from 0 - 333. For these lower frequencies, if I slowly increase the DUTY cycle up to about CCPR1L =75 it ramps up to 100%. They it stays at 100% until ~CCPR1L =260 at which it instantly drops to 0%. From CCPR1L =260 to 333 it again ramps up to 100%. It does the exact opposite when I ramp down in speed. Does anyone have a clue why this is happening? If I reset the code for anything from like 4kHz and up to work exactly as it's suppose to. I really think it's a software issue, but I'm not sure. I really want to run at lower frequency (don't care about audible noise) to minimize switching losses. Help?!?!?! Thanks, Gary ________________________________________ duty var word btnwk var byte clr con 1 'LCD clear screen instruction I con 254 'Instruction prefix value '******** Initialize *************************************** TRISA = %000000 'Set porta = output TRISB = %11111100 'set RB2:RB7 = input TRISC = %00000000 'Set portc = output btnwk=0 PORTC.2=0 'try to keep it from jumping when 12v connected OPTION_REG = %10000111 'set timer source as internal instuction cycle clock 'assign prescaler to tmr0 (not WDT) 'set prescaler to 1:64 INTCON = %10100000 'enable the tmr0 interrupt (intcon) 'Enable Global Interrupt Enable bit 'Disable RB0 interrupt ADCON1 = %00000110 'Make PortA into digital I/O instead of analog I/O PR2=332 'Set PR2 to 3 kHz TRISC.2=0 'Set CCP1 bit as output T2CON=%00000100 'Timer on prescale is 1 CCP1CON=%00001100 'Set to PWM Mode duty=0 CCPR1L = duty 'Set Pulse width - CCPR1L must be less than PR2. 'Lower number(pulse width) 'PR2 value is 100% duty cycle. 'PR2/2 = 50% duty cycle. '******** Main Program ************************************* DEFINE BUTTON_PAUSE 50 'change button pause to 50 milliseconds main: if duty > 60000 then 'did this b/c if <0, it rolls over to 65676 duty = 0 endif if duty > 333 and duty < 1000 then 'for 3khz operation duty = 333 endif CCPR1L = duty 'Set Pulse width - CCPR1L must be less than PR2. 'Lower number(pulse width) 'PR2 value is 100% duty cycle. 'PR2/2 = 50% duty cycle. serout 1,n9600,[I, clr] 'Clear LCD screen serout 1,n9600,[" ", #duty] 'Display seconds variable on LCD button PORTB.3, 1, 255, 255, btnwk, 1, speedup button PORTB.2, 1, 255, 255, btnwk, 1, speeddown goto main speedup: duty=duty+15 'for 3khz operation goto main speeddown: duty=duty-40 'for 3khz operation goto main -- http://www.piclist.com hint: PICList Posts must start with ONE topic: [PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads