Problems to identify Interrupts

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

CS
Posts: 127
Joined: Thu Nov 02, 2006 9:14 am

Problems to identify Interrupts

Post by CS » Wed Dec 13, 2006 9:31 pm

Hi all,

after solving the drawing problems I'm back with Interrupt-problems.

I want to check if the button on portB.0 and PORTB.1 are pressed longer then 10 sec.

there for I started to configure the Pic like the following:

Code: Select all


RCON = 0            ' Disable Interrupt priority
INTCON = %10010000  ' Enable all unmasked interrupts; External Interrupt Int0 enabled
INTCON2 = %01100000 ' External Interrups 0,1 at rising edge
INTCON3 = %00001000 ' External Interrupt INT2 enabled
Now I'm confused because I don't know how I can identify the occurred interrupt! In mB I have only one interrupt procedure where I can ask for INTCON.INT0IF = 1. How must I do this in SF?

Please help again.

CS

TimB
Posts: 262
Joined: Wed Oct 04, 2006 7:25 am
Location: London UK

Post by TimB » Thu Dec 14, 2006 7:40 am

If you need any interrupt then you only need a simple timer.

In the code just check the port inputs and if set inc a counter, else clear it, once the count reaches 10 seconds worth then set another flag that your main prog looks for.

As I said a simple timer is all you need.

CS
Posts: 127
Joined: Thu Nov 02, 2006 9:14 am

Post by CS » Thu Dec 14, 2006 7:55 am

Him TimB,

I thing I have displayed my problem not clear enough.

I want to check, if on of the button on PORTB.0 and PORTB.1 is pressed more then 10 sec (Pressing the buttons is more priority as the other code).

Therefor I have to check first if an external interrupt from PORTB.0 or PORTB.1 has occurred. If so, then I have to start the timer.

Am I totally confused or is it now clearer!?

CS

P.S.: Please can you give an example of your suggestion?

CS
Posts: 127
Joined: Thu Nov 02, 2006 9:14 am

Post by CS » Fri Dec 15, 2006 8:35 am

I'm amazed,

no one can explane how to detect the interrups on PORTB.0 or PORTB.1 (or any other interrups)? :cry:

In the help I only get information on how to use the Timer interrups!?

It would be nice if someone could answer.

CS

Dark Simpson
Posts: 12
Joined: Tue Nov 28, 2006 8:52 pm

Post by Dark Simpson » Fri Dec 15, 2006 9:00 am

You need to insert a piece of code into your interrupt handler sub to check if INTCON.INT0IF = 1... Or you can insert additional event, call it from your int sub and do checking of INTCON.INT0IF = 1 in that event codespace.
What is unclear?

User avatar
David Barker
Swordfish Developer
Posts: 1214
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Post by David Barker » Fri Dec 15, 2006 9:08 am

Tim has pretty much explained the strategy. There are a couple of modules which you should look at first on the wiki which would help you

http://www.sfcompiler.co.uk/wiki/pmwiki ... er.Modules

Check out ISROnChange and Autokey. Also check out ISRTimer. Much of the code is there. If you get stuck, post your code or algorithm and we will take a look.

CS
Posts: 127
Joined: Thu Nov 02, 2006 9:14 am

Post by CS » Fri Dec 15, 2006 10:21 am

@Dark Simpson: In mE I have one procedure called interrrupt. That procedure catches all interrups. In that procedure i can of course check INCON.INT0IF = 1. But how to do this in SF. I don't understand why TimB suggest me to use the timer interrupt. First I thought he missunderstood me but now David told me in his last post that that was pretty much expained!?? I don't understand how should my interrupt handler have to look when I only want to see if PORTB.0 or PORTB.1 are occurred. My main problem is that the help file also use the Timer but I don't want to use a timer. I only want to understand the interrupt handling! And last but not least very often the language makes it a little bit more difficult too!

I want to give you an example of the interrupt handle from mB (copied directly from the helpfile):

Code: Select all

sub procedure interrupt
  if TestBit(INTCON.TMR0IF) = 1 then
    counter = counter + 1
    TMR0 = 96
    ClearBit(INTCON.TMR0IF) ' ClearBit is realised as an inline function, and may be called from within an interrupt
  else
    if TestBit(INTCON.RBIF) = 1 then
      counter = counter + 1
      TMR0 = 96
      ClearBit(INTCON.RBIF)
    end if
  end if
