|
|
View previous topic :: View next topic |
Author |
Message |
JackB
Joined: 04 Mar 2016 Posts: 32 Location: Netherlands
|
SOLVED: Timer interrupt slow |
Posted: Sat Mar 19, 2016 6:49 pm |
|
|
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
|
|
Posted: Sat Mar 19, 2016 7:30 pm |
|
|
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
|
|
Posted: Sun Mar 20, 2016 5:04 am |
|
|
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); |
|
|
|
|
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
|