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

right order to use interrupts

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



Joined: 17 Nov 2011
Posts: 187

View user's profile Send private message Send e-mail

right order to use interrupts
PostPosted: Thu May 08, 2014 6:49 am     Reply with quote

hello,

I'm asking when I use timer1 to interrupt what is right order to use those:
Code:

SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_8);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
set_timer1(55594);


My purpose is in infinite loop first activate interrupt timer1
and measure frequency in pin B5 while(!input(pin_b5) // wait pin b5 to go high
and then while(input(pin_b5) // wait pin b5 to go low

and count those pulses in pin B5...

(the time for counting 1 s

frequency varies 10 000 ... 40000 Hz)

and then deactivate it and print result to LCD display and then
activate it again ...

what function activate timer and and what function deactivate it ?
in infinite loop ?

brdgs

-arto-
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu May 08, 2014 7:03 am     Reply with quote

my belief is that enabling all other ints on the service tree FIRST
and then global ints (GIE) LAST is the correct order.
at least that's how i do it.... Very Happy


Last edited by asmboy on Thu May 08, 2014 8:50 am; edited 1 time in total
alan



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

PostPosted: Thu May 08, 2014 7:14 am     Reply with quote

Sorry to jump on the bandwagon here.

asmboy, that is the way I always do it as well, but now you've got me thinking and worried.

I got a project where I want to disable and enable ADC interrupts at specific times, would I need to disable/enable GLOBAL everytime before changing the ADC interrupt. I have an SPI interrupt running as well.

Regards
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Thu May 08, 2014 8:16 am     Reply with quote

alan wrote:

I got a project where I want to disable and enable ADC interrupts at specific times, would I need to disable/enable GLOBAL everytime before changing the ADC interrupt. I have an SPI interrupt running as well.


I enable interrupts like that in my code too: do all the individual sources, then turn on the whole interrupt system. That way, at least you know you are not going to be interrupted while setting up the individual interrupt sources. However, in practice it often doesn't matter much.

Once initialised, when disabling/enabling an interrupt, you can simply disable each source as required without worrying about global interrupt enable. There's generally no need to do anything with GIE. That's largely handled for us by the hardware, or, as we know, on many CCS releases, messed up for us by the compiler behind the scenes driver/support code. GIE is handled automatically in the hardware in ISRs, and user code should (almost) never enable global interrupts in an ISR. Be aware that an interrupt may occur as soon as a source is enabled. All manipulation of the interrupt source, e.g. configuration of hardware, reading of data etc., must be finished by the time the relevant interrupt is enabled.

Classic critical sections, to make code sections atomic, can be implemented by manipulating GIE if they are generic, e.g. to implement semaphores/locks etc. While such things are key to many OSs, they are generally not required in typical PIC code, i.e. single threaded. On the odd occasion where such locking is required, it's often less intrusive to use individual source enables instead, e.g. to interrupt lock peripheral buffer access. The compiler also uses GIE to lock routines used in both main and ISR code, to prevent re-entrancy.

So no it doesn't matter much which order they are enabled - though individuals then global is safest - and no, you don't have to disable/re-enable GIE when you want to disable/enable a particular interrupt source.

PS: Don't forget that disabling the interrupt from a timer doesn't stop it counting.


Last edited by RF_Developer on Thu May 08, 2014 8:23 am; edited 1 time in total
alan



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

PostPosted: Thu May 08, 2014 8:21 am     Reply with quote

Thanks RF_Developer, I was wondering what will spring out of the code if I do that, and now it look as if you are just careful nothing should happen.

Regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Thu May 08, 2014 8:46 am     Reply with quote

They are individually only bit flags.
None has priority, or matter when it goes off/on.

The logic only checks in the very first state of the instruction, and the sets/clears apply in the last state of the instruction.

It'd might well 'matter' if things tried to all happen at once, but that is why the PIC internally (talking about the PIC16/18), used four clock cycles per instruction. Things that are time critical relative to one another, are done in different parts of the instruction. Smile

The reduction in clock cycles on the PIC33 etc., is why there are some extra timing restrictions (like the need to have a NOP between changing TRIS and read/write on a port).

Best Wishes
artohautala



Joined: 17 Nov 2011
Posts: 187

View user's profile Send private message Send e-mail

PostPosted: Thu May 08, 2014 9:19 am     Reply with quote

Ttelmah wrote:
They are individually only bit flags.
None has priority, or matter when it goes off/on.

The logic only checks in the very first state of the instruction, and the sets/clears apply in the last state of the instruction.

It'd might well 'matter' if things tried to all happen at once, but that is why the PIC internally (talking about the PIC16/18), used four clock cycles per instruction. Things that are time critical relative to one another, are done in different parts of the instruction. Smile

The reduction in clock cycles on the PIC33 etc., is why there are some extra timing restrictions (like the need to have a NOP between changing TRIS and read/write on a port).

Best Wishes


I found this code works:
Code:

 SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_8);
 enable_interrupts(INT_TIMER1);
 
 i = TRUE;

 while(i){
         
        G_KESK_LKM = 0;
        taajuus = 0;
         
         set_timer1(55650);      //good value in practice, in theory 55530
         enable_interrupts(GLOBAL);
         
         while(G_KESK_LKM < 9){
         
         //wait pin B5 to go high
         while(!input(PIN_B5));             
         
         //wait pin B5 to go low
         while(input(PIN_B5));         
         
         ++taajuus;
         
         }
     
      disable_interrupts(GLOBAL);
     
      if(taajuus > 50000){
     
      clear_lcd();
      strcpy(teksti,"humsensor off !");
      show_text(1,0 );
      delay_ms(2000);
     
      return;
      }
     
      //taajuus = frequense
      show_taajuus(taajuus );
 }
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu May 08, 2014 11:59 am     Reply with quote

if you have MULTIPLE interrupts enabled - then
disable_interrupts(GLOBAL);
is NOT such a great idea.

if the timer INT is the source of some action you do not wish to repeat
simply disable ONLY the timer INT- NOT the whole global show !

my 2 cents
Very Happy Very Happy
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Mon May 12, 2014 5:03 pm     Reply with quote

I would concur.

During program init, set up your interrupts as needed with the global interrupt last.

While the program is running, one only needs to disable the interrupts that are needed (like in your case, the ADC) or ones that might be related.

A good example of this is an ISR driven UART TX routine.

How does it work?

you have a send routine that primes the TXREG and then enables the IRQ and then lets the IRQ do the work.

When the IRQ reaches the end of the needed TX buffer, it disables itself.

I've done this on systems with all sorts of other IRQ's enabled and "stuff" going on (like AD AND Timers AND RX/TX IRQ's for another UART).

Cheers,

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
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