TMR1 issue


Closed Thread
Results 1 to 7 of 7

Thread: TMR1 issue

  1. #1
    Join Date
    Apr 2012
    Location
    Leicester UK
    Posts
    21

    Default TMR1 issue

    I'm trying to write a sample piece of code to explore the use of TMR1, I have TMR1 overflowing and triggering an interrupt which works. Though I appear to have an issue with setting up the Preload of the register. The TMR1 preload should be set up from the analogue input and then transferred later in the program to the TMR1 register. I have put an IF statement in the code to make the time that the LED, that is triggered by TMR1, stay on and off 10 times longer so any change in length caused by the preload is more noticeable.

    The issue is, no matter how much I vary the voltage divider on the analogue input it doesn't appear to adjust how long it takes to turn the LED output on and off.

    If anybody can give me some help with my code it would be highly appreciated.

    Code:
    clear
    DEFINE OSC 8
    
    'GP0 LED OUT
    'GP1 AD1 FOR POT INPUT
    'GP2 LED STATUS
    
    'REGISTERS
    OPTION_REG = %11000000
    INTCON = %11000000
    PIE1 = %01000001
    PIR1 = %00000000
    OSCCON = %01110001
    TRISIO = %00000001
    ANSEL = %01010001
    'T1CON = %00110001
    CCP1CON = %00000000
    CMCON0 = %00000100
    
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    
    ;---------------------------------------------------------------------------
    wsave   VAR BYTE    $20     SYSTEM      ' location for W if in bank0
    ;wsave   VAR BYTE    $70     SYSTEM      ' alternate save location for W 
                                             ' if using $70, comment wsave1-3
    
    ' --- IF any of these three lines cause an error ?? ------------------------
    '       Comment them out to fix the problem ----
    ' -- Which variables are needed, depends on the Chip you are using -- 
    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
    ' --------------------------------------------------------------------------
    
    'OUTPUT PINS
    LEDOut VAR GPIO.0
    LEDStatus VAR GPIO.2
    
    T1CON = %00110001
    
    'VARIABLES
    LENGTH VAR WORD
    PauseA var byte
    PASS var byte
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    TMR1_INT,  _StateChange,   PBP,  yes
            INT_Handler    AD_INT,  _PulseLength,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    ADCON0 = %00000111
    
    'MAIN PROGRAM
    MAIN:
    pausea = 0
    WHILE PauseA <= 100
        PAUSEA = PAUSEA + 1
        pause 1
    wend
    toggle ledstatus
    GOTO MAIN
    
    'SUB PROGRAMS
    PulseLength:
    LENGTH.highbyte = ADRESH   'SET UP THE TIMER SET UP VARIABLES
    LENGTH.lowbyte = ADRESL
    ADCON0 = %00000111
    @ INT_RETURN ;RETURN
    
    StateChange:
    if pass=10 then
        TOGGLE lEDOUT
        pass = 0
        else
        pass = pass + 1
    endif
    
    TMR1H = LENGTH.highbyte 'Transfer the timer variables to the timer register
    TMR1L = LENGTH.lowbyte
    T1CON = %00010101
    @ INT_RETURN ;RETURN
    END

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: TMR1 issue

    I'm a bit surprised you're getting any interrupts tripped at all because I don't see anything that actually enables them. Well, I do see the setting of PIE1 and that might do it but with DT-INTS you usually do
    Code:
    @ INT_ENABLE TMR1_INT
    @ INT_ENABLE AD_INT
    Is your voltage divider connected to AN0?

    Which chip are you using?

    /Henrik.

  3. #3
    Join Date
    Apr 2012
    Location
    Leicester UK
    Posts
    21


    Did you find this post helpful? Yes | No

    Default Re: TMR1 issue

    I am using a PIC12F683. Initially I had the voltage divider attached to AN0 but it is now connected AN1 and I changed the code to allow it to function while connected to that pin.

    I didn't realise that I had to include the @ INT_ENABLE TMR1_INT and @ INT_ENABLE AD_INT lines as my previous code that included the DT-INTS didn't have those lines in. Please see: http://www.picbasic.co.uk/forum/showthread.php?t=16433

    For Reference these pins are the inputs and the outputs:
    'GP0 LED OUT
    'GP1 AD1 FOR POT INPUT
    'GP2 LED STATUS

    I'll try adding the enable lines to the code, I'm also going to put the status LED on the analogue interrupt routine so I know that is triggering.

    Thank you for your help

  4. #4
    Join Date
    Apr 2012
    Location
    Leicester UK
    Posts
    21


    Did you find this post helpful? Yes | No

    Default Re: TMR1 issue

    I have put an extra LED into the circuit to monitor whether the Analogue Interrupt is being triggered, this LEDstatus1 (analogue interrupt sub program) does not seem to toggle. This leads to believe that the issue maybe to do with the analogue input not being read.

    Code:
    clear
    DEFINE OSC 8
    
    'GP0 LED OUT
    'GP1 AD1 FOR POT INPUT
    'GP2 LED STATUS
    'GP5 LED STATUS 1
    
    'REGISTERS
    OPTION_REG = %11000000
    INTCON = %11000000
    PIE1 = %01000001
    PIR1 = %00000000
    OSCCON = %01110001
    TRISIO = %00000001
    ANSEL = %00100001
    CCP1CON = %00000000
    CMCON0 = %00000100
    
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    
    ;---------------------------------------------------------------------------
    wsave   VAR BYTE    $20     SYSTEM      ' location for W if in bank0
    ;wsave   VAR BYTE    $70     SYSTEM      ' alternate save location for W 
                                             ' if using $70, comment wsave1-3
    
    ' --- IF any of these three lines cause an error ?? ------------------------
    '       Comment them out to fix the problem ----
    ' -- Which variables are needed, depends on the Chip you are using -- 
    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
    ' --------------------------------------------------------------------------
    
    'OUTPUT PINS
    LEDOut VAR GPIO.0
    LEDStatus VAR GPIO.2
    LEDStatus1 var GPIO.5
    
    high ledstatus
    pause 500
    low ledstatus
    pause 1000
    high ledstatus
    pause 500
    low ledstatus
    T1CON = %00110001
    
    'VARIABLES
    LENGTH VAR WORD
    PauseA var byte
    PASS var byte
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    TMR1_INT,  _StateChange,   PBP,  yes
            INT_Handler    AD_INT,  _PulseLength,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    @ INT_ENABLE TMR1_INT
    @ INT_ENABLE AD_INT
    
    ADCON0 = %00000111
    
    'MAIN PROGRAM
    MAIN:
    pausea = 0
    WHILE PauseA <= 10
        PAUSEA = PAUSEA + 1
        pause 1
    wend
    toggle ledstatus
    GOTO MAIN
    
    'SUB PROGRAMS
    PulseLength:
    LENGTH.highbyte = ADRESH   'SET UP THE TIMER SET UP VARIABLES
    LENGTH.lowbyte = ADRESL
    ADCON0 = %00000111
    toggle ledstatus1
    @ INT_RETURN ;RETURN
    
    StateChange:
    if pass = 10 then
        TOGGLE lEDOUT
        pass = 0
        else
        pass = pass + 1
    endif
    
    TMR1H = LENGTH.highbyte 'Transfer the timer variables to the timer register
    TMR1L = LENGTH.lowbyte
    T1CON = %00010101
    @ INT_RETURN ;RETURN
    
    END
    If anybody can see any issues I would appreciate it

    Thank you

  5. #5
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: TMR1 issue

    Hi,
    The datasheet says not to set ADON and GO/DONE bits at the same time. I don't know why and I'd guess it's got nothing to do with the problem but you never know. First set up and turn on the ADC in your initialisation, then flip the GO/DONE bit (ADCON0.1 = 1) when you want to start a conversion.

    Your comments in the code says the pot input is on GP1. The code does not set GP1 to input and does not set GP1 to analog. In a previous message though you said you had moved the pot input from GP1 to GP0 (which matches the TRIS and ANSEL setting) but if so it looks like your trying to sample the wrong input because ADCON0=%00000111 would sample GP1.

    You also seams to have CM-/GP1/AN1 configured as input to the comparator - don't know if that may present a problem.

    Well, not much concrete but atleast something to look into. I'd probably try getting the ADC running outside the interrupts to begin with it. Start it, poll the interrupt flag, get the result (or even use ADCIN for that matter). Then, when that works move it to interrupts.

    BTW, you're currently trying to sample as fast as it can possible go. As soon as one conversion is done and serviced you start the next. You'll spend a lot of time jumping in and out of the AD interrupt routine that way and the value doesn't get used untill the timer overflows. Since the timer is only reloaded when it overflows why not sample the pot in the timer interrupt as well?

    /Henrik.

  6. #6
    Join Date
    Apr 2012
    Location
    Leicester UK
    Posts
    21


    Did you find this post helpful? Yes | No

    Default Re: TMR1 issue

    Success!

    Henrik Thank you very much for your assistance. It looks like I need to spend more time and effort looking at and analysing my configuration registers. Though as you suggested it appears that if I set the various interrupt registers (INTCON and PIE1) you do not need the @ INT_ENABLE TMR1_INT and @ INT_ENABLE AD_INT lines (commented out below), maybe Darrel could shed some light on this? Though I must thank him for the DT-Ints code as it does appear to be excellent piece of code.

    To confirm I initially intended to have the analogue attached to AN0 but moved it to AN1 due to realising that I could not have CMCON0 (bits 2-0) set that AN0 as an analogue input and GPIO.1 as a digital input and output. so I swapped them around and unfortunately didn't swap all of the settings in the configuration registers that I should have done.

    I have attached the working code below for anyone to reference in the future.

    Code:
    clear
    DEFINE OSC 8
    
    'GP0 LED OUT
    'GP1 AD1 FOR POT INPUT
    'GP2 LED STATUS
    'GP5 LED STATUS 1
    
    'REGISTERS
    OPTION_REG = %11000000
    INTCON = %11000000
    PIE1 = %01000001
    PIR1 = %00000000
    OSCCON = %01110001
    TRISIO = %00000010
    ANSEL = %00100010
    CCP1CON = %00000000
    CMCON0 = %00000100
    ADCON0 = %00000101
    
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    
    ;---------------------------------------------------------------------------
    wsave   VAR BYTE    $20     SYSTEM      ' location for W if in bank0
    ;wsave   VAR BYTE    $70     SYSTEM      ' alternate save location for W 
                                             ' if using $70, comment wsave1-3
    
    ' --- IF any of these three lines cause an error ?? ------------------------
    '       Comment them out to fix the problem ----
    ' -- Which variables are needed, depends on the Chip you are using -- 
    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
    ' --------------------------------------------------------------------------
    
    'OUTPUT PINS
    LEDOut VAR GPIO.0
    LEDStatus VAR GPIO.2
    LEDStatus1 var GPIO.5
    
    high ledstatus
    pause 500
    low ledstatus
    pause 1000
    high ledstatus
    pause 500
    low ledstatus
    T1CON = %00110001
    
    'VARIABLES
    LENGTH VAR WORD
    PauseA var byte
    PASS var byte
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    TMR1_INT,  _StateChange,   PBP,  yes
            INT_Handler    AD_INT,  _PulseLength,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    '@ INT_ENABLE TMR1_INT
    '@ INT_ENABLE AD_INT
    
    ADCON0 = %00000111
    
    'MAIN PROGRAM
    MAIN:
    pausea = 0
    WHILE PauseA <= 100
        PAUSEA = PAUSEA + 1
        pause 1
    wend
    toggle ledstatus
    GOTO MAIN
    
    'SUB PROGRAMS
    PulseLength:
    LENGTH.highbyte = ADRESH   'SET UP THE TIMER SET UP VARIABLES
    LENGTH.lowbyte = ADRESL
    toggle ledstatus1
    @ INT_RETURN ;RETURN
    
    StateChange:
    if pass = 5 then
        TOGGLE lEDOUT
        pass = 0
        else
        pass = pass + 1
    endif
    
    TMR1H = LENGTH.highbyte 'Transfer the timer variables to the timer register
    TMR1L = LENGTH.lowbyte
    T1CON = %00010101
    ADCON0 = %00000111
    @ INT_RETURN ;RETURN
    
    END
    Thank you again for your assistance, you have been a real help.

    Andrew

  7. #7
    aliciaDJones's Avatar
    aliciaDJones Guest


    Did you find this post helpful? Yes | No

    Default Re: TMR1 issue

    I like the HTML coding and now a little bit about this but want to learn more abut HTML IS this tag is about HTML?

Members who have read this thread : 1

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

Tags for this Thread

Posting Permissions

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