DT_Interrupts - TMR1 Issue With 16F88


Closed Thread
Results 1 to 7 of 7
  1. #1
    Join Date
    May 2011
    Location
    Bangalore, India
    Posts
    33

    Default DT_Interrupts - TMR1 Issue With 16F88

    I tried the test program given by Darrel Taylor - DT_INTS-14 - Blinky Light. It uses Timer1 to blink an LED at a constant rate, no matter what the main code is doing. This is one of the impressive demos of his great DT-Interrupts.

    My idea is to use 16F88 in a power supply circuit with triac. This will be used for power tools like angle grinder that normally do not come with variable speed control. The problem is that the code does not work in a 16F88 while it works beautifully in a 16F628A. The LED blinks at about 1Hz rate in 16F628A but in 16F88 the LED is off or stays permanently lit. I have followed all the instructions and checked the code several times. I cannot spot any mistake in my code for 16F88. I guess, this issue may be related to the number of banks, memory size, etc. according to which some changes may have to be made in the DT_INT software. As per Darrel's instructions, the changes to be made are indicated by the error messages that appear when compiling is done. After I uncommented the line ";wsave VAR BYTE $70 SYSTEM", the compiling went through fine for both the PICs. But only 628A executes the code as desired.

    Though tragically, Darrel is not with us, there are other knowledgeable PIC enthusiasts who can help me out.

    The codes for both the PICs are given below. I would highly appreciate some hints or suggestions that will help me to solve the problem.

    Regards,
    Bala

    Code for 16F628A:
    '************************************************* ***************
    ' DT__Ints-14-Test-02.pbp Date: 23-Mar-15 No. of words: 216

    ' This code is a demo of Instant Interrupts by Darrel Taylor.
    ' An LED is connected to PortB.2 through a 1K resistor. Using TMR1 interrupt,
    ' the LED is made to blink at a constant rate, irrespective of what the main
    ' code is executing.
    '
    'Result: Works beautifully!
    '************************************************* ***************

    'PIC Used: 16F628A
    ;---------------------------------------------------------------------------
    ;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
    ' --------------------------------------------------------------------------
    LED2 VAR PORTB.2

    INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

    asm
    __CONFIG _FOSC_INTOSCIO & _WDT_ON & _PWRTE_ON & _MCLRE_ON & _LVP_OFF & _CP_OFF
    endasm

    TRISA = %00100000 'PortA: All except 5 are outputs
    TRISB = 0 'PortB: All are outputs
    CMCON = 7 'Disable comparator

    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
    INT_Handler TMR1_INT, _ToggleLED2, PBP, yes
    endm
    INT_CREATE ; Creates the interrupt processor
    ENDASM

    T1CON = %00110001 ;Prescaler = 8, TMR1ON
    @ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

    Main:
    PAUSE 1
    GOTO Main

    '---[TMR1 - interrupt handler]--------------------------------------------------
    ToggleLED2:
    TOGGLE LED2
    @ INT_RETURN

    Code for 16F88:
    '************************************************* ***************
    ' DT__Ints-14-Test-02.pbp Date: 23-Mar-15 No. of words: 274
    '
    ' This code is a demo of Instant Interrupts by Darrel Taylor.
    ' An LED is connected to PortB.2 through a 1K resistor. Using TMR0 interrupt,
    ' the LED is made to blink at a constant rate, irrespective of what the main
    ' code is executing.
    '
    'Result: No luck. On 16F88 the code does not work for some reason.
    '************************************************* ***************

    'PIC Used: 16F88
    ;---------------------------------------------------------------------------
    ;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
    ' --------------------------------------------------------------------------
    LED2 VAR PORTB.2

    INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

    asm
    __CONFIG _CONFIG1, _FOSC_INTOSCIO & _MCLRE_ON & _WDTE_ON & _PWRTE_ON & _LVP_OFF & _CPD_OFF & _BODEN_ON & _CCPMX_RB0 & _FCMEN_ON & _IESO_ON & _DEBUG_OFF & _WRT_OFF
    endasm

    TRISA = 0
    TRISB = 0
    CMCON = 7 'Disable comparator
    ANSEL = 0 'All I/O pins are digital
    ADCON0.0 = 0 'Switch off ADC


    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
    INT_Handler TMR0_INT, _ToggleLED2, PBP, yes
    endm
    INT_CREATE ; Creates the interrupt processor
    ENDASM

    OPTION_REG = OPTION_REG & $80 | 1 ; Set TMR0 Prescaler to 256, leave RBPU alone
    @ INT_ENABLE TMR0_INT ; enable Timer 0 interrupts

    Main:
    PAUSE 1
    GOTO Main

    '---[TMR0 - interrupt handler]--------------------------------------------------
    T0Count VAR WORD
    ToggleLED2:
    T0Count = T0Count + 1
    IF T0Count = 512 THEN T0Count = 0 : TOGGLE LED2
    @ INT_RETURN
    '--------------------------------------

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


    Did you find this post helpful? Yes | No

    Default Re: DT_Interrupts - TMR1 Issue With 16F88

    Hi,
    So, you're using TMR1 on the 16F628 and TMR0 on the 16F88?

    If operating at 4MHz and with the prescaler set to 1:256 TMR0 will overflow at around 15Hz.
    The line: IF T0Count = 512 THEN T0Count = 0 : TOGGLE LED2 doesn't work the way I think you want. The TOGGLE command will execute each time - not only when T0Count = 512. So the LED toggles at 15Hz.

    I'm not sure you're actually setting up TMR0 correctly with that weird AND/OR stuff, at least it doesn't seem to match the comment in your code.
    To me it looks like the end result of that operation would be OPTION_REG = %10000001 which means a prescaler of 1:4 so the LED is toggling at ~976Hz. If you want the pullups disabled, TMR0 operating as a timer with a prescaler of 1:256 then simply write OPTION_REG = %10000111

    /Henrik.

  3. #3
    Join Date
    Jan 2013
    Location
    Texas USA
    Posts
    229


    Did you find this post helpful? Yes | No

    Default Re: DT_Interrupts - TMR1 Issue With 16F88

    For the 16F88 I see that you are not setting the OSCCON register which is leaving the oscillator rate at its POR default.
    This coupled with your TMR0 setup and the Timer0 counter is making your LED stay on or off for over a minute.

    By default the OSCCON register is set to %00000000
    Which is 31.250 kHz Internal RC Oscillator Frequency (probably not what you want), and Oscillator mode defined by config bits FOSC<2:0> (which is correct)

    You have the OPTION_REG register set to the following:
    OPTION_REG = OPTION_REG & $80 | 1 which does this.
    OPTION_REG = $FF (default) & $80 | 1 = $81 which does this.
    PORTB pull-ups = disabled
    Interrupt Edge = on falling edge of RB0/INT pin
    TMR0 clock = Internal instruction cycle clock
    Prescaler = set to TMR0
    Prescaler = 1:4

    Now you have Timer0 setup the following way by not setting the OSCCON and OPTION_REG registers set the way you do.

    Internal instruction cycle = 1/[Processor Frequency /4] = 1/(31250/4) = 128us
    Timer0 = 8bit timer
    Timer0 Prescaler = 4
    Timer0 Overflow Interrupt = Internal instruction cycle x Prescaler x 2^8 = 128us x 4 x 256 = 131ms
    So your Timer0 Interrupt fires every 131ms.

    Time to toggle LED2: T0Count x Timer0 Overflow Interrupt = 512 x 131ms = 67.11 seconds.
    So your LED will toggle ~67 on/off.


    For the 16F628 by default the internal oscillator runs at 4Mhz so the Internal instruction cycle is this.
    Internal instruction cycle = 1/[Processor Frequency /4] = 1/(4000000/4) = 1us
    Timer1 = 16bit timer
    Timer1 prescaler = 8

    Timer1 Overflow Interrupt = Internal instruction cycle x Prescaler x 2^16 = 1us x 8 x 65536 = .524 seconds
    So your LED will toggle ~.524 seconds on/off, which is what you would expect.

    To correct your issues you should set the OSCCON and OPTION_REG registers to setup a Timer0 interrupt that you would expect and adjust the Timer0 counter in the interrupt handler appropriately to adjust the on/off rate you are looking for.
    Last edited by Tabsoft; - 23rd March 2015 at 20:43.
    Regards,
    TABSoft

  4. #4
    Join Date
    Jan 2013
    Location
    Texas USA
    Posts
    229


    Did you find this post helpful? Yes | No

    Default Re: DT_Interrupts - TMR1 Issue With 16F88

    To achieve your target .5sec on/off with. TMR0 you can do the following.
    Set the internal oscillator to 4MHz via the OSCCON register.
    Set the TMR0 Prescaler to 1:32 via the OPTION_REG register.
    Then set your T0Count test to "=>61" in the interrupt handler.

    When the values are plugged into the equation you get the following.
    Internal instruction cycle = 1 / [Oscillator Frequency / 4] = 1 / [4000000 / 4] = 1us
    Timer0 Overflow Interrupt = Internal instruction cycle * Prescaler * 2^8 = 1us * 32 * 256 = 8.192ms
    Time to Toggle LED2: T0Count * Timer0 Overflow Interrupt = 61 * 8.192ms = .4997 seconds
    Last edited by Tabsoft; - 23rd March 2015 at 21:20.
    Regards,
    TABSoft

  5. #5
    Join Date
    May 2011
    Location
    Bangalore, India
    Posts
    33


    Did you find this post helpful? Yes | No

    Default Re: DT_Interrupts - TMR1 Issue With 16F88

    Henrik and Tabsoft, thanks a lot for your helpful comments and suggestions.

    I had tried the codes for both TMR0 and TMR1 as given by Darrel. But none of them worked as expected when I used 16F88. The mistake I made is that I assumed the default oscillator frequency of 16F88 to be 4MHz; it's actually 31.25KHz. I have solved my problem by merely adding the line shown below in the beginning of the code for 16F88.

    OSCCON = %01101110 'Bits 6,5,4: 110 = Internal osc is set to 4MHz.

    I have merely copied the code from Darrel's test program for DT_INTS-14 Version 1.1 and there is nothing wrong with the Option_Reg settings for TMR0. What I have added are a few lines specific to the PIC used. With both TMR0 and TMR1, the LED blinks at about 1Hz. The links are given below.
    http://www.dt-ints.com/DT_INTS-14/blinky.html
    http://www.dt-ints.com/DT_INTS-14/combine.html

    Tabsoft, special thanks to you for taking the time for doing all the calculations and suggesting changes in the code. I made the changes as suggested by you for TMR0 (1:32 Prescaler and Toggle the LED if the count >= 61). The LED blinks but at 0.5Hz (1 second On, 1 second Off). So I changed the prescaler to 1:16 and now the LED blinks at 1Hz.

    The updated code that uses TMR0 in 16F88 is shown below.

    Regards,
    Bala

    '************************************************* ***************
    ' DT_Ints-14-16F88-TMR0 Int Test.pbp Date: 24-Mar-15 No. of words: 278
    '
    ' This code is a demo of Instant Interrupts by Darrel Taylor.
    ' An LED is connected to PortB.2 through a 1K resistor. Using TMR0 interrupt,
    ' the LED is made to blink at a constant rate, irrespective of what the main
    ' code is executing.
    '
    'Result: Works perfectly.
    '************************************************* ***************

    'PIC Used: 16F88
    ;---------------------------------------------------------------------------
    ;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
    ' --------------------------------------------------------------------------
    LED2 VAR PORTB.2
    DEFINE OSC 4
    OSCCON = %01101110 'Bits 6,5,4: 110 = Internal osc is set to 4MHz.

    INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

    asm
    __CONFIG _CONFIG1, _FOSC_INTOSCIO & _MCLRE_ON & _WDTE_ON & _PWRTE_ON & _LVP_OFF & _CPD_OFF & _BODEN_ON & _CCPMX_RB0 & _FCMEN_ON & _IESO_ON & _DEBUG_OFF & _WRT_OFF
    endasm

    TRISA = 0
    TRISB = 0
    CMCON = 7 'Disable comparator
    ANSEL = 0 'All I/O pins are digital
    ADCON0.0 = 0 'Switch off ADC


    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
    INT_Handler TMR0_INT, _ToggleLED2, PBP, yes
    endm
    INT_CREATE ; Creates the interrupt processor
    ENDASM

    OPTION_REG = OPTION_REG & $80 | 1 ; Set TMR0 Prescaler to 256, leave RBPU alone
    @ INT_ENABLE TMR0_INT ; enable Timer 0 interrupts

    Main:
    PAUSE 1
    GOTO Main

    '---[TMR0 - interrupt handler]--------------------------------------------------
    T0Count VAR WORD
    ToggleLED2:
    T0Count = T0Count + 1
    IF T0Count = 512 THEN T0Count = 0 : TOGGLE LED2
    @ INT_RETURN

  6. #6
    Join Date
    Jan 2013
    Location
    Texas USA
    Posts
    229


    Did you find this post helpful? Yes | No

    Default Re: DT_Interrupts - TMR1 Issue With 16F88

    Bala,

    Glad to be of help and that you have it working as you wanted.

    I am a little curious about your statements and reported observations though.

    Your posted code does indeed create a ~1Hz blinking led (~.5sec on / ~.5sec off).
    It does this by creating a TMR0 Overflow Interrupt that fires every 1.024ms and your T0Count tests for 512 counts which makes LED2 toggle every ~524ms.

    TMR0 Overflow = (1 / [4000000/4]) * 4 * 256 = 0.001024 seconds (You are setting the Prescaler to 1:4 as "OPTION_REG = OPTION_REG & $80 | 1" does)
    BTW, I guess the comments have not be updated in the posted code for the above OPTION_REG line? ("Set TMR0 Prescaler to 256")

    LED2 Toggle = TMR0 Overflow * 512 = 0.001024 * 512 = 0.524288 seconds
    This creates a ~0.5sec On / ~0.5sec Off rate for ~1Hz.

    You state that my suggestion of setting the TMR0 Prescaler to 1:32 and T0Count test to 61, blinks the light at 0.5Hz (1 second On, 1 second Off).
    And you then set the Prescaler to 1:16 and then LED2 blinks at 1Hz.

    Well, setting up the configuration as I suggested here on my end does create a blinking led at ~1Hz.

    TMR0 Overflow = (1 / [4000000/4]) * 32 * 256 = 0.008192 seconds
    LED2 Toggle = TMR0 Overflow * 61 = 0.008192 * 61 = 0.499712 seconds (~0.5sec On / ~0.5sec Off).

    I have verified your code with my suggested settings added via the simulator (do not have the 16F88 IC) and it blinks at ~1Hz.
    I also verified your posted code as is via the simulator and have the same ~1Hz blinking rate as would be expected from the calculations.

    If you set the Prescaler to 1:16 and leave the T0Count test to 61 then the result would be different.
    TMR0 Overflow = (1 / [4000000/4]) * 16 * 256 = 0.004096 seconds
    LED2 Toggle = TMR0 Overflow * 61 = 0.004096 * 61 = 0.249856 seconds
    Which would cause LED2 to blink at ~2Hz (~.250sec On / ~.250sec Off)

    Perhaps your setting of the OPTION_REG register was not quite right when you tested the suggestions?
    To set the PORTB Pullups enabled and TMR0 Prescaler to 1:32, OPTION_REG = $84 %10000100.
    To set the PORTB Pullups enabled and TMR0 Prescaler to 1:16, OPTION_REG = $83 %10000011.

    Again, just curious about your observations...
    Regards,
    TABSoft

  7. #7
    Join Date
    May 2011
    Location
    Bangalore, India
    Posts
    33


    Did you find this post helpful? Yes | No

    Default Re: DT_Interrupts - TMR1 Issue With 16F88

    Tabsoft, you are absolutely right on both the counts.

    In the case of the code taken from Darrel's test program, the Option_Reg setting is hex 81 which is binary 10000001. Bits 2-0 are "001" which means that the prescaler is set to 1:4 and not 1:256 as shown in the comment. As you have mentioned, possibly, the comment has not been updated. Henrik was also right in saying that the TMR0 setting did not seem to match the comment in the code.

    The settings you suggested are 1:32 prescaler for TMR0 and if the count >= 61, toggle the LED and reset the counter. This indeed gives ~1Hz blinking rate. In my previous post I mentioned that I tried 1:32 prescaler and changed it to 1:16 to make the LED blink at 1Hz. This is incorrect. In the 16F87/88 datasheet under Option_Reg, a table is shown with 3 column headings - BitValue, TMR0 Rate & WDT Rate. For 1:32 prescaler, by mistake I took the WDT value (101 in Col. 3) instead of TMR0 value (100 in Col. 2). This was the reason for the 0.5Hz rate. In fact in my final version, I have used the value you suggested (100 for 1:32) and they work perfectly.

    Thanks again for all the help.

    Regards,
    Bala

Similar Threads

  1. TMR1 issue
    By Lestat in forum General
    Replies: 6
    Last Post: - 29th August 2012, 15:41
  2. Replies: 6
    Last Post: - 24th November 2011, 16:46
  3. Issue with 16F88 startup
    By Plcguy in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 21st October 2010, 15:11
  4. Question on DT_Interrupts
    By financecatalyst in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 9th May 2010, 17:32
  5. Code Issue - select case or 'if' issue - not sure why
    By jamie_s in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 7th October 2007, 08:52

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