Simple interrupt


Closed Thread
Results 1 to 11 of 11
  1. #1
    Join Date
    Aug 2008
    Posts
    42

    Default Simple interrupt

    Hello All,
    I know this subject has been covered many times but I just don't understand how to setup a simple external interrupt.
    I am using portA on my 16f88 for outputs to a stepper motor. Port B is for my inputs. Can someone show me how to set portb.2 as the interrupt? I wish to push a button and apply 5v to this pin and have the program restart. Please show the handler code and where it should be placed in a program. Many thanks to anyone that can help.

  2. #2
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Simple interrupt

    Much easier to use portb.0 interrupt for a single button.

    Your program only has to restart and take no special action or remember nothing?
    Then why an interrupt at all?

    Why not check the button in your main routine and then reset variables and restart the main loop on the button push?

    Better still, enable MCLR in config settings and use a reset button to reset the chip at hardware level.
    Then all of your variables are cleared, and your program restarted for free (no code space used).

  3. #3
    Join Date
    Aug 2008
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Simple interrupt

    Thanks for responding Art, the program that I am running goes into several long pauses, PAUSE 20000 for example. You have a simple solution that normally would work, I can insert a button on MCLR instead of having it permanently tied to 5v, but this is an automotive application and I need a reduced signal from the brake switch to restart the program. Here is my program, it is an attempt at a simple cruise control for an automobile. Please forgive my old style way of programming, but the program works, at least on the bench, I just need a way of restarting the program even when it is in those long pauses. Portb.0 can be changed so that it can be an interrupt, but I don't know how to code it. This simple program counts pulses from the Vehicle Speed Sensor, (VSS), stores it in B1, then counts again and stores the result in B2. Then it compares the two signals and makes adjustment to the throttle via a stepper motor. Any further help or ideals would very much be appreciated.

    ' Cruise Control Program
    ' Microcontroller used: 16F88
    ' 20 MHZ CRYSTAL fuse at hs
    ' Porta.0 - Porta.3 are stepper motor outputs
    ' Portb.0 is signal in from VSS (Vehicle Speed Sensor)
    ' Portb.1 is the signal to engage when 5v is applied. 10K tied to ground
    ' Portb.2 is tied to the brake switch. 10 k tied to ground
    ' Fine tuning may need to the "ti" and "ts" variables for vehicle,
    ' they also may need to be a "byte" instead of "word".


    :START
    clear
    C var byte
    ti var byte
    ts var word
    B1 var word
    B2 VAR word
    TRISa = %00000000
    trisb = %00000111
    portb = 0
    porta = 0
    c = 0
    ti = 50 ' this is the pause between motor turns
    ts = 2500 ' this changes how long of a count in milliseconds

    INIT:
    IF PORTb.1 = 1 THEN COUNTER1 'Press sw1 to engage
    pause 100
    GOTO INIT


    COUNTER1:
    if portb.0 = 1 then counter1 ' Wait till end of pulse
    count portb.0 ,ts, B1 ' read pulses from vss for ? second
    pause 500


    CRUISE:
    if portb.0 = 1 then Cruise ' Wait till end of pulse
    count portb.0 ,ts, B2 ' get a second reading and store in B2
    IF PORTb.2 = 1 THEN porta = 0:goto START ' BRAKE LIGHT SIGNAL, kill NOW
    IF B2 > B1 THEN REVR
    IF B2 < B1 THEN FORW
    pause 20000 ' If B2 = B1 then pause
    goto cruise


    FORW:
    PORTa = %00000011
    PAUSe ti
    PORTa = %00000110
    PAUSE ti
    PORTa = %00001100
    PAUSE ti
    PORTa = %00001001
    PAUSE ti
    C = C + 1
    if c = 10 then portb = 0:goto start ' if no response after 10 sweeps then restart
    pause 20000
    GOTO cruise


    REVR:
    PORTa = %00001001
    PAUSE ti
    PORTa = %00001100
    PAUSE ti
    PORTa = %00000110
    PAUSE ti
    PORTa = %00000011
    PAUSE ti
    C = C - 1
    pause 20000
    GOTO cruise

  4. #4
    Join Date
    May 2006
    Location
    Del Rio, TX, USA
    Posts
    343


    Did you find this post helpful? Yes | No

    Default Re: Simple interrupt

    Here is another way to do the pause:


    FOR I = 1 to 200
    PAUSE 100
    'Check for button press here
    NEXT I

  5. #5
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Simple interrupt

    I would normally use Steve's solution above, but you won't be able to check button pushes in the
    2.5 second COUNT command that way.

    Let's hope I remember everything, and I'm assuming registers for 16F877A are the same for your chip.

    Near the start of your program, after any defines:

    Code:
    Define  INTHAND _Brake    ' Tell PBP Where the code starts on an interrupt
    INTCON.4 = 1                                    'enable portb.0 interrupt
    intoccured var byte
    Then straight after that:

    Code:
    '****************************************************************
    '*  Name    : ASM_INTS.PBP                                      *
    '*  Author  : Darrel Taylor                                     *
    '*  Notice  : Copyright (c) 2003                                *
    '*  Date    : JAN 4, 2003                                       *
    '****************************************************************
    
    wsave       var byte    $20     SYSTEM          ' location for W if in bank0
    
    ' --- IF any of these three lines cause an error ??  Simply Comment them out to fix the problem ----
    wsave1      var byte    $A0     SYSTEM          ' location for W if in bank1
    wsave2      var byte    $120    SYSTEM          ' location for W if in bank2
    wsave3      var byte    $1A0    SYSTEM          ' location for W if in bank3
    ' ------------------------------------------------------------------------------
    
    ssave       var byte    BANK0   SYSTEM          ' location for STATUS register
    psave       var byte    BANK0   SYSTEM          ' location for PCLATH register
    fsave       var byte    BANK0   SYSTEM          ' location for FSR register
    
    Asm
    INT_START  macro
        IF (CODE_SIZE <= 2)
            movwf   wsave            ; copy W to wsave register
            swapf   STATUS,W         ; swap status reg to be saved into W
            clrf    STATUS           ; change to bank 0 regardless of current bank
            movwf   ssave            ; save status reg to a bank 0 register
            movf    PCLATH,w         ; move PCLATH reg to be saved into W reg
            movwf   psave            ; save PCLATH reg to a bank 0 register
        EndIF
        movf      FSR,W              ; move FSR reg to be saved into W reg
        movwf     fsave              ; save FSR reg to a bank 0 register
        endm
    EndAsm
    
    Asm
    INT_RETURN   macro
        MOVF    fsave,W              ; Restore the FSR reg 
        MOVWF   FSR
        Movf    psave,w              ; Restore the PCLATH reg
        Movwf   PCLATH
        swapf   ssave,w              ; Restore the STATUS reg            
        movwf   STATUS
        swapf   wsave,f
        swapf   wsave,w              ; Restore W reg
        Retfie                       ; Exit the interrupt routine    
        endm
    EndAsm
    Then this:

    Code:
    '*********************** ISR *****************************
    Brake:
    @ INT_START                    
    '
      R0save = R0                     ; Save 2 PBP system vars that are used during
      R1save = R1                     ; the interrupt
    '
    IF INTCON.1 = 1 THEN        'handle portb.0 interrupt
    INTCON.1 = 0            'clear portb.0 interrupt flag
    goto overextint            'skip over timer interrupt handler
    ENDIF                '
    '
    overextint:
    '
      R1 = R1save                     ; Restore the PBP system vars
      R0 = R0save
    @ INT_RETURN                      ; Restore context and return from interrupt
    '
    '*********************************************************
    Now this would usually jump back to the point of execution it left from,
    but you want to reset, and need not bother with resoring context,
    so I'd create a routine that resets all vars and goes to the start of your program,
    name it overextint: and delete the overextint label from this code.

    If this works, thank Darrel, if it's broken, blame me!
    Last edited by Art; - 1st March 2012 at 23:38.

  6. #6
    Join Date
    Aug 2008
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Simple interrupt

    Wow, all of that for an interrupt huh. Maybe I should try some other way, all that code looks like Greek to me. Is all that crap really necessary?
    I do appreciate any help but I hate assembly language , mainly because I don't know it. This all really leaves me scratching my head.

  7. #7
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Simple interrupt

    You don't have to know it.
    You only need to change one label and never look at it again
    (assuming I've got it right which is an assumption :P

  8. #8
    Join Date
    Aug 2008
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Simple interrupt

    I think Steve is on to something, most of the time program execution works great. It is when it goes into the long pauses, necessarily so, that I can't stop the program. Wait........Just tried it and it seems to work !!!
    I put Steve's code in where there was the pause 20000 and it I pleased thus far in my tests on the bench. I noticed the other day while driving that unless your going uphill your are really giving your car very little throttle and therefore the stepper motor must do the same thing and make slow adjustsments and await the result and either adjust or continue to hold the throttle right where it is. This program will hopefully do that. I'm sure that it will need further tweaking. I just mounted my stepper motor and made an arm that is mechanically connected to my throttle valve. Next I am going to build the hardware for the project, (an enclosure for my electronics, mounting switches etc). My Kudos to Steve and Art. I will post my results in few days.

    Thank You Thank You
    Thank You Thank You

  9. #9
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Simple interrupt

    That method will work unless you brake while program execution is being held up by the COUNT command.
    If you decided to brake while that command was starting out it's time duration, it would take 2.5 seconds
    for your program to know you hit the brakes, and if you brake for less than 2.5 seconds at that time,
    your program will never register it. Sub standard for an auto application.

  10. #10
    Join Date
    Aug 2008
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Simple interrupt

    True but at 20 mhz that 2.5 seconds seems more like 1 second, Also I can lower this to say 1000 and it still works well. A less than elegant solution, I know, but I am not a programmer. If I am unsatisfied with it on the road then I may try a relay attached to the brake switch that controls mclr. I just thought that in PicBasicPro you could enter a few simple lines of code like ON INTERRUPT GOTO START and it was as easy as pie, I guess not. Everyone says read the spec sheet on the chip, well I have downloaded them and I am still lost. I guess I am just to damn old to understand it.

  11. #11
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Simple interrupt

    At 20 Mhz, that 2.5 second delay is only going to be half a second... much more acceptable.
    Didn't see that in your comments before.

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts