Thanks Bruce Abbot, but according to the 25K22 specsheet bits 6 and 7 of CCP1CON are used for P1M advanced output configuration bits
Bits 6 and 7 can be ignored, but bits 2 and 3 must be set. See datasheet page 205:-
"REGISTER 14-1: CCPxCON: STANDARD CCPx CONTROL REGISTER
bit 3-0 CCPxM<3:0>: ECCPx Mode Select bits
11xx =: PWM mode"
Here's my working test code for MPLAB X. You may recognize some of it...
#include <xc.h>
void Init_TMR0()
{
T0CON = 0b01000111; // 8bit, internal clock, prescale 1:256
}
int DCyc;
void interrupt low_priority lp(void)
{
if (TMR0IF) //TMR0 overflow flag, if set triggers IRQ TMR0Clk=Clk/2
{ TMR0=63903; //Comp needed for 64Mhz, calibrates timer for 100uS/IRQ.
TMR0IF=0; //64736 -(13 to enter isr + 2 cnts dly) = 64721 expected but 63903 gives rock-solid 100uS
//--------------------SET PWM Duty Cycle-------------------------------
CCP1CONbits.DC1B0 = DCyc & 1; //set low bit
CCP1CONbits.DC1B1 = (DCyc >> 1) & 1; //set second lowest
CCPR1L = (DCyc >> 2); //sets DCycH hi 8 hi-bits
//DC1B0=n; syntax works as well in HT18
}
}
void PWM1Setup(void)//CCP1 output on RC2
{
TRISC2=0; //PWM requires the PWM pin TRIS'd as output
//
//Select 8-bit Timer: Choices TMR2/TMR4/TMR6,use CxTSEL<1:0> bits of CCPTMRS0
//C1TSEL=0x01; //TMR4 selected options are: 10=TMR6 00=TMR2 01=TMR4
CCPTMRS0=(CCPTMRS0 & 0xFC); //Mask to leave C3TSEL and C2TSEL unchanged
CCPTMRS0=(CCPTMRS0 | 0x01); //C1TSEL=0x01 TMR4 selected
/* Bit 7 6 5 4 3 2 1 0
------------------------------------------------------------------------
x 0 0 0 0 1 0 0
TxOUTPS<3:0>
POSTSCALER 1:1 to 1:16 TMxOn PRESCALER
1:1=00 01=1:4 1x1:/16
*/
T4CON=0b00000100;
//CCP1CON holds duty cycle LSb in bits<5:4>LSbs, but CCPR1L=MSbits
CCP1CON=0b0000
1100; //DCyc=0 off PWM1 channel,
mode = PWM// CCPR1L=(CCPR1L & 0xC0); //Mask P1M bits, MSbits of DCyc=0, CPR1H not used
PR4=0xFF; //overflow count 0XFF for 10-bit resolution for any PWM freq.
CCP1IE=0; // Disable CCP1 IRQ enable not used for PWM only mode
TMR4IE = 1; // enable TIMER4 interrupt
PEIE = 1; // enable peripheral interrupts
TMR4ON = 1; //Turn on TMR4 used for duty cycle period
}
//==== End of PWM1Setup ===================================
void main(void)
{
// Init_PIC();
Init_TMR0();
PWM1Setup();//Setup CCP1 cbit2 PWM
IPEN =1; //Priority interrupts enabled
//RCONbits.IPEN = 1; //also works 9.80
TRISB =1; //INT0IE sw on bbit0 ready with pullup to Vdd
//INT0IF=0;
//INT0IE=1;
TMR0IE=1;
TMR0ON=1;
TMR0IP=0;
TMR4IP=0;
TMR4ON=1;
TMR4IP=0;
TMR4IE=0;
CCP1IE=0;
CCP1IP=0;
// PIE1=1; //Not Needed for TMRx
// PIE2=1; //Not Needed for TMRx
PLLEN =1;
PEIE =1; //Needed for TMRx interrupts and A2D?
GIEL=1; //Enables Low-Priority if GIEH/GIE=1
GIEH=1; //Ok to use INTCONbits.GIE = 1; to enable all interrupts
//======================== START =======================================
DCyc=50;
while(1);
}