Menu

Using Timer1 TMR1H, TMR1L to initiate timed events

Help
2021-03-10
2021-03-13
  • Andrew Jameson

    Andrew Jameson - 2021-03-10

    PIC in question is a 12f683 ...

    Essentially Timer1 is reset and started by a regular event (interrupt triggered by an edge on GPIO.2) from that point onward I need to generate a couple of pulses at specific times by referencing the timer registers ... (Timer1 does not have time to generate an overflow - if it does it goes to sleep and waits for an input on GPIO.2)

    It all seems to work as expected but closer examination of a simple LED flash indicator exhibits an unexpected behaviour - it sometimes generates a much briefer pulse than the designed 1mS.

    so ...

    c1mSTime = 250 i.e. 250 x 4 uS
    PulseWidth = c1mSTime + Timer1
    GPIO.4 = 1
    loop3:
    Compare(Timer1, PulseWidth)
    movwf CompResult
    if (CompResult <> cGreaterThan) then
    goto loop3
    end if
    GPIO.4 = 0

    Compare is a word comparison function in assembler the result of which returns in the w reg (didn't know if there's a way to get it back as a direct return from the function name reference).

    Now ... is what I am doing bad practice ? Timer1 continues running and I was wondering if the timer's registers are getting updated during my testing.

    So how does my code fail and make an unexpected short pulse ?

    All the examples I can find do these things by preloading the timer and looking out for the overflow flag - which I can't do in this case.

    I plan to look at CCP support as this might be an better alternative but I'd like to understand why my initial solution is misbehaving but would value a "best" practice solution suggestion.

    All a bit new at the moment - started simple but now feel as though I fell in the deep end !

    Thanks

    Andrew

     

    Last edit: Andrew Jameson 2021-03-10
  • Chris Roper

    Chris Roper - 2021-03-10

    Did you consider using the Millis() function to handle the timing for you?
    it would make your code less device dependent and more portable too.

    https://sourceforge.net/p/gcbasic/discussion/629990/thread/ff0785c717/

     
  • Andrew Jameson

    Andrew Jameson - 2021-03-10

    Thanks Chris,

    It's a thought but I need to get down to pulses in the range of 100uS - 200uS.

    Do you think that CCP can do it ? I thought that I could just stick the value I want into the CCP registers and sit and wait for a flag ?

    Rather than move away from what I'd implemented, I'd like to understand why it fails and creates a short pulse.

     
  • Chris Roper

    Chris Roper - 2021-03-10

    The CCP can easily do that.

    Most PIC have instruction cycles measured in Nano Seconds so a Micro Second is a long time to many devices.

    I suspect your short pulse is a glitch generated by the timer rollover.

    I had intended to follow up on the millis() function with a micros() Function exposed as a software interrupt but as the PIC architecture fails to implement an IRQ instruction I put it on the back burner.

    If you look in the GCBASIC\libraries folder you will find millis.h.

    Have a read through that and you will get a better understanding of how I handled the rollover and timer portability.

     
  • Andrew Jameson

    Andrew Jameson - 2021-03-11

    Hi Chris and et al ...

    There are times when programming feels like opening a combination lock - worse, you're never certain if the door is actually there.

    According to the datasheets the CCP compare mode is continuously watching Timer1. So if Timer1 is running, it must at some stage match the state of the CCPR1 register and I would have expected it to the set CCP1IF.

    So - reducing it to the tiniest code fragment :

    It's a 12f683 :

    CCP1CON = 0x0A
    CCPR1L = 255
    CCPR1H = 1
    TMR1ON = 1

    do
    if (PIE1.CCP1IF = 1) then
    PIE1.CCP1IF = 0
    ss = ss + 1
    end if
    loop

    Needless to say ss never gets incremented - what am I missing ?

    Thanks

     
  • David Stephenson

    Just a thought - what are you using as the TIMER1 clock source? Maybe the clock source is not working.

     
  • Andrew Jameson

    Andrew Jameson - 2021-03-11

    Thanks David but Timer1 is running and using Fosc4 :

    TICON = 0b00000001

     
  • Andrew Jameson

    Andrew Jameson - 2021-03-12

    Found it ! And it is covered by a Microchip application note. Reading non-latched live timer registers ... by the time I've read TMR1H, TMR1L has incremented and overflowed into TMR1H ... I spotted that Timer1 was varying around a count of 240 - 260 and that was the key.

    The solution would be to do a multiple read - which is what Microchip suggest or to stop the timer to take a copy of the registers.

    Ideally I'd like to find out how to trigger a CCP timer match interrupt. The interrupt works if I set the CCP mode select bits as 1011 but it resets Timer1 count to zero ... I can't get CCP mode select bit 1010 to trigger an interrupt - datasheet says "yes" - chip says "no". (Don't want to involve the CCP1 pin as I'm using its INT support; an input.)

    In the interim, might have a look at using 1011 trigger and then restore Timer1's registers back to what they had been.

    Any comment ?

    Thanks Andrew

     
  • Andrew Jameson

    Andrew Jameson - 2021-03-13

    Got it working without having to reset Timer1. The CCP1IF bit flag seems to be only valid from within the interrupt handler :

    12F683

    CCP1CON = 0b00001010

    On Interrupt CCP1 Call CCP1_Interrupt_Handler
    sub CCP1_Interrupt_Handler
    if (CCP1IF = 1) then
    CCP1IF = 0
    CCPMatchFlag = 1
    end if
    end sub ;(CCP1_Interrupt_Handler)

     
  • Jerry Messina

    Jerry Messina - 2021-03-13

    do
    if (PIE1.CCP1IF = 1) then
    PIE1.CCP1IF = 0

    You're checking the wrong register.
    The CCP1IF intr flag bit is in PIR1, not PIE1. PIE1 is the intr enable register (CCP1IE).

     
  • Andrew Jameson

    Andrew Jameson - 2021-03-13

    Hi Jerry,
    Amazing what effect a typo can make ! It's gone from utter frustration and code that didn't work to one where everything works as expected !

    So grateful for your keen observation !

    Regards,

    Andrew

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.