PDA

View Full Version : LED PWM with High Frequencies?



RossWaddell
- 7th February 2013, 23:51
I've set up a PIC16F1825 to do PWM on CCP3/4 for motor control as follows:



' ************************************************** *************
' Set up registers for PWM on CCP3, CCP4
' ************************************************** *************

CCP3CON = %00001100 ; Use CCP3 in PWM mode (Motor 1)
CCP4CON = %00001100 ; Use CCP4 in PWM mode (Motor 2)


CCPTMRS = %00000000 ; Use Timer2

T2CON = %00000101 ; Timer2 on with 1:4 prescaler
PR2 = 62 ; For 16Mhz OSC the desired output freq of 15,873Hz is
; achieved with this PR2 value (8-bit resolution
; with 1:4 prescaler)

; PWM freq must be ~ 16-20kHz to reduce noise


I need to use a relatively high frequency value for the motors. My question is this: would it hurt the LEDs or otherwise be a bad idea to use the same frequency for LED PWM? I want to set up CCP1 with the same timer, prescaler & resolution as the motors so that I can include the LEDs in this loop to 'ramp up' the motors:



' Spin up motors to saved value of _MotorRPM
' (Below a value of 'MinDuty', the motors don't move at all)
FOR i = (MinDuty - PreSpinVal) to MotorRPM
DutyVar3 = i

IF PortEngDir = 0 THEN
DutyVar4 = i ' Port engine (CCP4), fwd (CCW)
ELSE
DutyVar4 = (MaxDuty - I) ' Port engine (CCP4), rev (CW)
ENDIF

CCP3CON.4 = DutyVar3.0
CCP3CON.5 = DutyVar3.1
CCPR3L = DutyVar3 >> 2

CCP4CON.4 = DutyVar4.0
CCP4CON.5 = DutyVar4.1
CCPR4L = DutyVar4 >> 2

pause SpinUpPause

#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [LCD_INST, LCD_CLR]
pause 5
HSEROUT ["RPM=", DEC i, " ", 13, 10] ' Send text followed by carriage return and linefeed
#ENDIF
NEXT i


I know of the SPWM_INT.bas include file from Darrel (which allows you to use 200Hz, high enough so no flicker is seen) but I don't know if I need to use that here instead of sharing Timer2 with the same high frequency as with the motors.

wdmagic
- 8th February 2013, 05:26
no it wont hurt the leds

RossWaddell
- 9th February 2013, 18:39
Thanks wdmagic.

Seems like trying to add PWM on ECCP1 is throwing a wrench into the existing motor speed control - the motor just turns 'on' (without ramping up) and the LEDs connect to RC5 are unlit. Is it because ECCP1 is taking control of some pins I'm already using? I think maybe there are additional registers/config I need to set in order to get a single PWM output on RC5.



' ************************************************** *************
' Pin Connections
' ************************************************** *************

' RA0 -> B pin of rotary encoder
' RA1 -> A pin of rotary encoder
' RA2/CCP3 -> Stbd motor PWM output (motor 1)
' RA3/MCLR -> Button switch pin of rotary encoder

' RA5/CCP2 -> PWM for flashing LEDs ?

' RC0 -> Stbd motor direction signal (motor 1)
' RC1/CCP4 -> Port motor PWM output (motor 2)
' RC2 -> Port motor direction signal (motor 2)
' RC4 -> Serial output (Tx)
' RC5/CCP1 -> PWM for steady-on amber LEDs
; This is also the only available Rx pin, so this might not work
; with plan to have 1 knob to control them all

DEFINE OSC 16 ; Set oscillator 16Mhz

OSCCON = %01111000 ' 16MHz internal osc

ANSELA = 0 ; Digital only for all PortA pins
ANSELC = 0 ; Diginal only for all PortC pins

TRISA = %00001011 ' Make PORTA pins 0-1 input for rotary encoder,
' pin 3 for rotary button
TRISC = 0

i VAR BYTE

MOTOR_1_DIR VAR PORTC.0 ' Alias PORTC.0 as "MOTOR_1_DIR"
MOTOR_1_PWM VAR PORTA.2 ' Alias PORTQ.2 as "MOTOR_1_PWM"
MOTOR_2_DIR VAR PORTC.2 ' Alias PORTC.2 as "MOTOR_2_DIR"
MOTOR_2_PWM VAR PORTC.1 ' Alias PORTC.1 as "MOTOR_2_PWM"

ButtonPress VAR PORTA.3 ' Alias PORTA.3 as "ButtonPress"

' ************************************************** *************
' Set up registers for PWM on CCP3, CCP4 & CCP1, CCP2
' ************************************************** *************

CCP3CON = %00001100 ; Use CCP3 in PWM mode (Motor 1)
CCP4CON = %00001100 ; Use CCP4 in PWM mode (Motor 2)
CCP1CON = %00001111 ; Use CCP1 in PWM mode (PWM for steady-on engine LEDs)
;CCP2CON = %00001100 ; Use CCP2 in PWM mode (PWM for blinking engine LEDs)

CCPTMRS = %00000000 ; Use Timer2 for all CCPs

T2CON = %00000101 ; Timer2 on with 1:4 prescaler
PR2 = 62 ; For 16Mhz OSC the desired output freq of 15,873Hz is
; achieved with this PR2 value (8-bit resolution
; with 1:4 prescaler)

; PWM freq must be ~ 16-20kHz to reduce noise

PreSpinVal CON 17 ; Value to subtract from MinDuty for motor spin up
MinDuty CON 75 ; 75 when max duty = 250 (8-bit resolution)
;SpinUpPause CON 17 ; Pause during motor spin up
SpinUpPause CON 7 ; Pause during motor spin up
MaxDuty VAR WORD ; According to Darrel Taylor:
; MaxDuty = (PR2 + 1) * 4

MaxDuty = (PR2 + 1) * 4 ; 252 but with prescaler resolution it's actually 250

DutyVar3 VAR WORD ; temp variable to store duty variable for CCP3
DutyVar4 VAR WORD ; temp variable to store duty variable for CCP4
DutyVar1 VAR WORD ; temp variable to story duty variable for CCP1

FOR i = 0 to MaxDuty
IF i <= MotorRPM THEN
; Spin up motors but only until saved value of MotorRPM is reached
DutyVar3 = i

IF PortEngDir = 0 THEN
DutyVar4 = i ' Port engine (CCP4), fwd (CCW)
ELSE
DutyVar4 = (MaxDuty - I) ' Port engine (CCP4), rev (CW)
ENDIF

CCP3CON.4 = DutyVar3.0
CCP3CON.5 = DutyVar3.1
CCPR3L = DutyVar3 >> 2

CCP4CON.4 = DutyVar4.0
CCP4CON.5 = DutyVar4.1
CCPR4L = DutyVar4 >> 2
ENDIF

IF i <= StdyOnLEDs THEN
; Fade in steady-on LEDs but only until saved value of StdyOnLEDs is reached
DutyVar1 = i

CCP1CON.4 = DutyVar1.0
CCP1CON.5 = DutyVar1.1
CCPR1L = DutyVar1 >> 2
ENDIF

pause SpinUpPause
NEXT i



How do I get just a single PWM on RC5 without affecting any other port pins?

wdmagic
- 10th February 2013, 03:16
Sorry I cant help you with that, I dont use that particular chip, and your using a bit of code that im unfamiliar with. Im used to only having 2 pwms, and using the hpwm command to output my signal.