Post
by Doj » Sun Nov 15, 2009 11:27 am
Dear Jay,
I think your interrupt routine ignores many rules which should be applied to them.
I do not wish to sound horrible in saying this, but the concept of how to use an interrupt seems to have been missed.
It looks to me as if you are trying to use an interrupt as if it were part of the normal flow of a basic program.
This is simply not the case, you can not use this methodology when operating interrupt code.
Having gone through the same exercise a few years ago I found it initially very confusing.
As it turns out it is very simple once the concept goes click!
The part which I initially did not get is that once set up the interrupt it will run all the code inside the interrupt, regardless of where your own code is in basic, and regardless of you expecting it to do something else.
This means that between any line, statement or function you have to think of what would happen if you suddenly copied and pasted the code in the interrupt at any point in your basic code.
It is like you are walking along the street and every second you disappear off and quickly do some shopping, then come back, and then a second later you go off and do a bit more etc.
Some rules which are generally seen to be relevant(as always these may not apply when you know what is going on).
1, keep the code in the interrupt as small as it is possible, as much logic outside the interrupt is best, most code does NOT need to be called at every interrupt, only the important stuff.
2,NEVER put any code which halts the processor for an amount of time which is longer than the interrupt, this means no delay commands, USART read commands or really any basic library calls unless you know exactly how long they take to run.
3, unless you absolutely have to do so, never do anymore than simple addition and subtraction in an interrupt, and certainly no floating point.
If these ideas are taken on board when first trying interrupts I can say from hours of experience that you will get them going and be able to use them without any issue.
If you look on the Swordfish Wiki you will find an interrupt serial routine which will give you guidance on one method of its use.
I have a serial interrupt routine which goes in many of my projects and it is basically doing nothing more than looking at the USART RX flag to see if it is set, and while ever it is set moving the contents of RCREG(the serial buffer for received serial data) into an array for use outside the interrupt.
Once the data has stopped(I use a timer of 5ms to see if its over) the main program then checks for the index of the array being grater than 0, if so it copies the data to another array and works on the data.
Should a new stream of serial data arrive the interrupt will fill the original array up again and the loop continues.
This all happens in less than 20 lines of code inside the interrupt and all other code(60k) is outside the interrupt.
You have to remember that once started the interrupt will happen constantly and you never need to think about it, you have a normal basic routine which checks for a flag or data values in a variable which were set in the interrupt, if you need to do some delays or other library calls which require time and can not be interrupted in their operation you can simply suspend the interrupt execution by using the PIC interrupt registers and reset them when finished.
When I look at your code I think what would happen logically is that the led will come on then the delay will never be allowed to finish, therefore you will never move beyond the 500ms delay.
Also I see no setting up of registers for the interrupt timers for their operating frequency, again have a look on the Swordfish Wiki at the user modules, I have written one which is specifically about how to set up an interrupt timer(which is the basis of most needs of an interrupt).
I hope that helps a bit and come back with questions once you have read all the articles.