16F1827 interrupt hosed


Closed Thread
Results 1 to 19 of 19
  1. #1

    Question 16F1827 interrupt hosed

    This is very strange. I have the interrupt working with a toggle on RB1 while main is generating in a loop a pulse on RB0.
    During power up both ports are putting out a toggle, but about 5 to 10 seconds after power on the interrupt generated toggle stops. Main still is toggling away. I went through and made sure other peripheral interrupt sources are off...

    what am I missing? Would someone please load this code and verify that the interrupt is stopping for some reason?



    Code:
    
    ' This code is for 16F1827 MCU with built in oscillator (Max Osc 32Mhz)
    ' Code requires PicBasic Pro 2.60 along with MPASM assembler
    
    ASM
        __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
        __config _CONFIG2, _PLLEN_OFF & _LVP_OFF & _LVP_OFF & _STVREN_OFF
            
    ENDASM
    DEFINE OSC 8  
        
    ' Define ADCIN parameters
      DEFINE ADC_BITS 8   ' Set number of bits in result
      DEFINE ADC_CLOCK 4   ' Set clock source, look on data sheet for chart
      DEFINE ADC_SAMPLEUS 500   ' Set sampling time in uS 
      
      DEFINE  INTHAND myint                   ' Setup interrupt handler
       
    ;*******************************************************************************
    ;*******************************************************************************
    ; System hardware configuration
    ;*******************************************************************************
    ;*******************************************************************************
            OSCCON = %01110000   ' 8MHz internal
            ANSELA = %00000001   ' all digital. A/D disabled
            ANSELB = %00000000
            TRISB = %00000000    ' set port directions 0 = output, 1 = input
            TRISA = %00000001
            ADCON0 = %00000111  ' Set PORTA digital 1, analog 0
            APFCON0.0 = 1        ' CCP1 PWM output on RB0
            APFCON0.3 = 1        ' CCP2 PWM output on RA7
            APFCON1 = 1
            CCPR1L    = 64       ' Set PWM Duty-Cycle to 50%
            CCPR2L    = 64
            PR2 = 49             ' Set PWM frequency 
            CCP1CON = %00000000  ' Mode select = PWM off , to turn on %00001100
            CCP2CON = %00000000  ' Mode select = PWM off, to turn on %00001100
            T2CON = %00000110    ' %00000100 = TMR2 ON 1:1  pre-scale
                                 ' %00000101 = TMR2 ON 1:4  pre-scale
                                 ' %00000110 = TMR2 ON 1:16 pre-scale
                                 ' %00000111 = TMR2 ON 1:64 pre-scale
     
            
    ;*******************************************************************************
    ; Program variables 
    ;*******************************************************************************
            ADCVAL  var byte
          
            
            
    ;*******************************************************************************        
    ; Program constants
    ;*******************************************************************************
            
     
    
    ;******************************************************************************* 
    ; Power on initialization to known port states   
    ;*******************************************************************************
          
    PowerOn_init: 
            PortA = 0             ' force low to avoid glitches 
            POrtB = 0
            PIR1 = 0             ' clear TMR1 int flag
            PIE1 = %00000001     ' TMR1 int enabled
            INTCON = %11000000   ' global & peripheral ints enabled
            T1CON = %00010001    ' TMR1 1:2 prescale, timer1 on
    
    ;*******************************************************************************
    ;*******************************************************************************
     goto mainloop
    asm
    ; Save W, STATUS and PCLATH registers, if not done previously
    myint   
            ; retfie auto-restores w, status, bsr, fsr and pclath
      bcf   T1CON,TMR1ON ; stop timer 1
      bcf   PIR1,TMR1IF  ; clear over flow flag
      movlw 0xEF         ; load timer for 16,535 * 2 prescaler interrupt on 16 bit timer
      movwf TMR1H        ; load high byte
      movlw 0xEF         
      movwf TMR1L        ; load low byte
      bsf   T1CON,TMR1ON ; re-enable timer 1
      movlw 0x02
      xorwf PORTB,f      ; toggle RB1
      retfie             ; Return from interrupt
     
            retfie                        ; Return from interrupt
    endasm
     
     
    mainloop:
        adcin 0, adcval
        
        LATB.0 = 1
        pauseus (4*adcval) + 1000
        LATB.0 = 0 
        pause 15
        
        goto mainloop

  2. #2
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    Try adding BSR=0 as the first asm instruction in your ISR. If this works, I will be happy to explain why. But if not the reason will confuse the issue.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    Very strange...I did what you suggested but it only prolonged the end result. I am seeing two things when the interrupt crashes....either it hoses the main loop and the interrupt oscillates at a high frequency of 235 Khz or it completely stops and main keeps going with its toggle. This is what I added to the ISR.

    Code:
    asm
    ; Save W, STATUS and PCLATH registers, if not done previously
    myint   
            ; retfie auto-restores w, status, bsr, fsr and pclath
      
      bcf   BSR,0
      bcf   T1CON,TMR1ON ; stop timer 1
      bcf   PIR1,TMR1IF  ; clear over flow flag
      movlw 0xEF         ; load timer for 16,535 * 2 prescaler interrupt on 16 bit timer
      movwf TMR1H        ; load high byte
      movlw 0xEF         
      movwf TMR1L        ; load low byte
      bsf   T1CON,TMR1ON ; re-enable timer 1
      movlw 0x02
      xorwf PORTB,f      ; toggle RB1
      retfie             ; Return from interrupt
            
    endasm

  4. #4
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    Try bsr=0. There maybe more bank select bit then just 1.Like this:
    Code:
    Myint
    Bsr=0
    asm
    Rest of isr
    OR
    Code:
    myint
    asm
    clrf bsr
    rest of isr
    Last edited by cncmachineguy; - 18th October 2011 at 05:43.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  5. #5
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    here is what I think is happening:
    When the INT is called, the state of the BSR is unknown. If the main program is doing something that requires bsr to be other then 0, when you enter the ISR you can't manipulate the things in the ISR because the wrong bank is selected.

    When you added the BCF BSR,0 - This almost fixed it but not quite. When it stays in the ISR that is because you can't clear the flag (acting on wrong reg, NOT PIR) so the INT just fires forever. My guess is when you think the main is running without INT, that may be not true, it may be that you just aren't toggling the output so you think the ISR has not fired.

    The easiest way I know of to troubleshoot this is using MPLAB SIM inside of MPLAB. put a breakpoint at the first line of the ISR, then when it fires you can single step through while watching reg's like port b and even better BSR!
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  6. #6


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    Thanks for your help! I will try your suggestion. I did notice one thing before leaving the office last night, when I remove the ADC from main everything works well. When I rerun the test using ADC enabled it screws things up. Do I need to also do something with T1CON like select a bank of memory that it can write to that is common across banks? some how I think writing to values to the timer is somehow not being read out of the correct bank at some point after the interrupt is enabled upon exit....just my guess.

    Nick

  7. #7
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    BSR will be restored when you exit the ISR. That chip auto saves and restores W,PC,Status, BSR, I think. So no need to worry about it from the Main point of view. I have not checked the banks you are using in the ISR, but I am thinking since it works sometimes they may be all in BANK 0. Could be the ADC is whats creating the NON bank 0 setting in the BSR.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  8. #8


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    Bert,

    Thanks for the help. I used your suggestion in conjunction with BANKSEL T1CON at the start of the ISR after the ASM tag. It all works now!!!

    Nick

  9. #9
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    do you understand why? sounds like you do. BTW DT_INT takes care of BSR for you I think. I am being pushed towards using them and prolly will end up there. Just an FYI.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  10. #10


    Did you find this post helpful? Yes | No

    Question Re: 16F1827 interrupt hosed

    I am seeing something strange.....It seems I can not read my ADC's or run anything in main when my interrupt is enabled. What my code is supposed to do is output a 1.5ms pulse every 16ms for "home" position on 4 servo's in the interrupt. At any time an ADC value on 5 ADC's is above a threshold I want to stop the interrupt and run the scaled up ADC values to run my servo's in real time. What am I missing?

    Code:
     
    ASM
        __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
        __config _CONFIG2, _PLLEN_OFF & _LVP_OFF & _LVP_OFF & _STVREN_OFF
            
    ENDASM
    DEFINE OSC 8  
        
     ;Define ADCIN parameters
     
      DEFINE ADC_BITS 8   ' Set number of bits in result
      DEFINE ADC_CLOCK 4   ' Set clock source, look on data sheet for chart
      DEFINE ADC_SAMPLEUS 500   ' Set sampling time in uS 
      
      DEFINE  INTHAND myint                   ' Setup interrupt handler
       
    ;*******************************************************************************
    ;*******************************************************************************
    ; System hardware configuration
    ;*******************************************************************************
    ;*******************************************************************************
            OSCCON = %01110000   ' bit.7 =32MHz internal
            ANSELA = %00000001   ' all digital. A/D disabled
            ANSELB = %00000000
            TRISB =  %00000000    ' set port directions 0 = output, 1 = input
            TRISA =  %00000001
            ADCON0 = %00000111  ' Set PORTA digital 1, analog 0
            ADCON1 = %01000000
             
            
    ;*******************************************************************************
    ; Program variables 
    ;*******************************************************************************
            ADCVAL      var     byte   bank0   
            ADCVAL2     var     byte   bank0  
            ADCVAL3     var     byte   bank0   
            ADCVAL4     var     byte   bank0   
            ADCVAL5     var     byte   bank0   
            
            
    ;*******************************************************************************        
    ; Program constants
    ;*******************************************************************************
            centM       con     1500        ;motor stop
            forM        con     2000        ;motor forward
            revM        con     1000        ;motor reverse
            
     
    
    ;******************************************************************************* 
    ; Power on initialization to known port states   
    ;*******************************************************************************
          
    PowerOn_init: 
            PortA = 0             ' force low to avoid glitches 
            POrtB = 0
            PIR1 = 0              ' clear TMR1 int flag
            PIE1 =   %00000001    ' TMR1 int enabled
            INTCON = %11000000    ' global & peripheral ints enabled
            T1CON =  %00010001    ' TMR1 1:2 prescale, timer1 on
    
    ;*******************************************************************************
    ;*******************************************************************************
     goto mainloop
    asm
    ; Save W, STATUS and PCLATH registers, if not done previously
    myint   
            ; retfie auto-restores w, status, bsr, fsr and pclath
      BANKSEL T1CON 
      clrf  BSR
      bcf   T1CON,TMR1ON ; stop timer 1
      bcf   PIR1,TMR1IF  ; clear over flow flag
      movlw 0xBF         ; load timer for 16,535 * 2 prescaler interrupt on 16 bit timer
      movwf TMR1H        ; load high byte
      movlw 0xFF         
      movwf TMR1L        ; load low byte
      
      call  _home
      
      bsf   T1CON,TMR1ON ; re-enable timer 1
     
    ;  movlw 0x02
    ;  xorwf PORTB,f      ; toggle RB1
      retfie             ; Return from interrupt
            
    endasm
    home:
         if adcval < 4 and adcval2 < 4 and adcval3 <4 and adcval4 < 4 and adcval5 < 4 then
         PORTB = %00001111
           pauseus 1500
         PORTB = %00000000
         endif
    return
        
     
    mainloop:
        call readADC  
        call spin
    '    call forward
    '    call back
    '    call left
    '    call right
        pause 15
        goto mainloop
    
     readADC: 
          adcin 0, adcval   
          ADCIN 1, adcval2
          adcin 2, adcval3
          adcin 3, adcval4
          adcin 4, adcval5
          return
          
          
     spin:
         if adcval > 4 then 
           LATB = %00001111
                pauseus 6*(adcval) + 900
           LATB = %00000000
         endif     
         return
         
                           
     forward: 
         if adcval2 > 4 then
           LATB = %00001100
                pauseus 6*(adcval) + 900
           LATB = %00000000
           LATB = %00000011
                pauseus 6*(adcval) + 900
           LATB = %00000000
         endif
         return
        
     back: 
         if adcval3 > 4 then
           LATB = %00000011
                pauseus 6*(adcval) + 900
           LATB = %00000000
           LATB = %00001100
                pauseus 6*(adcval) + 900
           LATB = %00000000
         endif
        return
        
     left:
         if adcval4 > 4 then
           LATB = %00000101
                pauseus 6*(adcval) + 900
           LATB = %00000000
           LATB = %00001100
                pauseus 6*(adcval) + 900
           LATB = %00001010
         endif
        return
     
     right:
        if adcval5 > 4 then
           LATB = %00001010
                pauseus 6*(adcval) + 900
           LATB = %00000000
           LATB = %00000101
                pauseus 6*(adcval) + 900
           LATB = %00001010
        endif
        return

  11. #11
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    Try changing

    call readADC
    call spin

    to

    GOSUB readADC
    GOSUB spin

    From the manual:
    CALL
    CALL Label
    Execute the assembly language subroutine named Label.
    GOSUB is normally used to execute a PICBASIC PRO™ subroutine. The main difference between GOSUB and CALL is that with CALL, Label=s existence is not checked until assembly time. Using CALL, a Label in an assembly language section can be accessed that is otherwise inaccessible to PBP.
    See the section on assembly language programming for more information on CALL.

    CALL pass ' Execute assembly language subroutine named _pass
    Dave
    Always wear safety glasses while programming.

  12. #12


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    Hello Dave,

    I changed the calls to subs and still nothing runs in main while the interrupt is enabled. I can't even get a simple portb.0 set / reset to give me anything on the I/O.

    Nick
    Last edited by Macgman2000; - 19th October 2011 at 19:41.

  13. #13
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    CALL or GOSUB doesn't make any difference.
    But you cannot run Basic Language statements in an Assembly Language interrupt.
    Re-use of PBP's system variables will corrupt the main programs flow.

    If you want to use Basic statements in ASM interrupts, you need to either use ON INTERRUPT or DT_INTS.
    DT

  14. #14


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    Darrel,

    How would I structure my code using your interrupt include file? I want to accomplish the following:

    1). update 4 servo's with a refresh rate of 16ms. Pulse width on the servos range between 1 ~ 2 ms based on reading 5 ADC channels.

    Best Regards,
    Nick

  15. #15


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    I found this in the new PBP3 Reference Manual on page 264

    "Whenever a block of inline Assembly Language is entered, PBP sets the bank-select register to BANK0".

    So, why does Nick have to manually select BANK0 using BANKSEL T1CON? It's true that all of the registers in his ISR are in BANK0. And yes, all his A to D registers are in BANK1, but why isn't PBP doing the switch to BANK0?

  16. #16
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    Good catch! Looks like I updated pbp but not my brain. Yet another good reason to upgrade

    Darrel are you referring to the pauseus? If so are the rest non system variable things?
    Last edited by cncmachineguy; - 20th October 2011 at 04:26.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  17. #17
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    Quote Originally Posted by Macgman2000 View Post
    ... How would I structure my code using your interrupt include file? ...
    I guess the structure would look a lot like the examples found here ... http://www.darreltaylor.com/DT_INTS-14/hello.html
    Look at the Hello World, Blinky Light, Elapsed Timer and then how they are combined 1-3.
    DT

  18. #18
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    Quote Originally Posted by cncmachineguy View Post
    Darrel are you referring to the pauseus? If so are the rest non system variable things?
    if adcval < 4 and adcval2 < 4 and adcval3 <4 and adcval4 < 4 and adcval5 < 4 then

    That is a compound if statement, meaning there is more than one condition to be tested.
    That requires it to store intermediate results in T? temp variables, which are part of PBP's system vaiables.
    The compares themselves will call a library function that uses R? system vars.

    PAUSEUS will overwrite the R0 system variable.
    PAUSE would use R0 and R1.

    It's very difficult to know which statements will interfere with which system variables.
    So it's best not to tempt fate.
    Last edited by Darrel Taylor; - 20th October 2011 at 04:55.
    DT

  19. #19
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: 16F1827 interrupt hosed

    Thanks Darrel
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

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