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

Interrupt Tutorials

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



Joined: 06 Aug 2015
Posts: 10

View user's profile Send private message

Interrupt Tutorials
PostPosted: Fri Aug 07, 2015 12:42 am     Reply with quote

Hey guys,

Could someone provide me with or point me to a good Interrupt tutorial. I would like to become more familiar with Interrupts. I understand the concept of interrupts what I feel I'm missing is a detailed example.

If possible I would like to see (With comments) how interrupts are used with timers/counters to execute time driven events, for example Blink and LED every few seconds.

Thank you in advance
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Fri Aug 07, 2015 1:49 am     Reply with quote

Do a search on this forum.

Set the "search all terms button"
Search for keyword "interrupts".
Search for author "One of the regulars(either Mr T, asmboy, me, etc)".

Mike
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Aug 07, 2015 4:54 am     Reply with quote

key point on using interrupts..
1) never do any math (esp. FP !) inside the ISR
2) never print anything inside the ISR
3) never do any long, complicated 'switches' inside the ISR
4) never do any complicated 'if elses' inside the ISR

5) check out the CCS supplied examples
6) do as Mike say, search this forum
7) experiment ! start small,build on what you learn
8) problem? post small program here, others can help

Jay
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Fri Aug 07, 2015 6:31 am     Reply with quote

Quote:

key point on using interrupts..

9)never use a delay_MS() statement or add ANY delay that is not essential
IN your ISR handler

10) wherever possible set a FLAG in the ISR handler and do the lifting in MAIN()

11) if it is NOT time critical -use POLLING of the specific interrupt flag instead of an interrupt service routine.

12) be sure to read portB , even if it is a dummy-read when using the portB edge interrupts.
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Fri Aug 07, 2015 9:33 am     Reply with quote

13) if accessing a variable both inside the interrupt handler and in the mainline and the variable if not the same width as the Processor data bus width then disable the interrupt in the mainline before operating on the variable. For example if you are using an 8 bit processor such as a PIC16 or PIC18 and using an int16 variable inside and outside the interrupt handler then interrupts must be disabled in the mainline before accessing the variable.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Micro_Guy



Joined: 06 Aug 2015
Posts: 10

View user's profile Send private message

PostPosted: Fri Aug 07, 2015 11:45 pm     Reply with quote

These are all very helpful and greatly appreciated, Thanks everyone!
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Sat Aug 08, 2015 12:40 am     Reply with quote

Like all things, 'rules' can often be simplified, and are often wrong....

70% of the rules posted come down to one simple statement:

The interrupt handler should just do the task involved in handling the interrupt, and do it as quickly as possible. This covers all the 'print', 'delay', 'maths' etc., points. These are not quick.

This includes the critical thing that the handler must 'do the task involved'. So for INT_TBE, it must load a new character to send. INT_RBA, must receive a character. INT_RB, must read the port etc..

Then.

One disagreement here is on the "don't use large switches" line. In fact a state machine with a huge array of choices in a switch can be a very good way of handling events in an interrupt. Key is though, that you have to know how switches in CCS 'work'. If you only use sequential switch values, _and don't have a 'default'_, CCS will code switches for more than perhaps half a dozen cases, as a 'jump table'. Means that each switch takes the same time, and in fact is identical to the time needed for a single array access. Perfectly sensible and very acceptable in the interrupt. One of the few cases where you can have apparently very 'long' code in the interrupt safely.

Then there is the general comment 'keep the number of interrupts as low as possible'. Point here is that every interrupt present, increases the potential worst case latency of the other interrupts. If you need five timers, then consider instead having a single master 'tick', and using this to do all the timings. It always sounds so 'nice' to have a separate timer for eah thing, but it comes with dangers.

Unfortunately, CCS does not optimise the interrupt code, instead saving every register that 'might' be used in the handlers. For most things the difference is small (and in fact as soon as you do things like array accesses, things like the table pointers need to be saved, so this is not unreasonable). However for truly optimal responses, manual handling of what to save, is worthwhile.

On accessing a variable, there are two ways of doing this:
Code:

int16 val_used_in_interrupt; //the global copy updated in the interrupt

    int16 local_copy; //the 'main' variable

//First route - No 13 - can be used for both read and write
    disable_interrupts(GLOBAL); //Just disable interrupts for a moment
    local_copy=val_used_in_interrupt; //Copy - other way round for write
    enable_interrupt(GLOBAL);//end re-enable.

//second route     
    do
       local_copy=val_used_in_interrupt; //copy
    while (local_copy != val_used_in_interrupt); //is the copy right?

The second keeps copying while the values differ. So may have to copy the value a couple of times if an interrupt just happens to occur in the loop. However has the advantage that interrupts don't have to be disabled. For something with very tight timing requirements. This is potentially 'better'.

Asmboy's comments 10, and 11, really are important. The tightest timed code I've ever written, used the CCP, and polled this, rather than using an ISR. Nearly three times faster than the ISR version. Almost everything I write uses 10 in some form or other.
Micro_Guy



Joined: 06 Aug 2015
Posts: 10

View user's profile Send private message

PostPosted: Mon Aug 10, 2015 12:32 am     Reply with quote

These tips have already proven very beneficial. Thanks for all your help. Always glad to learn more.
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