Author Topic: PIC18F2550 Interrupt Timing ???  (Read 2284 times)

0 Members and 1 Guest are viewing this topic.

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 1526
  • Country: us
PIC18F2550 Interrupt Timing ???
« on: April 18, 2016, 01:38:31 am »
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 clock
      0x1388 = 5000 count match for Comparator count
   Measured clocks:
      OSC2 = 2 MHz
      RA5 bit = 200 Hz  (interrupt clock)

I have done similar interrupt timing for a pic16f876 without issue.
   Design data:
      20 MHz external clock
      0x0140 = 320 count match
   Measured clock:
      15.82 KHz (interrupt clock)


PIC18F2550 code snippet:

Code: [Select]
#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 bits
   TRISB=0b11100101;       // Set Port B direction bits
   TRISC=0b01111111;       // Set Port C direction bits

   OSCCON=0x72;            // Select internal oscillator @ 8MHz

   ADCON0=0;               // A/D converter off
   ADCON1=0x0f;            // All digital inputs

   INTCON2bits.nRBPU=1;    // Port B pull-ups disabled
   
   UCON=0x00;              // USB module and supporting circuitry disabled
   UCFG=0x08;              // On-chip USB transceiver disabled

   PORTA=0xff;
   PORTB=0xff;

   // Setup battery monitor
   ADCON0=0x01;            // A/D converter on
   ADCON1=0x0e;            // AN0 only
   ADCON2=0x91;            // Right justified | 4*Tad | Fosc/8  (for 8 MHz system clock)
   
   // Setup rotary encoder
   en0=0;
   sw0=sw1=sw2=0;
   lastA0=PORTCbits.RC1;

   // Setup CCP1 configuration
   CCPR1H=0x13;                  // 100 Hz interrupt
   CCPR1L=0x88;
   CCP1CON=0x0b;                 // Compare mode, trigger special event
   // Setup Timer3 configuration
   TMR3H=0;
   TMR3L=0;
   T3CON=0x55;                   // T3CCP | 1:4 Prescale | TMR3CS | TMR3ON bits
   // Enable CCP1 interrupt
   PIR1bits.CCP1IF=0;            // CCP2 Interrupt Flag bit
   PIE1bits.CCP1IE=1;            // CCP2 Interrupt Enable bit
   INTCON=0xc0;                  // GIE and PEIE interrupts


   while (1) {

      // Read battery voltage
      ADCON0bits.GO=1;
      while (ADCON0bits.nDONE);
      vBat = (uint16_t)ADRESH << 8 | (uint16_t)ADRESL;
      ddsA = 5.0 * (float)vBat / 1024.0;

      // Process encoder inputs
      if (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 Flag

LATAbits.LA5 = 0;

      // Read rotary encoder
      currA0=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;
   }
}
« Last Edit: April 18, 2016, 02:27:17 am by MarkF »
 

Offline Skimask

  • Super Contributor
  • ***
  • Posts: 1425
  • Country: us
Re: PIC18F2550 Interrupt Timing ???
« Reply #1 on: April 18, 2016, 05:50:54 am »
   T3CON=0x55;                   // T3CCP | 1:4 Prescale | TMR3CS | TMR3ON bits
Check that...
Looks to me like you set a 1:2 prescale.
I didn't take it apart.
I turned it on.

The only stupid question is, well, most of them...

Save a fuse...Blow an electrician.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: PIC18F2550 Interrupt Timing ???
« Reply #2 on: April 18, 2016, 10:55:02 am »
"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.
================================
https://dannyelectronics.wordpress.com/
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 1526
  • Country: us
Re: PIC18F2550 Interrupt Timing ???
« Reply #3 on: April 18, 2016, 12:54:10 pm »
   T3CON=0x55;                   // T3CCP | 1:4 Prescale | TMR3CS | TMR3ON bits
Check that...
Looks to me like you set a 1:2 prescale.
I would agree if this was Timer 1; but this is Timer 3 and the bit layout is different.
 

Offline android

  • Regular Contributor
  • *
  • Posts: 134
  • Country: au
Re: PIC18F2550 Interrupt Timing ???
« Reply #4 on: April 18, 2016, 01:26:26 pm »
Mikroelectronica have a free timer calculator that could be useful...generates c code of sorts:
http://www.mikroe.com/timer-calculator/
Lecturer: "There is no language in which a double positive implies a negative."
Student:  "Yeah...right."
 

Offline Skimask

  • Super Contributor
  • ***
  • Posts: 1425
  • Country: us
Re: PIC18F2550 Interrupt Timing ???
« Reply #5 on: April 18, 2016, 01:39:59 pm »
   T3CON=0x55;                   // T3CCP | 1:4 Prescale | TMR3CS | TMR3ON bits
Check that...
Looks to me like you set a 1:2 prescale.
I would agree if this was Timer 1; but this is Timer 3 and the bit layout is different.

I 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?
« Last Edit: April 18, 2016, 01:41:34 pm by Skimask »
I didn't take it apart.
I turned it on.

The only stupid question is, well, most of them...

Save a fuse...Blow an electrician.
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 1526
  • Country: us
Re: PIC18F2550 Interrupt Timing ???
« Reply #6 on: April 19, 2016, 03:03:08 am »
   T3CON=0x55;                   // T3CCP | 1:4 Prescale | TMR3CS | TMR3ON bits
Check that...
Looks to me like you set a 1:2 prescale.
I would agree if this was Timer 1; but this is Timer 3 and the bit layout is different.

I 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?

The 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.
« Last Edit: April 19, 2016, 03:13:54 am by MarkF »
 

Offline Skimask

  • Super Contributor
  • ***
  • Posts: 1425
  • Country: us
Re: PIC18F2550 Interrupt Timing ???
« Reply #7 on: April 19, 2016, 04:20:23 am »
The 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.
I blame Microchip.....because I can :D
I didn't take it apart.
I turned it on.

The only stupid question is, well, most of them...

Save a fuse...Blow an electrician.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf