PIC24FJ128GA204 Output Compare (with dedicated timers) - Page 1
Forum section: electronics / general

author: NivagSwerdna
author_rank: Super Contributor
timestamp: March 07, 2017, 08:07:25 am
content: HiI'm having troubles understanding 'Output Compare with dedicated timers' which is supported by the PIC24FJ128GA204 on the PIC24F curiosity board.I think I have it working but I am not convinced it synchronised properly...Specifically I want to have an hardware interupt fire a fixed period after TIMER4 resets.So for example TIMER4 runs with a period of 1second, I would like the TIMER4 interrupt to generate once per second and the OC1 to fire and toggle a pin exactly 100ms after the TIMER4 reset.It seems to be working with "Single Compare Continous Pulse Mode" and TMR4 as Clock Source and TMR4 as Sync Trigger. I have set the Primary compare count to give the interval needed.But...I find the documentation a bit unconvincing and would appreciate some reassurance!Specifically...re: Clock Source....when I specify TMR4 does that mean the dedicated timer in OC1 then increments at the same rate that TMR4 ticks i.e. subject to the TMR4 prescale?re: Trigger Source...This is my real problem... it doesn't seem clearly defined... If I set the Trigger source to TMR4 which event is used? Is this the TMR4 reset event (i.e PR4 match)?Thanks in advance,Nivag

author: Howardlong
author_rank: Super Contributor
timestamp: March 07, 2017, 01:43:16 pm
content: I agree that the documentation around some peripherals is confusing and often unclear. As often as not I find that it's trial and error to get something to work.Here is my solution which I've tested in the simulator on MPLAB X IDE 3.51, XC16 v1.30. I'm away at a customer at the moment so I don't have any silicon to test it on. Also note that I don't setup the PPS as there's no need for simulator purposes.Code:#pragma config FWDTEN=OFF#include <xc.h>#define FCY 2000000 // Default 2MHz FCY (8MHz FRC, RCDIV -> div-by-2, FCY=FOSC/2)#include <libpic30.h>#define TIMER_PRESCALER 64 // Choose with FCY to make sure 16 bit timer is enough for 1 second timer#define TIMER_PERIOD (FCY/TIMER_PRESCALER) // One second, make sure this fits into unsigned 16 bits#define OC_DELAY (TIMER_PERIOD/10) // 1/10th secondvoid __attribute__((__interrupt__, __auto_psv__)) _T4Interrupt(){Nop();IFS1bits.T4IF=0;}void __attribute__((__interrupt__, __auto_psv__)) _OC1Interrupt(){Nop();IFS0bits.OC1IF=0;}int main(void){IEC1bits.T4IE=0;IFS1bits.T4IF=0;T4CON=0;T4CONbits.TCKPS=0b10; // 0b10 -> div-by-64 prescalePR4=TIMER_PERIOD-1; // one secondTMR4=0;IEC1bits.T4IE=1;IEC0bits.OC1IE=0;IFS0bits.OC1IF=0;OC1CON1=0;OC1CON2=0;OC1CON1bits.OCTSEL=0b010; // 0b010 -> Timer4 clock sourceOC1CON2bits.OCTRIG=0; // 0 -> Syncs from SYNCSELx sourceOC1CON2bits.SYNCSEL=0b01110; // 0b01110 -> Timer4 is sync/trigger sourceOC1TMR=0;OC1R=OC_DELAY-1; // 1/10th sec wrt Timer4, when interrupt is triggeredIEC0bits.OC1IE=1;OC1CON1bits.OCM=0b011; // 0b011 -> Single Compare Continuous Pulse modeT4CONbits.TON=1;while (1){Nop();}return 0;}

author: NivagSwerdna
author_rank: Super Contributor
timestamp: March 07, 2017, 06:16:34 pm
content: Thanks for your time...So...OC1CON2bits.SYNCSEL=0b01110; // 0b01110 -> Timer4 is sync/trigger sourceThe semantics of that being the SYNC is performed when TMR4=PR4, i.e. the roll-over?

author: Howardlong
author_rank: Super Contributor
timestamp: March 08, 2017, 01:17:01 pm
content: The timer is used both for the clock source and for syncing, so there are two references to it in the OC config.

author: NivagSwerdna
author_rank: Super Contributor
timestamp: March 09, 2017, 01:04:03 pm
content: Actually my issue was more of..."What does SYNC from Timer4 represent"I don't believe SYNC is really defined for timers, in fact the word Sync does appear in Figure 13-1 of the datasheet where it is possibly hugely misleading as this implies that it is related to the post-scaled clock which I do not think is correct. My feeling is that SYNC is a thing that happens which causes the interrupt flag to be set and this is in my case when TIMER4=PR4.One thing I had not realised, but discovered by experimentation, is that for the DMA operations although the sources are defined as "interrupt" these operations work if interrupts are disabled... i.e. it is more the hardware level event (that presumeably sets the flag) rather than the actual interrupt. Makes sense in retrospect. I assume that the DMA operation is triggered by the edge since it seems to allow repeated subsequent operations completely under hardware control (i.e. not resetting the flag).

author: Howardlong
author_rank: Super Contributor
timestamp: March 09, 2017, 05:14:50 pm
content: Indeed, there is quite a bit of experimentation required in my experience, it is rarely crystal clear, and worse sometimes it's not properly defined. When I wrote that code above I had to re-read various sections several times and use trial and error when there was no clarity.What doesn't help is that you have to collate the FRM sections with the datasheets yourself, and choose appropriately with PIC24, dsPIC and PIC32. Lower end PICs have all the detail in each device datasheet.For some PIC24s, there is a different peripheral for output compare (SCCP/MCCP) which have two separate interrupt vectors and their own counters to perform what you're trying to achieve: it still needs a fair bit of effort to figure out how to drive them.