CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

SOLVED: Timer interrupt slow

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
JackB



Joined: 04 Mar 2016
Posts: 32
Location: Netherlands

View user's profile Send private message

SOLVED: Timer interrupt slow
PostPosted: Sat Mar 19, 2016 6:49 pm     Reply with quote

I use a PIC18F67K90 at 20MHz.
It seems my 1mSec timer interrupt, is about 2 times too slow.
The LED should flash at 1 Hz rate, but it is 1 second on and 1 second off.
The other two receive interrupts are not triggered much.
What should I check to find out why the timer interrupt is slowing down?

main.c:

Code:

#include "project.h"

#define DMX_SIZE        128
#define DMX_BREAK_COUNT 8

uint16 msecs;
uint16 heartbeat_count;

uint8 dmx_in[DMX_SIZE];
uint16 dmx_index;
uint16 dmx_value;
uint16 dmx_break_time;
uint8 dmx_skip_bytes;
uint8 dmx_signal_detected;
uint16 dmx_address;

... (some more variables)

void main()
{
    setup_timer_2(T2_DIV_BY_4, 249, 10);
    enable_interrupts(INT_TIMER2);
    enable_interrupts(INT_RDA);     // UART1 gives INT_RDA
    enable_interrupts(INT_RDA2);    // UART2 gives INT_RDA2
    enable_interrupts(GLOBAL);

    while(1)
    {
    }
}

#INT_TIMER2
void timer2_isr()
{
    // Timer interrupt every 1 mSec
    if(--heartbeat_count==0) {
        output_toggle(PIN_C1);      // Heartbeat LED
        heartbeat_count = 500;            // Toggle every 500 mS
    }
    if (dmx_break_time < 1000)
        dmx_break_time++;           // Increase measured break time by 1 mSec
    if (dmx_break_time > 100)
        dmx_signal_detected = 0;    // Flag indicates presence of DMX signal
    msecs++;       
}

#INT_RDA2
void usb_isr2() {
    // Is this receiver interrupt on the STD stream? Does not trigger?
    std_byte = (int8)fgetc(USB_STREAM);             // Read RX register
    if (std_byte == 0x0d)
        input_string_fetching[input_index] = (char) '\0';
    else
        input_string_fetching[input_index] = (char) std_byte;
    input_index++;
    if (input_index > INPUT_STRING_SIZE-1)
        input_index = INPUT_STRING_SIZE-1;
}

#INT_RDA
void dmx_isr() {
    // Is this receiver interrupt on the DMX stream? Does not trigger?
    int8 dmx_byte = (int8)fgetc(DMX_STREAM);             // Read RX register
    if (dmx_break_time > DMX_BREAK_COUNT) {      // MARK time after Slot > 15mS, reset index
        dmx_index = 0;
        dmx_skip_bytes = 2;
        dmx_signal_detected = 1;
    }
    if (dmx_skip_bytes > 0) {
        dmx_skip_bytes--;
    }
    else {
        dmx_in[dmx_index++] = dmx_byte;
        if (dmx_index == DMX_SIZE)
           dmx_index = DMX_SIZE-1;           // Ensure this cannot overflow.
    }
    dmx_break_time = 0;             // Character received: reset break time
}



project.h:

Code:

#ifndef PROJECT_H
#define   PROJECT_H

#include <18F67K90.h>
#include "types.h"

#define BOARD_CURRENT_DRIVER  1
#define BOARD_VOLTAGE_DRIVER  1-BOARD_CURRENT_DRIVER

#case

#device ADC=12

#fuses MCLR,HSH,NOPLLEN

#use delay(crystal=20mhz)

#use rs232(UART1, BAUD=250000,BITS=9,PARITY=N,STOP=1,ERRORS,stream=DMX_STREAM, LONG_DATA)

#use rs232(uart2, baud=9600, stream=USB_STREAM)

#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3)

enum errors { err_range, err_too_far, err_too_many };

#endif   /* PROJECT_H */


Last edited by JackB on Sun Mar 20, 2016 5:05 am; edited 1 time in total
jeremiah



Joined: 20 Jul 2010
Posts: 1358

View user's profile Send private message

PostPosted: Sat Mar 19, 2016 7:30 pm     Reply with quote

The parameters you have have chosen make the pin toggle every second

Fosc = 20MHz
Fcy = 20/4 = 5MHz
Prescaler of 4x: 5/4 = 1.25 MHz
Postscaler of 10x: 1.25/10 = 125kHz = 8us per tick

250 ticks per period => 8us * 250 = 2ms per timer period

500 counts per toggle => 2*500 = 1 second per toggle (1 second on and 1 second off)
JackB



Joined: 04 Mar 2016
Posts: 32
Location: Netherlands

View user's profile Send private message

PostPosted: Sun Mar 20, 2016 5:04 am     Reply with quote

Hi Jeremiah,

thank you very much! That fixed the problem!
I'm still learning with ccs c.
It works as expected, and I have added your comments in the code for future reference.
This is how I understood it:

// The parameters to make the pin toggle every 500ms are
// Fosc = 20MHz
// Fcy = 20/4 = 5MHz
// Prescaler of 4x: 5/4 = 1.25 MHz
// Postscaler of 5x: 1.25/5 = 250kHz = 4us per tick
// (249+1) ticks per period => 4us * 250 = 1ms per timer period
// 500 counts per toggle => 1*500 = 500ms per toggle (500ms on and 500ms off)
setup_timer_2(T2_DIV_BY_4, 249, 5);
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group