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 support@ccsinfo.com

Interrupt Priority Settings

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



Joined: 22 Feb 2006
Posts: 14

View user's profile Send private message

Interrupt Priority Settings
PostPosted: Wed Feb 22, 2006 6:45 am     Reply with quote

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
Alex N



Joined: 10 Feb 2006
Posts: 16

View user's profile Send private message

PostPosted: Wed Feb 22, 2006 7:39 am     Reply with quote

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)
   {

   }

}

KenMacfarlane



Joined: 20 Sep 2005
Posts: 23
Location: Glasgow, Scotland, UK

View user's profile Send private message

#priority
PostPosted: Thu Feb 23, 2006 7:33 am     Reply with quote

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
eliberg
Guest







interrupt priority
PostPosted: Fri Feb 24, 2006 6:52 am     Reply with quote

//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
Ttelmah
Guest







PostPosted: Fri Feb 24, 2006 9:18 am     Reply with quote

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
Alex N



Joined: 10 Feb 2006
Posts: 16

View user's profile Send private message

PostPosted: Mon Feb 27, 2006 7:42 am     Reply with quote

My version of compiler 3.222 has no HIGH option. So, it's time to think about version update. Smile
soong2020



Joined: 13 Feb 2008
Posts: 25

View user's profile Send private message

PostPosted: Sun Feb 24, 2008 10:23 am     Reply with quote

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
Ttelmah
Guest







PostPosted: Sun Feb 24, 2008 11:35 am     Reply with quote

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