Timer Interrupt to exit a closed loop


Closed Thread
Results 1 to 8 of 8
  1. #1
    Join Date
    Oct 2004
    Location
    North Norfolk UK
    Posts
    146

    Default Timer Interrupt to exit a closed loop

    Hi,
    Damn I am struggling lately, I could really use some help right now.
    I have a program that is capturing different data from both CCP modules, the routine is started by an interrupt on a comparator and I am attempting to limit the duration that the ccp modules are capturing by setting a timer for approx 200ms.

    What Is hapening is that the interrupt timer is flagged but it is looping through the routine again, but only once.

    I have identified where the problem lies and I have stripped out the irrelevant code.

    As can be seen I am using Darrel's Instant Interrupts. I have tried rearanging the placement of the timer0 commands, timer on/off enable/disable I have disabled the flag and set those manually in the INTCON but all to no avail.

    The following code produces a trace on portd that clearly shows the routine passing through the timer0 interrupt sequence twice. As this is a module in larger compilation I would really wish not to ignore this error, besides I dislike things not being correct it is like attempting to sweep things under the carpet,, they will always come back to haunt you!

    Thanks

    ps Now I have to try and find out how to insert the code inside this message.
    Attached Files Attached Files

  2. #2
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    i didn't read the whole thing carefully, but usually when you load a timer, you want to stop it before to load, .

    Will be great to know the PIC you're usiing so far.

    To post your code in a box, just use code tags

    [code]
    paste your code here
    [/code]
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

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


    Did you find this post helpful? Yes | No

    Default

    Hi Duncan,

    The comparator will give an interrupt on any change of the comparator (rising and falling, 2 per cycle).

    If you only want one edge, you'll need to test CMCON bit 6 or 7, (depending on which comparator you are using), to see which edge it was.

    If using both comparators, you'll get an interrupt when either comparator changes.
    <br>
    DT

  4. #4
    Join Date
    Oct 2004
    Location
    North Norfolk UK
    Posts
    146


    Did you find this post helpful? Yes | No

    Default

    Hi Steve

    Sorry I forgot to mention It is in an 18F4520, actually it's on a fairly well modified LABX1 board, Ill migrate to a suitable MCu after I have finished.
    and I had a scout about the forum for info about the VB code to do all sorts of wonderfull things to the post

    Code:
    define OSC 16
    
    INCLUDE "DT_INTS-18.bas"       ; Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"    ; Include if using PBP interrupts
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   CMP_INT,  _StartTag,       PBP,  yes            
            INT_Handler   TMR0_INT,  _AllDone,        PBP,  yes
        endm
        INT_CREATE                
    ENDASM
    
    TRISA =  %00001111   
    TRISB =  %11011111  
    TRISC =  %00111111
    TRISD =  %00000000
    PORTD = 0 
    
    Z var byte
    
    T0CON   = %10000011    'set up timer 0 and turn it ON  @16mhz 0011 = 262ms 
    CMCON   = %00100011    ' set up comparator inputs
    
    
    @ INT_ENABLE  TMR0_INT          ;all done
    T0CON.7 = 0                     ' turn off timer until needed
    
    
    start:
    portd.5 = 0
    '=============================================================
    '=============================================================
    Get_Raw_Data:'          GET RAW DATA
    '-------------------------------------------------- Z = 0-----------------
    
    @ INT_ENABLE  CMP_INT            ;wait here until an  interrupt event 
    Z = 0                                     'on the comparators
    Waiting:
                if z = 0 then waiting
    @ INT_DISABLE CMP_INT 
    '----------------------------------------- Z = 1--------------------
    portd.5 = 1                           'all done marker
    TMR0H = %00111100                     ' preload timer to 15400
    TMR0L = %00100000
    T0CON.7 = 1                    ' turn back on timer 0 , used by all done
    
    getData:                          ']loop here until timer1 overflows 
    if z = 1 then getdata             '] 
    '--------------------------------------------Z = 4-----------------
    getout:
    PORTD.5 = 0                      'all done marker
    T0CON.7 = 0                       'turn timer0 off until used again  
    
    finished:
    goto start
    
    ;;;;;;;;;;;;;;;;;;;;;      interrupt handlers        ;;;;;;;;;;;;;;;;;;;;;;
    
    StartTag:
    z = 1              ' moves towards middle of routine
    @ INT_RETURN
    
    AllDone:
    z = 4             ' moves towards end of routine
    @ INT_RETURN
    end
    simple

    Loading the timer: I have read somewhere (datasheet maybe?) that it is good practice to have the timer running before you initially start an interrupt which I do in the setup. I then enable interrupt and turn the timer off so that I can preload and then turn it back on when I am ready to start the stopwatch.
    I have tried it another way which is to setup prescale and leave timer off /then preload and when I am ready to use it I start timer with the enable interrupt on the next line, regrettably the same thing happens.
    I cannot help feeling I am missing something really fundamental. This problem has been around for me for a couple of weeks now, I am ready to stich the module back into the main compilation... feeling pretty dispondent and mentally tired.... i really appeciate your input.

  5. #5
    Join Date
    Oct 2004
    Location
    North Norfolk UK
    Posts
    146


    Did you find this post helpful? Yes | No

    Default

    Hi Darrel,

    Thanks just got your reply, although I using the comparators to feed the CCp modules. As you say the cmp interrupt is on *any change on either comparator*

    so i am using the cmp as a sort of interrupt on change on both analog pins. It is then inportant to disable the cmp interrupt as soon as possible. I did have one comaparator output (the one i felt most probable to set) linked to portb internal interrupt but it oscillated like crazy, I get little or no bounce using this setup. I had been disabling the cmp_int "inside" it own handler routine but felt that this was bad practice (any thought?)which I why I try to keep the sub routines as simple as posible ie Z=1 or Z=2.

    I have tried introducing delays without using pause (small count loops) to allow the interrupt disable to settle.

    but I guesss that whilst I have been concentrating on timer0 as the culprit I should be back looking at CMP_INT to see if there is any way this could be responsible. But this loopback is happening 206ms after I have disabled CMP.

    I also check that Z variable that I use as a progress gate is not corrupted, that is to say that even though Z = 1 the program is passing through a conditional IF's that should prevent it, confused........ I am totally.

  6. #6
    Join Date
    Oct 2004
    Location
    North Norfolk UK
    Posts
    146


    Did you find this post helpful? Yes | No

    Default

    well it looks as if I have found a workaround, it seems as if the first line after the
    @ INT_ENABLE CMP_INT is being ignored furthermore placing Z = 0 at any position from start to the @ INT_ENABLE CMP_INT will also cause a problem so I have to place a dummy line after the enable and everything works as it should do....... or so it appears on the surface to.
    Code:
    @ INT_ENABLE  CMP_INT 
    Z = 0                             'dummy line ignored
    Z = 0
    Waiting:
    if Z = 0 then Waiting
    I have only one variable in the example. I do not think I can face it but I have a feeling that I may have to check the stability of all my variables before and after an interrupt implementation .

    I have just pulled the whole house down to find a needle ......... but for the want of that needle.... I am cold wet and have nothing to cook on!!!

    think I will go down the road and post a christmas card to myself

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


    Did you find this post helpful? Yes | No

    Default

    I had been disabling the cmp_int "inside" it own handler routine but felt that this was bad practice (any thought?)
    That's the correct way.
    Comparators can give many interrupts right at the point where it switches (hundreds even, if the analog signal is slow). If it's allowed to return from the interrupt without disabling, it'll end up right back in the handler again until it's past the switching point of the comparator. External hysterisis can be added to the comparator to eliminate that, but it's not needed in this case.

    Also, much like the PORTB change interrupt, you should read the CMCON register inside the handler to end the mismatch condition. Typically, the handler would do that anyways to determine which comparator fired.

    And,
    before enabling the comparator the first time. Read CMCON, then Reset the interrupt flag.
    Then be sure to clear it again before re-enabling later. The flag may have been set during the time it was Disabled.

    that I may have to check the stability of all my variables before and after an interrupt implementation
    No need,
    Nothing happens to your other variables during an interrupt, unless you specifically change them in the handler.
    <br>
    DT

  8. #8
    Join Date
    Oct 2004
    Location
    North Norfolk UK
    Posts
    146


    Did you find this post helpful? Yes | No

    Default

    Hi Darrel

    Thankyou for your help..., again. I was experiencing occasional hysterisis whilst using the internal comparators but by slightly increasing the speed of the analog signal along with placing two bypass caps on each VDD pin of the MCU the internal bounce was brought easily under control.


    By executing strict good housekeeping with respect to the flags and reading the cmcon register as you advised (it is in the Datasheet) together with re-setting all the registers prior to re-enabling I now have all six interrupts functioning perfectly within the same sub-routine and all being disabled upon exit. I am delighted and relieved, i almost feel a poem coming on but I note you recently penned something apt.

    I can fly effortlesly ..... so until I have to learn how to land I am enjoying the moment.

Similar Threads

  1. Elapsed Timer Demo
    By Darrel Taylor in forum Code Examples
    Replies: 111
    Last Post: - 29th October 2012, 17:39
  2. Controlsystem for compact sporting (clay shooting)
    By Fredrick in forum mel PIC BASIC Pro
    Replies: 11
    Last Post: - 30th July 2009, 16:48
  3. Can't ID interrupt source with this IntHandler??
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 3rd June 2009, 02:35
  4. Using input from Switch to control a loop
    By MrRoboto in forum mel PIC BASIC
    Replies: 9
    Last Post: - 2nd February 2009, 05:02
  5. Serial Relays
    By tazntex in forum General
    Replies: 3
    Last Post: - 17th May 2007, 17:42

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