end sub
That is easy to understand.

Away from my 10 seconds problem (So the timer is hopefully also away) I only want to look at the interrupts wich occurred on PORTB.0 and PORTB.1. Can you you explain that?

@David: I can't give you code because I don't know how to start the interrupt handling. The modules on Wiki are to complex for me and I have to admit, that I don't understand they.

CS

User avatar
David Barker
Swordfish Developer
Posts: 1214
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Post by David Barker » Fri Dec 15, 2006 1:18 pm

> That is easy to understand.

Ok, here is the Swordfish version of what you have given - it's pretty much the same...

Code: Select all

dim
   TMR0 as TMR0L.AsWord,
   RBIF as INTCON.0,
   TMR0IF as INTCON.2 
   
interrupt MyInterrupt()
   if TMR0IF = 1 then
      counter = counter + 1
      TMR0 = 96
      TMR0IF = 0
   elseif RBIF = 1 then
      counter = counter + 1
      TMR0 = 96
      RBIF = 0
   endif
end interrupt

CS
Posts: 127
Joined: Thu Nov 02, 2006 9:14 am

Post by CS » Fri Dec 15, 2006 2:20 pm

Hi David,

when I see your code (thanks for that!!!) then one question will be left over:

Why you have to declare TMR0 as TMR0L.AsWord

All the other declarations are very simple but this one I don't understand?

THX

CS

xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

Post by xor » Fri Dec 15, 2006 2:44 pm

CS,

A Word variable is set up in memory as Byte0 (low byte)/ Byte1 (high byte), sequentially in that order. If you look under Memory Organization in the datasheet you will also not that most, if not all, 2-byte Special Function Regesters (SFR) are LowByte/HighByte sequentially in memory.

When you declare TMR0L.AsWord you are telling the compiler that you are working with 2-bytes (a Word) starting with TMR0L. Effectively, you are using the whole 16-bit TMR0 register of TMR0L/TMR0H.

I think this a really great feature of Swordfish and simplifies how you work with GFR's and SFR's in memory. It is especially notable that Swordfish writes to TMR0H first when working with TRM0L.AsWord, which follows the rules for writing to this particular register in 16-bit mode.

TimB
Posts: 262
Joined: Wed Oct 04, 2006 7:25 am
Location: London UK

Post by TimB » Fri Dec 15, 2006 2:45 pm

Timer 0 on the 18series can be a 8 bit or a 16 bit timer.

Dim TMR0 as TMR0L.AsWord forces the compiler to use the register as a word variable and load both. How ever of you do that then remember to set the Tmr up as a 16 tmr or you will end up with some strange results.

CS
Posts: 127
Joined: Thu Nov 02, 2006 9:14 am

Post by CS » Fri Dec 15, 2006 4:37 pm

Thanks to all!

Hopefully I understood everything. At this time I'll try to understand all the interrupt things!

CS

CS
Posts: 127
Joined: Thu Nov 02, 2006 9:14 am

Post by CS » Sat Dec 16, 2006 3:11 pm

Hi,

I'm back and it seems that I haven't understand everything right. Here is some code, wich makes a little flicker on the display and that's it.

At the bottom of the display is a backgroundpicture shown with an arrow on the left and on the right side. In the middle should stand the menu point. When I press the RB1 or RB2 then the display flicker alittle bit but shows nothing. Where is the misstake?

Code: Select all

Device = 18F452
Clock =  20

#option GLCD_MODEL = SED1520
Include "GLCD.bas"
Include "Fonts.bas"
Include "Bitmaps.bas"
Include "FixedFont.bas"
Include "Convert.bas"

Dim RES As PORTC.4,
    INT0 As INTCON.1,
    INT1 As INTCON3.0,
    INT2 As INTCON3.1,
    SETUP As Boolean,
    aktMenu As Byte
    
