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:

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
For clockwise rotation of the DC motor, I use:

Code:
LOW MOTOR_1_DIR
DutyVar3 = 0
and inside the loop:

Code:
DutyVar3 = DutyVar3 + 1
This works! The motor spins CW slowly up to 250 (max duty cycle with prescaler of 1:4, according to Mister E's MultiCalc).

The problem is when I want to spin the motor CCW. For that, I use:

Code:
HIGH MOTOR_1_DIR
DutyVar3 = 250
and inside the loop:

Code:
DutyVar3 = DutyVar3 - 1
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).