Thanks Darrel - I'll add that formula into the next round of changes once I get the basic PWM via registers sorted out.
Part of this thread was how to set PWM frequency/duty cycle via registers so I can use CCP3 & CCP4 on the PIC16F1825 (CCP1 & CCP2 are ECCP's). I have code to control DC motors via a SN754410 motor driver and while it works OK with pbp's HPWM I have to use CCP1 & CCP2 and changing the duty cycle in a loop (the motors have to spin up to the desired speed slowly) means that the HPWM command is changing more than just the duty cycle. So, wanting to learn how to do this via registers I came up with this simple test code:
For clockwise rotation of the DC motor, I use:Code:DEFINE OSC 16 ; Set oscillator 16Mhz ' *************************************************************** ' Device Fuses ' *************************************************************** #CONFIG __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF __config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF #ENDCONFIG OSCCON = %01111000 ' 16MHz internal osc pause 100 ' As advised by Darrel Taylor for EEPROM issue ANSELA = 0 ; Digital only for all PortA pins ANSELC = 0 ; Diginal only for all PortC pins TRISA = 0 TRISC = 0 MOTOR_1_DIR VAR PORTC.0 ' Alias PORTC.0 as "MOTOR_1_DIR" MOTOR_1_PWM VAR PORTA.2 ' Alias PORTA.2 as "MOTOR_1_PWM" ' *************************************************************** ' Set up registers for PWM on CCP3 & 4 ' *************************************************************** CCP3CON = %00001100 ; Use CCP3 in PWM mode T2CON = %00000101 ; Timer2 on with 1:4 prescaler PR2 = 62 ; For 16Mhz OSC the desired output of 15,873Hz is ; achieved with this PR2 value (8-bit resolution ; with 1:4 prescaler) i VAR BYTE DutyVar3 VAR BYTE ;LOW MOTOR_1_DIR ;DutyVar3 = 0 HIGH MOTOR_1_DIR DutyVar3 = 250 FOR i = 0 to 250 ; DutyVar3 = DutyVar3 + 1 DutyVar3 = DutyVar3 - 1 CCP3CON.4 = DutyVar3.0 CCP3CON.5 = DutyVar3.1 CCPR3L = DutyVar3 >> 2 pause 33 NEXT i Main: GOTO Main
and inside the loop:Code:LOW MOTOR_1_DIR DutyVar3 = 0
This works! The motor spins CW slowly up to 250 (max duty cycle with prescaler of 1:4, according to Mister E's MultiCalc).Code:DutyVar3 = DutyVar3 + 1
The problem is when I want to spin the motor CCW. For that, I use:
and inside the loop:Code:HIGH MOTOR_1_DIR DutyVar3 = 250
This almost works: the motor spins CCW slowly up to max speed but then when the loop is over (and presumably the motor is spinning its fastest) it just stops. Am I using the wrong register settings when I want to count backwards from the maximum (with the SN754110, if the motor direction pin is HIGH then the motor speed starts at the opposite end of the duty cycle range).Code:DutyVar3 = DutyVar3 - 1




Bookmarks