need help with interrupt

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
jchandir
Posts: 10
Joined: Wed Apr 08, 2009 12:09 am

need help with interrupt

Post by jchandir » Sun Nov 15, 2009 7:32 am

Can someone please help me with this simple Rx data interrupt. I cannot get it to work no matter what I do. I am using a 18f2553 with a microchip USB bootloader. I have tried it without the bootloader and it still does not work. The code will not jump into this ISR. I have all the variables defined, but i am not adding it to the code below to save space. I just feel like i am forgetting to set something. I have even tried to reset the interrupt vectors. Not sure if I know what I am doing anymore. Any help would be great.

Thank
Jay

Code: Select all


Device = 18F2553
Clock = 48

#option org_reset = $0800
//#option vector_isr_lo = $0808
//#option vector_isr_hi = $0818
//#option TIMER_PRIORITY = iplow

Include "usart.bas"
Include "ADC.bas"
Include "convert.bas"
//Include "ISRTimer.bas"




Interrupt RX_DATA(ipHigh)
Save(0)
 
 led1 = 1                    // just testing with led to see if i triggered the INT
 DelayMS (500)          // Problem is It never comes here! 
 led1 = 0
 
 USART.Read(rxdat)
 
 
 If rxdat= $FE Then
    USART.Read(rxdat)
    
    Select rxdat 

        Case $01 
            Mode=1
            escape = true
        Case $02
            Mode=2
            escape = true
        Case $03
            USART.Read(rate,points)
            Mode=3
            escape = true
    Else
            Mode=1

    EndSelect 
    
EndIf
 

   // clear flag !!!!
RCIF=0
Restore
End Interrupt





// Init of all my variables and TRIS registers go here 


SetBaudrate(br115200)
Enable (RX_DATA)
//RCON.7=0
RCIE=1                ' Enable RCIE 

While true
    escape = false
    Select Mode

        Case 1 
            USART.Write ($FE,$01)
            Mode_1() 
        Case 2
            USART.Write ($FE,$02)
            Mode_2()
        Case 3
            USART.Write ($FE,$03)
            current = 0
            Mode_3()
    Else
            USART.Write ($FE,$01)
            Mode_1()
   

    EndSelect 
    
    

Wend

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Sun Nov 15, 2009 10:14 am

If you want to try getting it to work without the bootloader, comment out the

Code: Select all

#option org_reset = $0800 
I'd get it working stand-alone before trying to get it running w/the loader.

Jerry

Doj
Posts: 362
Joined: Wed Apr 11, 2007 10:18 pm
Location: East Sussex

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.

jchandir
Posts: 10
Joined: Wed Apr 08, 2009 12:09 am

Post by jchandir » Sun Nov 15, 2009 5:51 pm

Will do.. I added the little led part to see if i ever even get into the interrupt. the delay and everything was just a test. I sent it one byte to see if i got that led to blink, notifying me of the jump, but i will read that article you wrote and see if I can get it to work. The timer registers are set in a different part which I didn't need yet. All i was trying to do is get it to read a byte from the Rx buffer which I wanted to use for mode selection.

Thank you for the quick response.

Doj
Posts: 362
Joined: Wed Apr 11, 2007 10:18 pm
Location: East Sussex

Post by Doj » Sun Nov 15, 2009 6:08 pm

Ok Jay,
Unfortunately interrupts need more planning than the basic commands, and the code they are used within must be sympathetic to their needs.
Once mastered they will allow a far more flexible structure to be implemented and very complex code which can run as if several things were going on at once.

If all you want to do is blink a led and test a button its probably not worth it.

jchandir
Posts: 10
Joined: Wed Apr 08, 2009 12:09 am

Post by jchandir » Sun Nov 15, 2009 7:03 pm

Just wondering one thing, my interrupt routine will only execute like once in three days just to read which mode i want it to be in. That is why it did not matter how long it was. That routine pretty much terminates whatever other subroutine the pic is in and changes which subroutine it gets stuck in. So for this, what I have sould work right? What register or command am i forgetting? I have tried it without the boot loader but it just will not jump to the routine. Eventually I will have a ipLow timer running to collect data which will only be interrupted by the RX data to switch modes (ex sleep). I have read tons of stuff on the forums and I though this is the right way to do interrupts.

1) Set the registers
1) Use enable( ... ) instead of Intcon register
2) Clear flag (of the desired interrupt) inside the interrupt routine.

Am i missing anything else?

This is the first time I am using swordfish basic, I was previously using PBP and I figured I give swordfish a shot. I am just having a hard time not using registers for interrupts like I was doing in PBP.

Doj
Posts: 362
Joined: Wed Apr 11, 2007 10:18 pm
Location: East Sussex

Post by Doj » Sun Nov 15, 2009 7:26 pm

Jay I think the use of an interrupt may still be passing you by.
As far as I can see your interrupt routine can not work, it will never go beyond the delay, you must have an understanding of the whole concept to either use an interrupt or decide that it is not required.
Neither the delay nor the USART read have any place in the interrupt, they should be in a separate routine which could be called from the main routine by a flag set in the interrupt.

From what you say, if the event is only happening rarely then why would you need an interrupt, which is designed for very fast response to differing inputs.

Please remember that posting a small part of the code you have may be useless, as what you show may have nothing to do with the issues you face, more often than not the issue lies within the part you leave out.

jchandir
Posts: 10
Joined: Wed Apr 08, 2009 12:09 am

Post by jchandir » Sun Nov 15, 2009 8:55 pm

Okay I took your advice about making my isr really small and moving the select cases into the main part of the program and I got it to work using ISRRX but I still could not get the normal interrupt to work. I think I am happy about the way its working now but do you think I could send you my terrible code and you could show me the right way of doing things. My code works but I would love to learn how to do things more efficiently. Again this is the first time I am using swordfish so my code is def not very good. Do you think you have the time? Let me know, that was be awesome.
Thank you for all your help...

Doj
Posts: 362
Joined: Wed Apr 11, 2007 10:18 pm
Location: East Sussex

Post by Doj » Sun Nov 15, 2009 10:24 pm

Jay we all write code in our own way, as long as logic is good and the sensible rules are followed it really does not matter.

I can only look at what you post and help if able, there will also be others watching and they may be able to offer help also.

jchandir
Posts: 10
Joined: Wed Apr 08, 2009 12:09 am

Post by jchandir » Sun Nov 15, 2009 11:01 pm

Okay. Thank you for the quick response..

Post Reply