PIC18F2550 Interrupt Timing ??? - Page 1
Forum section: electronics / general

author: MarkF
author_rank: Super Contributor
timestamp: April 18, 2016, 01:38:31 am
content: What am I missing here?I'm trying to setup a 100 Hz interrupt for a pic18f2550 but getting a 200 Hz interrupt.Design data:8 MHz internal clock0x1388 = 5000 count match for Comparator countMeasured clocks:OSC2 = 2 MHzRA5 bit = 200 Hz (interrupt clock)I have done similar interrupt timing for a pic16f876 without issue.Design data:20 MHz external clock0x0140 = 320 count matchMeasured clock:15.82 KHz (interrupt clock)PIC18F2550 code snippet:Code:#include <xc.h>#include <stdint.h>#include <stdio.h>#include <math.h>#include "xtal.h"// CONFIGURATION BITS// CONFIG1L#pragma config PLLDIV = 5 // PLL Prescaler Selection bits (Divide by 5 (20 MHz oscillator input))#pragma config CPUDIV = OSC1_PLL2 // System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])#pragma config USBDIV = 1 // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)// CONFIG1H#pragma config FOSC = INTOSC_EC // Oscillator Selection bits (Internal oscillator, CLKO function on RA6, EC used by USB (INTCKO))#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)// CONFIG2L#pragma config PWRT = ON // Power-up Timer Enable bit (PWRT enabled)#pragma config BOR = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)#pragma config BORV = 3 // Brown-out Reset Voltage bits (Minimum setting 2.05V)#pragma config VREGEN = OFF // USB Voltage Regulator Enable bit (USB voltage regulator disabled)// CONFIG2H#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)// CONFIG3H#pragma config CCP2MX = OFF // CCP2 MUX bit (CCP2 input/output is multiplexed with RB3)#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)#pragma config LPT1OSC = OFF // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)#pragma config MCLRE = OFF // MCLR Pin Enable bit (RE3 input pin enabled; MCLR pin disabled)// CONFIG4L#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))int8_t en0;uint8_t sw0,sw1,sw2;uint8_t currA0,lastA0;uint8_t fUpdate=0;uint16_t vBat;uint8_t ddsM;float ddsF1,ddsF2;float ddsP1,ddsP2;float ddsA;float ddsT;//============================================================void main(){TRISA=0b11000001; // Set Port A direction bitsTRISB=0b11100101; // Set Port B direction bitsTRISC=0b01111111; // Set Port C direction bitsOSCCON=0x72; // Select internal oscillator @ 8MHzADCON0=0; // A/D converter offADCON1=0x0f; // All digital inputsINTCON2bits.nRBPU=1; // Port B pull-ups disabledUCON=0x00; // USB module and supporting circuitry disabledUCFG=0x08; // On-chip USB transceiver disabledPORTA=0xff;PORTB=0xff;// Setup battery monitorADCON0=0x01; // A/D converter onADCON1=0x0e; // AN0 onlyADCON2=0x91; // Right justified | 4*Tad | Fosc/8 (for 8 MHz system clock)// Setup rotary encoderen0=0;sw0=sw1=sw2=0;lastA0=PORTCbits.RC1;// Setup CCP1 configurationCCPR1H=0x13; // 100 Hz interruptCCPR1L=0x88;CCP1CON=0x0b; // Compare mode, trigger special event// Setup Timer3 configurationTMR3H=0;TMR3L=0;T3CON=0x55; // T3CCP | 1:4 Prescale | TMR3CS | TMR3ON bits// Enable CCP1 interruptPIR1bits.CCP1IF=0; // CCP2 Interrupt Flag bitPIE1bits.CCP1IE=1; // CCP2 Interrupt Enable bitINTCON=0xc0; // GIE and PEIE interruptswhile (1) {// Read battery voltageADCON0bits.GO=1;while (ADCON0bits.nDONE);vBat = (uint16_t)ADRESH << 8 | (uint16_t)ADRESL;ddsA = 5.0 * (float)vBat / 1024.0;// Process encoder inputsif (en0 > 0)ddsF1 += pow(10.,abs(en0)-1);else if (en0 < 0)ddsF1 -= pow(10.,abs(en0)-1);en0=0;}}//============================================================void interrupt isr(){if (PIE1bits.CCP1IE && PIR1bits.CCP1IF) {PIR1bits.CCP1IF = 0; // clear CCP1 Interrupt FlagLATAbits.LA5 = 0;// Read rotary encodercurrA0=PORTCbits.RC1;if (lastA0==0 && currA0==1) {if (PORTCbits.RC2==1) en0--; else en0++;}lastA0=currA0;if (PORTCbits.RC0==0) sw0=1;if (PORTCbits.RC4==0) sw1=1;if (PORTCbits.RC5==0) sw2=1;LATAbits.LA5 = 1;}}

author: Skimask
author_rank: Super Contributor
timestamp: April 18, 2016, 05:50:54 am
content: Quote from: MarkF on April 18, 2016, 01:38:31 amCheck that...Looks to me like you set a 1:2 prescale.

author: dannyf
author_rank: Super Contributor
timestamp: April 18, 2016, 10:55:02 am
content: "PIC18F2550 code snippet:"1. I typically work on the bit or mask levels, with comments so it can be traced easily during debug and for future reuses.2. I would put those code that initializes the adc or timers in separate routines so they can be reused later in other programs.

author: MarkF
author_rank: Super Contributor
timestamp: April 18, 2016, 12:54:10 pm
content: Quote from: Skimask on April 18, 2016, 05:50:54 amI would agree if this was Timer 1; but this is Timer 3 and the bit layout is different.

author: android
author_rank: Regular Contributor
timestamp: April 18, 2016, 01:26:26 pm
content: Mikroelectronica have a free timer calculator that could be useful...generates c code of sorts:http://www.mikroe.com/timer-calculator/

author: Skimask
author_rank: Super Contributor
timestamp: April 18, 2016, 01:39:59 pm
content: Quote from: MarkF on April 18, 2016, 12:54:10 pmI dunno. I'm looking at the datasheet for T1CON and T3CON right now.T3CON = $55 = 01010101 = enable 16bit, T3 source for CCPx,PRESCALE 1:2, sync ext clk in, internal clk source, T3 enabled.At any rate, would it hurt to try other prescale values to see how the interrupt timing changes?

author: MarkF
author_rank: Super Contributor
timestamp: April 19, 2016, 03:03:08 am
content: Quote from: Skimask on April 18, 2016, 01:39:59 pmThe bit layout for T3CON is not what I expected. T3CCP2:T3CCP1 is bits 3 and 6 instead of being next to one another. And T3CKPS1:T3CKPS0 is bits 4 and 5. I looked at it over and over and missed it every time.

author: Skimask
author_rank: Super Contributor
timestamp: April 19, 2016, 04:20:23 am
content: Quote from: MarkF on April 19, 2016, 03:03:08 amI blame Microchip.....because I can