Please Help Me Understand PWM Operation Diagram (PIC18F25K22) - Page 1
Forum section: electronics / general

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 21, 2015, 10:04:46 pm
content: I have carefully RTFM about PWM yet still seem to not get "it", how to get my PWM to work.I am trying to get the RC2 CCP1 pin to work with TMR4 for approx 20KHz 10-bit PWM operation with internal clock set at 64MHzI get ziltch at the output.Attached is the Microchip specsheet diagram of PWM operation..I cannot seem to get to understand how PWM works from studying this carefully.Here's what I think I know, it is not enough to get this !#@^@& PWM to work:1)I fully understand PWM as a dutycycle controlling method using a timer to generate a fixed frequency free-running oscillator that has its high(on) time (dutycycle) controlled by PWM register settings.2)I fully understand how PWM might work:A fixed frequency oscillation is created with by using a (usually 8-bit) clocked counter to reach a full count at some period(freq., i.e. say approx 20KHz) and this counter is setting an output pin high on at count zero and at overflow.If there is no match with a comparator a fixed value(dutycycle setting) the output will remain high indefinitely.If the counter does count up to a value that matches the comparison value(aka duty cycle), then the output pin is set low for the remainder of the count until a counter overflow sets the output pin high again at counter overflow.To increase the resolution of a PWM, the counter overflow increments a a few bits of a concatenated secondary counter to increase the 8-bit's counter overflow period to something like 10 bits. In this case the counter then must overflow as many times as necessary to cause and allow setting a 10-bit match to cause the PWM output to be reset and set high again at overflow.A prescaler or postscaler for the 8-bit PWM counter can lower the PWM freq. as needed by dividing the system clock by some binary ratio.By allowing the 8-bit counter to only reach some fraction of the max 256(8-bit) overflow, the 8-bit counter count can be fed to a comparator whose purpose is increase the PWM frequency by having it reach a max count <overflow at some value. like only 64 or 128 counts, thus decreasing the period(count) of overflow, at the expense of PWM resolution.Therefore resolution is set only by the binary ratio of the comparison clock to the 8-bit clock?So why does the specsheet offer this silly(difficult to understand) formula to calculate resolution?Resolution in bits = ( LOG(4 * (PRX+1) )/2It would seem to me that to get 10-bit resolution of duty cycle using an 8-bit PWM freq, the comparison would require using a clock running 4x as fast, synchronizing the start of the 8-bit PWM counter to the 10-bit comparsion 4x as fast counter.That being said, I don't quite understand the diagram taken from the PIC18Fx5K2x specsheet.It shows the output of the 8-bit concatenated counter toggling the RS flipflop, but RS flipflops don't toggle, they do set/reset. I also don't understand what that line from the lower comparator to the TMRX block and S pin of the S/R FF.I also don't understand why two bits of the system clock are used for comparison.But in any case, either by not enough RTFM or by a coding error, I do not have all the settings required or correctly set to get the ball rolling.I can choose from three clocks and a handful of output or multiple bridge output pins.I only want one PWM output pin, RC2 CCP1Is it just me or I am missing something?

author: Andy Watson
author_rank: Super Contributor
timestamp: June 22, 2015, 12:23:25 am
content: Quote from: SuzyC on June 21, 2015, 10:04:46 pmCan I suggest the following interpretation of Figure 14-4: The two extra bits are "concatenated" at the low end of TMRx, not at the overflow end. I.e. the value in TMRx represents the high-order bits of the count, the two low-order bits come from either Fosc or the prescaler.QuoteYou only have 8 bits to define PRx. As stated above, these bits represent the high-order bits of the totalperiod. I.e you can only define the repetition frequency to a resolution of 8 bits.QuoteEr ... not on the diagram that I can see!I see the lower comparator causing the timer (TMRx) to be reset to zero (I assume) and the flip-flop to be SET. I think the line that extends up to the arrow that links CCPRxL to CCPRxH is indicating that the value in CCPRxL is loaded into CCPRxH when the lower comparator trips.The upper comparator RESETs the flip-flop when the value in TMRx and the extra two low bits match the 10 bits defined in CCPRxL plus CCPxCON<5:4>In summary: The value in PRx defines the upper 8 bits of the PWM period (frequency). The value in CCPRxL+ CCPxCON<5:4> defines the ON duty period. TMRx is clocked at a quarter of whatever clock source you've selected.

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 22, 2015, 01:07:37 am
content: Hmmm, my dear Watson, I still don't get it, if they concatenate at the lsb or msb it still creates the same bit-length counter that feeds into a comparator.I wish Microchip would have included a waveform diagram that showed the simultaneous behavior of clocks and counters and comparators and logic in PWM operation, or even better, a C-code example on how to setup at least one of the many PWM possible pin outputs.

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: June 22, 2015, 08:43:39 am
content: Quote from: SuzyC on June 22, 2015, 01:07:37 amThe total number of bits is the same either way, but you need to stuff the bits into the correct places or else you won't get the PWM ratio you were expecting. If you want 8 bit PWM then just load the 8 bit value into CCPRxL. For 10 bit PWM you must put bits 1-0 into CCPxCON 5-4, and bits 9-2 into CCPRxL.QuoteThis is the standard PWM block used in most PIC chips, so it shouldn't be hard to find code examples.Basic operation is quite simple; 8 bit TMRx counts up until it matches the value in PRx. This is the PWM period. The output pulse is set high at the start of the cycle, and reset low when the value loaded into CCPRxL matches the count in TMRx. If CCPRxL = 0 then the output latch is held in reset and the pulse never starts. If CCPRxL is larger than PRx then a match never occurs and the output stays high throughout the PWM cycle.10 bit resolution is achieved by adding 2 extra bits from CCPxCON, which is compared to 2 bits from the prescaler. This makes the PWM pulse 'step' 4 times faster, quadrupling the resolution without effecting the period.QuoteIf you have loaded reasonable values into CCPRxL and PRx then either you aren't in PWM mode or you haven't configured the output module or I/O pins correctly.

author: H.O
author_rank: Frequent Contributor
timestamp: June 22, 2015, 08:57:30 am
content: QuoteNow that formula isn't quoted quite correct, it should be Resolution in bits = LOG [4*(PRX+1)] / LOG(2). So if you set PRX to, lets say, 103 then that turns out to something like 8.7bits which isn't quite 9 bits but still more than 8.....In reallity it means that the dutycycle register(s) can be set to anything between 0 and 415 for a 0 to 100% dutycycle.QuoteCorrect, and that's exactly what's happening due to the timbase beeing concatenated by the two bits of the internal Fosc/4 divider making it 10bits wide. The RS Flipflop ain't it.EDIT:QuoteThat IS where the 2 bits of extra resolution is comming from.

author: mikerj
author_rank: Super Contributor
timestamp: June 22, 2015, 10:37:28 am
content: Quote from: SuzyC on June 21, 2015, 10:04:46 pmCalling functions you don't understand as 'silly' is hardly constructive.The PWM resolution is simply determined by the maximum value the internal counter reaches before being reset (i.e. 1 PWM period) which is calculated by 4*(PRx+1).Two additional bits are added to PRx within the PIC to improve the resolution, which is why the register value is multiplied by 2^2 = 4. A value of one is first added to the PRx value, since by design a PRx register value of zero yields a period of 4 clock cycles.To determine the number of bits required to represent an arbitrary number, you simply take LOG base 2 of that number.Resolution = LOG2(4*(PRx+1))Since pocket calculators typical don't have a LOG Base 2 function, the LOG identity LOGy(x) = LOGb(x)/LOGb(y) has been added to convert the result of an arbitrary base LOG (e.g. base 10 for a pocket calculator) to a base 2 LOG, i.e. LOG2(x) = LOGb(x)/LOGb(2).So:Resolution = LOG(4*(PRx+1))/LOG(2)simply calculates the number of clock cycles in one PWM period, and then calculates the number of bits required to hold that value, which yields the resolution in bits.

author: android
author_rank: Regular Contributor
timestamp: June 22, 2015, 11:17:35 am
content: Hi SuzyC,You may find thisPWM calculator spreadsheetthat I put together a while back helpful. It displays a chart that illustrates the various interactions between the MCU freq, PWM freq and prescaler settings that you select. I used LibreOffice Calc - I'm not sure what it looks like in Excel.

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 22, 2015, 12:44:54 pm
content: Thanks to all for your help, but I am not yet quite getting it, CCP1 RC2 output is still steady at Vss.For instance, suppose I have battery-operated device and I want to know what is the lowest system clock freq. usable and still have 10-bit resolution.I can see that in all cases, at any freq, the PRx value must be 0xFF for 10-bit resolution, so this is no secret, but why I call the specsheet formula silly is that it doesn't help get the answer for the selecting the lowest practical PWM freq.I realize as clock speeds get slower and slower, PWM freq. falls to a freq. that fails to be blink'n practical for LED MTPX'ing, motor control or PWM voice synthesis.Microchip fails helping a designer to get this coding task done quickly, and this is due just to poor technical writing.What is simply required in the specsheet is simply a chart or graph of System Clock v. PWM Freq. v. Bit Resolution.Thanks Android, you seem fully qualified for and should seriously try to apply for a tech writer position at Microchip.I downloaded the .odb file and it loads successfully into Excel 2007 and yet yields a blank spreadsheet.

author: H.O
author_rank: Frequent Contributor
timestamp: June 22, 2015, 03:51:55 pm
content: QuoteThere is no lower limit. You can run your PIC at 32kHz and STILL get a PWM signal with 10 bit resolution out of it.ThehighestPWM frequency, while maintaining 10 bit resolution will always be Fosc / 2^10. So at 32.768kHz the PWM frequency can not be higher than 32Hz in order to maintain 10bit resolution, or 128Hz to maintain 8bit resolution and so on.

author: picandmix
author_rank: Frequent Contributor
timestamp: June 22, 2015, 04:23:47 pm
content: To help you prove things are still working ok on your system here is a .hex file with a pwm example that puts out approx 25% duty on RC2 and 75% on RC1

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 22, 2015, 04:50:07 pm
content: Thanks picandmix for the help and .hex file, but I already know my HW is working correctly from previous test programs and a .hex file gives me no C-code insight of what I might be coding wrong.Thanks, H.0, this gives idea what the lower system clock freq. limits are and PWM freq. at the very lowest of Fosc.This is what I have so far: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 bitCCP1CONbits.DC1B1 = (DCyc >> 1) & 1; //set second lowestCCPR1L = (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=TMR4CCPTMRS0=(CCPTMRS0 & 0xFC); //Mask to leave C3TSEL and C2TSEL unchangedCCPTMRS0=(CCPTMRS0 | 0x01); //C1TSEL=0x01 TMR4 selected/* Bit 7 6 5 4 3 2 1 0------------------------------------------------------------------------x 0 0 0 0 1 0 0TxOUTPS<3:0>POSTSCALER 1:1 to 1:16 TMxOn PRESCALER1:1=00 01=1:4 1x1:/16*/T4CON=0b00000100;//CCP1CON holds duty cycle LSb in bits<5:4>LSbs, but CCPR1L=MSbitsCCP1CON=00000000; //DCyc=0 off PWM1 channelCCPR1L=(CCPR1L & 0xC0); //Mask P1M bits, MSbits of DCyc=0, CPR1H not usedPR4=0xFF; //overflow count 0XFF for 10-bit resolution for any PWM freq.CCP1IE=0; // Disable CCP1 IRQ enable not used for PWM only modeTMR4IE = 1; // enable TIMER4 interruptPEIE = 1; // enable peripheral interruptsTMR4ON = 1; //Turn on TMR4 used for duty cycle period}//==== End of PWM1Setup ===================================void main(void){Init_PIC();Init_TMR0();PWM1Setup();//Setup CCP1 cbit2 PWMIPEN =1; //Priority interrupts enabled//RCONbits.IPEN = 1; //also works 9.80TRISB =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 TMRxPLLEN =1;PEIE =1; //Needed for TMRx interrupts and A2D?GIEL=1; //Enables Low-Priority if GIEH/GIE=1GIEH=1; //Ok to use INTCONbits.GIE = 1; to enable all interrupts//======================== START =======================================Start:DCyc=50;goto Start;

author: picandmix
author_rank: Frequent Contributor
timestamp: June 22, 2015, 05:48:03 pm
content: Rather lost in all your C code above.This is how its done in Assembly, am sure you could readily convert it to run in C; believe you can also run Assembly code within C, though no idea how.Code:CONFIG3H CCP2MX = PORTC1pwm_setup; sequence from datasheetmovlw b'11111001' ; period = 2000 hz at 4mhz with tm2 prescaler 4movwfPR2clrfCCPR1L; set pwm1 duty to zeroclrfCCPR2L; set pwm2 duty to zerobcfTRISC,2; ensure /set ccp1/2 ports to outputbcfTRISC,1movlw b'01111100'; tmr2=ON,pre=1:4movwfT2CONbsfT2CON,TMR2ONmovlwb'00111100'; set ccp1 to pwm modemovwf CCP1CONmovlw B'00111100'; set ccp2to pwm modemovwf CCP2CONpwm_runmovlw0x4F; raise LED1 PWM to start value of 0xnnmovwfCCPR1Lmovlw0xAF; raise LED2 PWM to start value of 0xnnmovwfCCPR2L

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 22, 2015, 06:08:01 pm
content: Thanks picandmix, but I am totally lost in assembly, it is hard enough to troubleshoot complex operations in C, I would imagine going to even a lower level would be an horror.Update: I put a test bit in main() to blink a LED if the TMR4>0 (LED on), if TMR0>250 (LED on RC3 off)Test LED turns on and briefly off, Means TMR4 is resetting on 256.. PR4, but no CCP1 pin output

author: picandmix
author_rank: Frequent Contributor
timestamp: June 22, 2015, 07:44:41 pm
content: Quote from: SuzyC on June 22, 2015, 06:08:01 pmThats all the code needed, added to the flasking led program, to set up and run pwm in assembly, do not think it could be much less.As I say, I do not know C, but to me it looks like you are investigating every bit of every register and including them all in your code.Probably many not needed as you can simply rely on the register default values.Forgive asking, but have you tried using a C tutorial to get you going more easily, there are a few still left around, heres one.http://www.electro-tech-online.com/articles/nigel-goodwins-tutorials-in-c.467/

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 22, 2015, 07:58:29 pm
content: Thanks picandmix, I have written 100's of complicated C-language programs that work, I think I understand C well-enough.Its this chip that's the problem.

author: lewis
author_rank: Frequent Contributor
timestamp: June 22, 2015, 08:35:21 pm
content: Here's some abridged code that I've used on the 18F45K22 in a product.The errata mentions the PWM does not work with CCP3, 4 or 5:http://ww1.microchip.com/downloads/en/DeviceDoc/80498B.pdfThe 10us delay in the main() function is very important for some reason. The ECCP module would not start up without it and I never figured out why. Could be a software bug, but I pared everything down to try to understand it, no joy.The pwm_init() function configures the ECCP module to use auto-shutdown triggered by the comparator. It also uses pulse steering. This is single output PWM, not half-bridge or full-bridge.It's all in the datasheet! (except the 10us delay bit, as I say, my PWM wouldn't work without it for some unknown [to me] reason).Code://outputssbit MOT at LATD5_bit; //PWM output for motorsbit MOT_TRIS at TRISD5_bit; //TRIS bit for PWM output#define MOT_PWM 0b0010//sets PWM duty cycle. Takes unsigned int as duty value, splits off LSBs to DC1B bits, the rest goes into CCPR1Lvoid pwm_set_duty(unsigned int duty) {if(duty >= 1023) duty = 1023; //ensure duty cycle does not go too farCCP1CON.B4 = lo(duty).B0; //set lsbs in ccp1con registerCCP1CON.B5 = lo(duty).B1;CCPR1L = (unsigned char)(duty>>2); //lop off LSBs, MSBs to register.}//initialise pwm. requires comparator to have been configured previously//comparator config not shown in code belowvoid pwm_init() {pwm_set_duty(0); //default zero duty cycleMOT = 0; //drive output latches lowMOT_TRIS = 1; //set outputs as inputs to prevent spurious signals, we have an external pulldownT2CON = 0; //turn off timerPR2 = PR2_CONFIG; //set period registerTMR2 = 0; //reset TMR2PSTR1CON = 0b00010000 | MOT_PWM; //steer on next pwm period, set correct output to driveCCPTMRS0 = 0; //all pwm uses tmr2CCPTMRS1 = 0; // " " " "ECCP1AS = 0b10110000; //auto shutdown enabled, comparator 1 source, drive all pins low on faultPWM1CON = 0; //auto restart disbaled for now, 0Tosc delay after fault.CCP1CON = 0b00001100; //Enhanced PWM, single output, P1A (steerable) active highCCPR1L = 0; //definitely zero duty cycleMOT = 0; //ensure output latches are low ready for TRISMOT_TRIS = 0; //set outputsT2CON = T2CON_CONFIG; //start the timerPWM1CON.P1RSEN = 1; //start the PWM - enable auto-restart after shutdown (hardware clears CCP1ASE [bit 7] of ECCP1AS register)}void main() {OSCCON = 0b01110010; //16MHz Primary oscillator (PLL disabled in CONFIG word); /*go fast*/OSCCON2 = 0;OSCTUNE = 0;LATA = 0; //all outputs default to lowLATB = 0;LATC = 0;LATD = 0;LATE = 0;TRISA = TRISA_CONFIG;ANSELA = ANSELA_CONFIG;TRISB = TRISB_CONFIG;ANSELB = ANSELB_CONFIG;WPUB = WPUB_CONFIG;TRISC = TRISC_CONFIG;ANSELC = ANSELC_CONFIG;TRISD = TRISD_CONFIG;ANSELD = ANSELD_CONFIG;TRISE = TRISE_CONFIG;ANSELE = ANSELE_CONFIG;INTCON = 0; //ensure no interrupts are enabledWDTCON = 0;delay_us(10); //wait for oscillator to stabilise. VERY IMPORTANT FOR ECCP MODULE for some reasonPMD0 = PMD0_CONFIG;PMD1 = PMD1_CONFIG;PMD2 = PMD2_CONFIG;RCON = RCON_CONFIG;//peripheral initialisationspwm_init(); //initialise PWM after delay// MAIN LOOPwhile(1) {//stuff}}

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: June 22, 2015, 09:59:53 pm
content: Quote from: SuzyC on June 22, 2015, 04:50:07 pmForgot the '0b'?To select PWM mode you must set CCPxM<3:2>, like this:-CCP1CON=0b00001100;QuoteNot sure what you wanted to do there, but CCPR1L just holds the upper 8 bits of the PWM value.

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 23, 2015, 12:24:09 am
content: Thanks Lewis, I read the errata link you posted and can see that the problem with PWM only applies to chip revision earlier than then 4.In fact in order to RTFM, I downloaded the newer, latest errata and it doesn't show the problem.Also the chips I have are quite new out of the oven, the are all revision 5.

author: android
author_rank: Regular Contributor
timestamp: June 23, 2015, 08:45:03 am
content: Quote from: SuzyC on June 22, 2015, 12:44:54 pmhmmm, kind of expected I guess. Try thisExcel 2003 version of the PWM calculator. ...created by LibreOffice so could still be flakyEdit: Here's a version created from my son's copy of MS Excel 2007:Third time lucky.

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 23, 2015, 10:04:17 am
content: Thanks Again Android, this .xls opens, but it is still unusable, flaky.

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 23, 2015, 11:03:19 am
content: Thanks for the .hex file, picandmix, but it will not program on my programmer because you set some CONFIG write protects in your code that disables verification after programming.

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 23, 2015, 11:08:16 am
content: Thanks Bruce Abbot, but according to the 25K22 specsheet bits 6 and 7 of CCP1CON are used for P1M advanced output configuration bits and I did not think I should change the default settings for these two bits. In my isr, I set the dutycycle when the PWM is started.I tried just setting the CCP1CON to 0 before PWM startup, but same results. I can see that PR4 is counting but the CCP1 pin remains constantly at Vss.

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: June 23, 2015, 04:00:51 pm
content: Quote from: SuzyC on June 23, 2015, 11:08:16 amBits 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 REGISTERbit 3-0 CCPxM<3:0>: ECCPx Mode Select bits11xx =: 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 bitCCP1CONbits.DC1B1 = (DCyc >> 1) & 1; //set second lowestCCPR1L = (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=TMR4CCPTMRS0=(CCPTMRS0 & 0xFC); //Mask to leave C3TSEL and C2TSEL unchangedCCPTMRS0=(CCPTMRS0 | 0x01); //C1TSEL=0x01 TMR4 selected/* Bit 7 6 5 4 3 2 1 0------------------------------------------------------------------------x 0 0 0 0 1 0 0TxOUTPS<3:0>POSTSCALER 1:1 to 1:16 TMxOn PRESCALER1:1=00 01=1:4 1x1:/16*/T4CON=0b00000100;//CCP1CON holds duty cycle LSb in bits<5:4>LSbs, but CCPR1L=MSbitsCCP1CON=0b00001100; //DCyc=0 off PWM1 channel,mode = PWM// CCPR1L=(CCPR1L & 0xC0); //Mask P1M bits, MSbits of DCyc=0, CPR1H not usedPR4=0xFF; //overflow count 0XFF for 10-bit resolution for any PWM freq.CCP1IE=0; // Disable CCP1 IRQ enable not used for PWM only modeTMR4IE = 1; // enable TIMER4 interruptPEIE = 1; // enable peripheral interruptsTMR4ON = 1; //Turn on TMR4 used for duty cycle period}//==== End of PWM1Setup ===================================void main(void){// Init_PIC();Init_TMR0();PWM1Setup();//Setup CCP1 cbit2 PWMIPEN =1; //Priority interrupts enabled//RCONbits.IPEN = 1; //also works 9.80TRISB =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 TMRxPLLEN =1;PEIE =1; //Needed for TMRx interrupts and A2D?GIEL=1; //Enables Low-Priority if GIEH/GIE=1GIEH=1; //Ok to use INTCONbits.GIE = 1; to enable all interrupts//======================== START =======================================DCyc=50;while(1);}

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 23, 2015, 04:33:14 pm
content: Bruce Abbot, a thousand thanks!What is so much a trap here in the spec sheet (of which I thought I printed out all the pages I carefully thought to be relevant) is that there is actuallytwo pagesabout setting up PWM giving thesame register name different configuration information.So, all this time I printed out and was using page 206 when the page required was 205and I didn't see the alternate. I was working with the Enhanced instead of the standard because when I was using Acrobat Reader and i was at that time first looking in the index then used asearch in reverseto find the configuration page for the register corresponding to CCP1CON. So I found the wrong page first, printed it out and to this moment assumed it had all the possible info for CCPxCON.I changed CCP1CON to 0b00001100 and bingo!

author: lewis
author_rank: Frequent Contributor
timestamp: June 23, 2015, 05:38:55 pm
content: Quote from: SuzyC on June 23, 2015, 04:33:14 pm* cough cough *

author: SuzyC
author_rank: Frequent Contributor
timestamp: June 23, 2015, 09:30:06 pm
content: Ad than you Lewis, I ignored your listing which also shows CcPxCON to be set to the correct value to work!I looked at your code and was just trying to understand the 10uS delay you said made things work, and I then concluded your reply was just about some old silicon revision problem that had already been rfixed.