![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
thushi
Joined: 22 Feb 2006 Posts: 14
|
Interrupt Priority Settings |
Posted: Wed Feb 22, 2006 6:45 am |
|
|
Hi All,
Please send me a sample CCS C coding to setup Interrupt Priority for timers.
for example:
Timer0... higher priority.
Timer1... lower prority.
best regards,
Thushi |
|
![](templates/subSilver/images/spacer.gif) |
Alex N
Joined: 10 Feb 2006 Posts: 16
|
|
Posted: Wed Feb 22, 2006 7:39 am |
|
|
Thushi, here are a bit different interrupts, but the code shows, how to set priorities.
Code: |
#include <18F1320.h>
#device HIGH_INTS=TRUE
#fuses HS
#fuses BORV42, BROWNOUT, PUT
#fuses NOWDT
#fuses MCLR
#fuses NODEBUG, STVREN, NOLVP
#fuses CPB, CPD, PROTECT
#use delay(clock=8000000)
// Settings for RS-232
#use rs232(baud=9600, xmit=PIN_A3, rcv=PIN_A4, BITS=8, PARITY=N)
#INT_TIMER0
void TMR0IrtHandle()
{
static int i=0;
i++;
}
#INT_RDA FAST
void RDAIrtHandle()
{
static int i=0;
i++;
}
void main()
{
delay_ms(500);
printf("\n\r");
printf("Program started\n\r");
// Allow interrupts
enable_interrupts(INT_RDA);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
// Main cycle
while (TRUE)
{
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
KenMacfarlane
Joined: 20 Sep 2005 Posts: 23 Location: Glasgow, Scotland, UK
|
#priority |
Posted: Thu Feb 23, 2006 7:33 am |
|
|
Older pics have no concept of interrupt priority. Newer ones allow you to promote one to high priority (although I've never used that facility).
CCS seem to have an interrupt dispatcher, which decides who gets precedence if 2 interrupt flags are set when interrupts (GIE) are enabled.
You explicitly set the order using #priority, otherwise the highest priority the one compiled first. See for example http://www.ccsinfo.com/forum/viewtopic.php?t=25534&highlight=interrupt+priority |
|
![](templates/subSilver/images/spacer.gif) |
eliberg Guest
|
interrupt priority |
Posted: Fri Feb 24, 2006 6:52 am |
|
|
//in this case timer1 has priority on timer0, so its service routine can
//interrupt the service routine of timer0. If you want the inverse you just
// have to change the two instruction:
// TMR0_high_priority=0; //0 = low priority
// TMR1_high_priority=1; // 1 = high priority
//in
// TMR0_high_priority=1;
// TMR1_high_priority=0;
// Timer1 overflows about 32 times Timer0
//This code is tested and I assure it works without problems. If you run it you will see a "t0" every 32 "t1" put on the video
#include <18f4431.h>
#include <stdlib.h>
#include <math.h>
#use delay(clock=20000000)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#fuses HS, NOPROTECT, NOBROWNOUT, NOWDT, NOLVP, PUT, NOSTVREN, NOFCMEN, NOIESO, NOMCLR
//these are the registers where are the configuration flag bits to set
//the interrupt priority of timer 1 and timer0
#BYTE INTCON2=0xFF0
#BYTE IPR1 =0xFF1
#bit TMR0_high_priority=INTCON2.2
#bit TMR1_high_priority=IPR1.0
#BIT T0CON=0xFD5.6
#define led_status PIN_D7
//-------------- interrupt TIMER1
#int_TIMER1
TIMER1_isr()
{printf(" t1");}
//-------------- interrupt TIMER0
#int_RTCC
TIMER0_isr()
{printf(" t0");}
//-------------- MAIN
void main(void)
{
output_bit(led_status,1);
delay_ms(2000);
output_bit(led_status,0);
printf("\n\r prova interrupt priority");
delay_ms(500);
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8 ); //res 1.6us, overflow 104ms
set_timer1(0); //start the timer
enable_interrupts(INT_TIMER1);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256); // res 51.2us overlofw 3.4s
T0CON=0; //timer0 16 bits
set_timer0(0);//ogni 3.4 sec
enable_interrupts(INT_RTCC);
//--------------- setting the priority interrupt
TMR0_high_priority=0;
TMR1_high_priority=1;
enable_interrupts(GLOBAL);
while(1)
{delay_ms(1000);
printf(" m ");
}
}
Put attention that I use a 18F4431 PIC, so maybe in you PIC the interrupt registers are different.
Bye
eli |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Fri Feb 24, 2006 9:18 am |
|
|
This is _lethal_ code.
The problem is that a high priority interrupt can interrupt a low priority one. However because you have not used the 'HIGH' keyword in the interrupt definiotions, the compiler will not know this, and will not save any registers for this. Also the interrupt vectors to a different location for the high priority interrupt. Again the compiler will not know this, and will put the global handler, that calls the routines, in the normal location for interrupts with just one priority. As posted, the Eliberg code, is a recipe for it not to work.
There are two different priority concepts in CCS C. The first is the #priority statement, which applies to all PICs, and sets the order in which the interrupt bits are checked. This does not allow one event to interrupt another, but does ensure that the 'higher priority' event is serviced first.
The second is hardware priorities. This only exists on the 18 chips.
Two different keywords provide support for this (compilers older than perhaps 30 vesions ago, provided only very 'partial' support for this feature). The two keywords are 'HIGH', and 'FAST'. The latter flags the interrupt as a 'high priority' interrupt, and uses the fast return stack for the interrupt handler. With this, if your code modifies any registers beyond the basic status/accumulator, then your code must save the registers first, and restore them afterwards. This gives the fastest handling, but will work for only a single high priority interrupt. This is what is shown by 'Alex N', and for the simple example of incrementing one variable, will work. The alternative keyword, is 'HIGH'. With this, a complete second int_global routine is generated, saving all the registers, and the interrupt flags for all routines flagged as 'high' are checked, ensuring safe operation, but at the cost of speed.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
Alex N
Joined: 10 Feb 2006 Posts: 16
|
|
Posted: Mon Feb 27, 2006 7:42 am |
|
|
My version of compiler 3.222 has no HIGH option. So, it's time to think about version update. ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
soong2020
Joined: 13 Feb 2008 Posts: 25
|
|
Posted: Sun Feb 24, 2008 10:23 am |
|
|
Hi guys, sorry for reviving such an old thread, but I'd like to ask on how to set the priority on Timer0 and Timer1 on a PIC16F877A? I need Timer1 to be on a higher priority.
Thank you |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Sun Feb 24, 2008 11:35 am |
|
|
If you read the thread, you will see that the _16_ chips, have no concept of 'priority' in the hardware sense. CCS, allows you to use the #priority keyword, _which sets the order in which the interrupt bits are tested_, but your hardware has no ability for one routine to interrupt the other.
So, you can try
#priority INT_TIMER1,INT_TIMER0
but this will only give the same results as having the timer1 interrupt routine defined first, and will not alow TIMER1, to interrupt TIMER0.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|