DT INTs which int to use??


Closed Thread
Results 1 to 5 of 5
  1. #1
    Join Date
    Oct 2009
    Location
    Utah, USA
    Posts
    427

    Default DT INTs which int to use??

    working with a 16F690 PIC

    My program is supposed to generate 1 or more pulses of specific length and quantity.

    Thought I had Darrels Instant Interrupts working in my code...

    But when I remarked out these lines (because I thought they were redundant with DT INT's)
    Code:
    'IOCB.7=1    'enable INT on change RB7
    'IOCB.6=1    'enable INT on change RB6
    'IOCB.5=1    'enable INT on change RB5 rotary push button
    My rotary encoder stopped working.

    I had this code in my program also... but I don't think I have the correct interrupt selected.

    Code:
    ASM
    INT_LIST  macro    ; IntSource,     Label,  Type,  Resetflag?                
            INT_Handler    IOC_INT,  _Encoder,   PBP,  yes       
        endm
        INT_CREATE                   ; Creates the interrupt processor
    ENDASM

    So my question is... How does one know which INT to use?? I am wanting to interrupt on change for B.5, B.6, B.7 and sometimes B.4 .
    I am looking at the 16F690 documentation but am confused on exactly how to determine which INT to use.


    I also would like to, at times, disable B.5,6&7 but keep B.4 as interruptable.

    Here is my complete code...
    Code:
    #CONFIG
      __CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _IESO_OFF & _FCMEN_OFF
    #endconfig
    include "ALLDIGITAL.pbp"        ' makes all I/O pins digital, no analog
    INCLUDE "DT_INTS-14.bas"        ; Base Interrupt System
    INCLUDE "ReEnterPBP.bas"        ; Include if using PBP interrupts
    wsave               VAR BYTE    $70     SYSTEM  ' alternate save location for W 
    DEFINE OSC 4
    Define LCD_DREG PORTC
    Define LCD_DBIT 4
    Define LCD_RSREG PORTA
    define LCD_RSBIT 4
    define LCD_EREG PORTA
    define LCD_EBIT 5
    define LCD_BITS 4
    define LCD_LINES 4
    define LCD_COMMANDUS 3000
    define LCD_DATAUS 100
    red   var PortC.0
    grn   var PortC.1
    sLCD  var PortA.2     'serial LCD (if used)
    TrisA = %00000000      'xx543210
    TrisB = %11110000      '7654xxxx
    TrisC = %00001000      '76543210
    ' N/U                   PortB.0  (output)
    ' N/U                   PortB.1  (output)
    ' N/U                   PortB.2  (output)
    ' N/U                   PortB.3  (output)
    ' N/U                   PortB.4  (input - to be grounded)
    ' Encoder PushButton    PortB.5  (input)
    ' Encoder channel A     PortB.6  (use pullups resistor if necessary)
    ' Encoder channel B     PortB.7  (use pullups resistor if necessary)
    '-------------------------------------------------------------------------
    eeprom 0,[2,0,3,1,1,3,0,2]
    PortB = 0
    Flag                var byte
    BtnFlag             var byte '0=adj P1, 1=adj P2, 2=adj Cnt
    CFlag               var bit
    Q_New               var Byte
    Q_Old               var byte
    M_Count             var byte [4]
    P_Count             var byte [4]
    Q_Count             var word
    Low_Count           var word
    L                   var bit  'flag Rotate Left
    R                   var bit  'flag Rotate Right
    P1                  var word  ' first pulse value
    P2                  var word  ' second pulse value
    Cnt                 var word  ' quantity of pulses to generate
    Reps                var word  ' counter to loop for pulses
    Cursor              var word  'if 0 then P1, if 1 then P2, if 2 then Cnt
    Busy                var bit
    P1=500  'default pulse width
    P2=0    'default no second pulse toggle
    Cnt=1   'default count of 1 pulse
    cflag=0 'default to One pulse repitition
    ' ---------------------- Set variable value @ startup ----------------------  
    Start:
    btnflag=0 
    Cursor=0
    low_count = 100
    Busy=0   
    For  Q_Old = 0 to 3
    Read Q_Old,M_Count[Q_Old]
    Read Q_Old + 4,P_Count[Q_Old]
    Next Q_Old
         
      Q_Count = 0   
      Q_New   = 0
      Q_Old   = 0
      Flag    = 0  
    'IOCB.7=1    'enable INT on change RB7
    'IOCB.6=1    'enable INT on change RB6
    'IOCB.5=1    'enable INT on change RB5 rotary push button
          
    ASM
    INT_LIST  macro    ; IntSource,     Label,  Type,  Resetflag?                
            INT_Handler    IOC_INT,  _Encoder,   PBP,  yes       
        endm
        INT_CREATE                   ; Creates the interrupt processor
    ENDASM
    low PortC.2       'initialize contact output
    pause 1000
    Lcdout $FE, 1                      ' Clear LCD screen
    Lcdout $FE,$80,"Pulse Generator"           ' Display message
    'serout2 slcd,16468,[$FE,$80,"Pulse Generator"]
    'serout2 SLCD,16468,[$1b, $2a, $20]
    pause 500
    lcdout $FE,$C0+19,"<" 'initial pointer on P1
    'serout2 slcd,16468,[$FE,$C0+19,"<"]
    gosub disp1
    gosub DisP2
    gosub DisC
    Pause 500                                   ' Wait .5 second
    sound PortA.0,[90,5,100,5,110,5]
    '===============================
    '===========================================================
    '=======     Main Program Loop    ==========================
    '===========================================================
    Main_Loop:
    @   INT_ENABLE   IOC_INT            ; enable external (INT) interrupts
    if PortB.4=0 then gosub pulseout  '  "GO" button pushed so generate pulses
    if PortC.3=0 then                 '  "Toggle" button pushed so invert output
        Toggle PortC.2
        sound PortA.0,[120,2]
        do while PortC.3=0 : loop      'wait for button to be released
    endif
    if flag=0 then main_loop 'no activity from rotary encoder 
    '@ INT_DISABLE           ; DISABLE external (INT) interrupts
    if btnflag=1 then
      if Cursor=0 then         ' erase Cursor on Row 2
        lcdout $FE,$C0+19," " 
        'serout2 slcd,16468,[$FE,$C0+19," "]
      endif 
      if Cursor=1 then         ' erase Cursor on Row 3
        lcdout $FE,$94+19," "  
        'serout2 slcd,16468,[$FE,$94+19," "]
      endif 
      if Cursor=2 then         ' erase Cursor on Row 4
        lcdout $FE,$D4+19," "  
        'serout2 slcd,16468,[$FE,$d4+19," "]
      endif
        
      Cursor=Cursor+1          ' now increment Cursor position
      if (p2>0) and (Cursor=3) then Cursor=0
        if (p2=0) and (Cursor=2) then  'skip moving cursor to 4th row
            Cursor=0                   'instead goto row 2
            cnt=1
            gosub DisC
        endif
        btnflag=0
      if Cursor=0 then                 'display cursor on row 2
        lcdout $FE,$C0+19,"<"
        'serout2 slcd,16468,[$FE,$C0+19,"<"]
      endif 
     
      if Cursor=1 then                 'display cursor on row 3
        lcdout $FE,$94+19,"<"
        'serout2 slcd,16468,[$FE,$94+19,"<"]
      endif
      
      if Cursor=2 then                 'display cursor on row 4
        lcdout $FE,$D4+19,"<" 
        'serout2 slcd,16468,[$fe,$d4+19,"<"]
      endif
      sound PortA.0,[100,2]
    endif
    if Cursor=1 then goto p2counter
    if Cursor=2 then goto ccounter
       'else fall through to P1Counter
    '-------------------------------
    '     adjust value of P1 
    '-------------------------------
    P1Counter:
    if  r =1 then
        high grn 'rotation is Right so Incriment
        if p1>999 then 
            p1=p1+100
        
        elseif p1>99 then 
            P1=P1+10
        else    
            p1=p1+1
        endif
        if p1>10000 then p1=0
        
        gosub DisP1
        r=0
    endif
    if  l =1 then
        High red 'rotation is Left so Decriment 
        if p1>1000 then
            p1=p1-100
          elseif p1>100 then 
            P1=P1-10
          else
            p1=p1-1
        endif
        if p1>65000 then p1=10000
        
        gosub DisP1
        l=0
    endif
    goto Main_Loop
    '-------------------------------
    '     adjust value of P2    
    '-------------------------------
    P2Counter: 
    if  r=1 then
        high grn 'rotation is Right so Incriment
        if p2>999 then 
            p2=p2+100
        
        elseif p2>99 then 
            P2=P2+10
        else    
            p2=p2+1
        endif
        if p2>10000 then p2=0
        
        gosub DisP2
        r=0
    endif
    if  l=1 then
        High red 'rotation is Left so Decriment 
        if p2>1000 then
            p2=p2-100
        elseif p2>100 then 
            P2=P2-10
        else
            p2=p2-1
        endif
        if p2>65000 then p2=10000
        
        gosub DisP2
        l=0
    endif
                              
    goto main_loop
    '-------------------------------
    '     adjust value of Cnt
    '-------------------------------
    CCounter:
    if  r=1 then   'rotation is Right so Incriment
        high grn 
        if cnt>999 then 
            cnt=cnt+100
        
        elseif cnt>99 then 
            cnt=cnt+10
        else    
            cnt=cnt+1
        endif
        if cnt>10000 then cnt=0
        
        gosub DisC
        r=0
    endif
    if  l=1 then   'rotation is Left so Decriment 
        High red 
        if cnt>1000 then
            cnt=cnt-100
        elseif cnt>100 then 
            cnt=cnt-10
        else
            cnt=cnt-1
        endif
        if cnt>65000 then cnt=10000
        
        gosub DisC
        l=0
    endif
                              
    goto main_loop
    '-------------------------------
    '     Update LCD display 
    '-------------------------------
    DisP1:
        If P1>999 then P1Sec   'change to seconds instead of milliseconds
    P1Ms:
        lcdout $FE,$C0,"1st Pulse= ",dec3 P1," mS  "
        'serout2 slcd,16468,[$FE,$C0,"1st Pulse= ",dec3 p1," mS  "]
        goto donelcd
    P1Sec:    
        if P1=10000 then
        lcdout $FE,$C0,"1st Pulse= ",dec2 (P1/1000),".",dec1 (p1/100)," Sec"
        'serout2 slcd,16468,[$FE,$C0,"1st Pulse= ",dec2 (P1/1000),".",dec1 (p1/100)," Sec"]    
        else
        lcdout $FE,$C0,"1st Pulse= ",dec1 (P1/1000),".",dec1 (p1/100)," Sec "
        'serout2 slcd,16468,[$FE,$C0,"1st Pulse= ",dec1 (P1/1000),".",dec1 (p1/100)," Sec "]
        endif
        goto DoneLCD
    DisP2:
        if P2>999 then P2Sec   'change to seconds instead of milliseconds
    P2Ms:    
        lcdout $FE,$94,"2nd Pulse= ",dec3 P2," mS  "
        'serout2 slcd,16468,[$FE,$94,"2nd Pulse= ",dec3 P2," mS  "]
        goto donelcd
    P2Sec:    
        If P2=10000 then
        lcdout $FE,$94,"2nd Pulse= ",dec2 (P2/1000),".",dec1 (p2/100)," Sec"
        'serout2 slcd,16468,[$FE,$94,"2nd Pulse= ",dec2 (P2/1000),".",dec1 (p2/100)," Sec"]
        else
        lcdout $FE,$94,"2nd Pulse= ",dec1 (P2/1000),".",dec1 (p2/100)," Sec "
        'serout2 slcd,16468,[$FE,$94,"2nd Pulse= ",dec1 (P2/1000),".",dec1 (p2/100)," Sec "]
        endif
        goto DoneLCD
        
    DisC:
        if cnt = 10000 then 
            lcdout $FE,$d4,"Continuous Pulses "
            goto DoneLCD
        endif
        if cnt <10 then 
            lcdout $FE,$d4,"Pulse Count= ",dec cnt,"   " 'need extra space char   
            else
            lcdout $FE,$d4,"Pulse Count= ",dec cnt,"  "
        '?? serout2 slcd,16468,[$FE,$d4,"Pulse Count= ",dec cnt,"   "] 
        endif
    DoneLCD:
        Flag = 0                           ' reset flag after display updated
        low red
        low grn       
    return
    '-------------------------------
    '     Generate desired Pulse 
    '-------------------------------
    PulseOut:
    '@ INT_DISABLE RABC_INT            ; disable external (INT) interrupts
    sound PortA.0,[75,2]
    Busy=1
    Continuous:
    if cnt=10000 then 'do continuous pulses
        Toggle PortC.2
        pause P1
        Toggle PortC.2
        pause p2
        goto Continuous   'do unitl Rotary button pushed
    endif
    
    for reps=1 to cnt
        Toggle PortC.2
        pause P1
        Toggle PortC.2
        pause p2
    next reps    
    if (cnt=1) and(P2>0) then Toggle PortC.2  'on/off/on or off/on/off
           
    sound PortA.0,[100,10,50,10]
    pause 500
    Busy=0
    return     'to Main program loop
    '================================================================
    '======================================
    '-- Rotary Encoder Interrupt Handler --
    '======================================
    Encoder:                ' ISR 
    If PortB.5=0 then   'INT caused by encoder push button
        btnflag=1  
        do while PortB.5=0 : loop
        goto Exitint
    endif
    Q_New = PortB.7 + PortB.7 + PortB.6     ' get port status
    '--------------------
    '      decriment    -
    '-------------------- 
    If M_Count[Q_Old] = Q_New then          ' if M_Count code satisfied then minus
        Q_count = Q_Count - 1
        r=1                                ' Set Left Flag
    goto Q_Skip
    endif
    '--------------------
    '      incriment    -
    '-------------------- 
    If P_Count[Q_Old] = Q_New then          ' if M_Count code satisfied then plus
        Q_Count = Q_Count + 1
        l=1                                ' Set Right Flag
    endif
    Q_Skip:
    Q_Old = Q_New                           ' update Q_Old Byte
    ExitInt:
    flag=1 
    @ INT_RETURN

    Also a little unsure of EXACT syntax when using instant interrupts with regard to how many spaces, etc. when defining the interrupts.
    Dwight
    These PIC's are like intricate puzzles just waiting for one to discover their secrets and MASTER their capabilities.

  2. #2
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DT INTs which int to use??

    I used to use a 16f690 (but haven't for ages....the more modern version 16f1828 is much nicer with respect to IOC...unless you are specifically tied to the 16f690 I heartily recommend getting/using a 16f1828 instead...it's pin for pin compatible to the 16f690) ), but here's an old thread where I was struggling with my 16f690 , Bruce sailed to the rescue...

    http://www.picbasic.co.uk/forum/showthread.php?t=13558

    there's an example IOC for a 16f690 zip file attached to the post (near the bottom of that page) ...that should show you how to approach IOC on a 16f690.

  3. #3
    Join Date
    Oct 2009
    Location
    Utah, USA
    Posts
    427


    Did you find this post helpful? Yes | No

    Default Re: DT INTs which int to use??

    Thanks Spankey...

    I followed that thread you referenced and could see that in that case with the 16f690 they used RABC_INT... and I used that in my latest code and it is working. Although I did have to un-comment the lines [CODE]['IOCB.7=1 'enable INT on change RB7
    'IOCB.6=1 'enable INT on change RB6
    'IOCB.5=1 'enable INT on change RB5 rotary push button/CODE]

    So I guess they are not redundant with DT-INT's


    What I am not understanding is how does one determine that RABC_INT is the correct one for 16f690 from the microchip documentation. I searched the .pdf for that PIC and it fails to even find "rabc".

    I also would like clarification on the exact syntax of setting up DT-INT's. ie. where and how many spaces are required at the beginning and inside of each line of the code

    Help me "mister wizard" er... Darrell
    Dwight
    These PIC's are like intricate puzzles just waiting for one to discover their secrets and MASTER their capabilities.

  4. #4
    Join Date
    Oct 2009
    Location
    Utah, USA
    Posts
    427


    Did you find this post helpful? Yes | No

    Default Re: DT INTs which int to use??

    So, for clarification, here is what I have that is working...


    Code:
    IOCB=%11110000    'enable INT on change RB 7,6,5,4
    
    ASM
    INT_LIST  macro    ; IntSource,     Label,  Type,  Resetflag?                
            INT_Handler    RABC_INT,  _Binthndlr,   PBP,  yes       
        endm
        INT_CREATE                   ; Creates the interrupt processor
    ENDASM
    Note that I changed the individual ...
    Code:
    'IOCB.7=1    'enable INT on change RB7
    'IOCB.6=1    'enable INT on change RB6
    'IOCB.5=1    'enable INT on change RB5 rotary push button
    Into one statement...
    Code:
    IOCB=%11110000    'enable INT on change RB 7,6,5,4
    (and added the additional bit that enables IOC on B.4)

    But I still wonder which part of my code is actually enabling the INT on change. As I look over at darrel's web page where he gives examples I do not see anywhere that he has to manipulate the registers to enable the INT's.

    So I am back to thinking that it is really my code
    Code:
    IOCB=%11110000
    that is making the INT's work and part of Darrel's code that tells the PIC where to jump to on INT. "Binthndler"

    still confused
    Last edited by Heckler; - 12th March 2012 at 22:07.
    Dwight
    These PIC's are like intricate puzzles just waiting for one to discover their secrets and MASTER their capabilities.

  5. #5
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DT INTs which int to use??

    To know which Int to use, you need to be a bit of a sleuth, the same thread...

    http://www.picbasic.co.uk/forum/show...2315#post92315 (checkout Bruce's post #30)

    I think you need to open dts_int-14.bas, do a search within for RABC, you should see these entries...

    Code:
      #define RAC_INT      INTCON,RAIF,  INTCON,RAIE   ;-- RA Port Change      *
      #define RBC_INT      INTCON,RBIF,  INTCON,RBIE  ;-- RB Port Change
      #define RABC_INT     INTCON,RABIF, INTCON,RABIE  ;-- RAB Port Change

    ....see which one of those bolded registers a 16f690 actually has & then use the associated DTS Int. (eg search the data sheet for RAIF...nothing, RBIF...nothing, RABIE ...bingo ...so use the RABC_INT)

Members who have read this thread : 0

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