Const DegreeSymbol = 127,
      Background(248) As Byte = ($01,122,11,0,$FF,$DF,$8F,$57,$DB,$DF,$DF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$DF,$DF,$DB,$57,$8F,$DF,$FF,
      $07,$07,$07,$07,$06,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$06,$07,$07,$07,$07),
      MenuPoints(5) As String = ("Point 1", Point 2", "Point 3","Point 4","Point 5")
      
interrupt Switches() 
    
    If INT0 = 1 Then
       INT0 = 0
    End If
    If INT1 = 1 Then
       If aktMenu < Bound(MenuPoints) Then
          Dec(aktMenu)
       ElseIf aktMenu = Bound(MenuPoints) Then
          aktMenu = 0
       End If
       SetFont(Fixed)
       TextAlign = taCenter
       Font.Style = 3
       WriteStr(61,22,MenuPoints(aktMenu))
       INT1 = 0
    End If
    If INT2 = 1 Then
        If aktMenu > 0 Then
           Inc(aktMenu)
        ElseIf aktMenu = 0 Then
           aktMenu = Bound(MenuPoints)
        End If
        SetFont(Fixed)
        TextAlign = taCenter
        Font.Style = 3
        WriteStr(61,22,MenuPoints(aktMenu))
        INT2 = 0
    End If 

End interrupt

Sub PrepareDisplayFrame()
    
    Rectangle(0,0,121,21)
    SetImage(0,21,Background,0)
    
End Sub

RCON = 0            ' Disable Interrupt priority
INTCON = %10010000  ' Enable all unmasked interrupts; External Interrupt Int0 enabled
INTCON2 = %01110000 ' External Interrups 0,1,2 at rising edge
INTCON3 = %00011000 ' External Interrupt INT2 enabled

TRISB = 1
High(RES)

SETUP = false
aktMenu = 0
Cls

PrepareDisplayFrame
       
While true

Wend
Reguards

CS

CS
Posts: 127
Joined: Thu Nov 02, 2006 9:14 am

Post by CS » Sat Dec 16, 2006 7:00 pm

I have tried to solve my problem with an event but the problem is still the same. For solving the problem I have reduced the code until the minimum. Hopefully someone can tell me the misstake:

Code: Select all

Device = 18F452
Clock =  20

#option GLCD_MODEL = SED1520
Include "GLCD.bas"
Include "FixedFont.bas"

Type TEvent = Event()

Dim INT0 As INTCON.1,
       INT1 As INTCON3.0,
       INT2 As INTCON3.1,
       aktMenu As Byte,
       Event1 As TEvent

Const MenuPoints(5) As String = ("Point 1", "Point 2","Point 3","Point 4","Point 5")

Event MenuChange()
      SetFont(Fixed)
      Font.Style = 3
      WriteStr(61,23,MenuPoints(aktMenu))
End Event

interrupt Switches() 
    
    If INT0 = 1 Then
       INT0 = 0
    End If
    If INT1 = 1 Then
       If aktMenu < Bound(MenuPoints) Then
          Dec(aktMenu)
       ElseIf aktMenu = Bound(MenuPoints) Then
          aktMenu = 0
       End If
       Event1()
       INT1 = 0
    End If
    If INT2 = 1 Then
        If aktMenu > 0 Then
           Inc(aktMenu)
        ElseIf aktMenu = 0 Then
           aktMenu = Bound(MenuPoints)
        End If
        Event1()
        INT2 = 0
    End If 

End interrupt

RCON = 0                    ' Disable Interrupt priority
INTCON = %10010000  ' Enable all unmasked interrupts; External Interrupt Int0 enabled
INTCON2 = %01110000 ' External Interrups 0,1,2 at rising edge
INTCON3 = %00011000 ' External Interrupt INT1 & INT2 enabled

TRISB = 1

High(PORTC.4)

aktMenu = 0
Cls

Event1 = MenuChange  
       
While true

Wend
The code compiles with no error but it doesn't work. It's like I said before I can only see a little flicker!

Reguards

CS

xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

Post by xor » Sun Dec 17, 2006 6:47 pm

CS,

I noticed that you've enabled and are testing INT1 and INT2 Flags in the Interrupt routine but you have TRISB = 1, which only helps with detecting INT0.

You also have RBPU's enabled (INTCON2.7 = 0), which means that your switch/button input is already held high and so cannot see a rising edge.

As a matter of course, check your configurations for WDT, HS_OSC, LVP, and others that can affect your PIC's functionality.

Post Reply