Menu â–¾ â–´

capture mode on 16f18856

Help
2019-11-11
2019-11-11
  • Jim giordano

    Jim giordano - 2019-11-11

    I'm trying to get capture mode working on a 16f18856.

    This is the code I'm using:

    dir rc2 in
    On Interrupt CCP1 call GotReset  ' watch for reset signal
    CCP1CON=b'00000101' 'every rising edge
    sub GotReset
      PIR6.CCP1IF=0  ' reset interrupt 16f18856
      'do other stuff here
    end sub
    

    But it's not working. What else do I have to set?

    For the 16f1938, this works-

    dir rc2 in
    On Interrupt CCP1 call GotReset  ' watch for reset signal
    CCP1CON=b'00000101' 'every rising edge
    sub GotReset
     PIR1.C1IF=0 ' reset interrupt (16f1938)
      'do other stuff here
    end sub
    

    So there must be something different about the 18856.

     

    Last edit: Jim giordano 2019-11-11
    • Anobium

      Anobium - 2019-11-11
      1. Dont set CCP1CON like that. You are overwriting the existing settings. Figure out the bit to set and set that bit only. My guess this is one issue.
      2. The two chips are totally different architectures. What does the datahsheet say?
       
  • Anobium

    Anobium - 2019-11-11

    More info.... ignoring what I wrote... use and

    CCP1CON = CCP1CON AND 0x10000100 'enable and falling edge
    CCP1CON = CCP1CON AND 0x10000101 'enable and rising edge

    And, check CCP1IE is set to 1. Should be by the compiler. Do not add to your code. Check compile is setting.

    And, did you have to set timer 1, 3 or 5 on the old part?

    And, is CCP/RC2 an input?

     
  • Jim giordano

    Jim giordano - 2019-11-11

    asm says:
    banksel PIE6
    bsf PIE6,CCP1IE
    so thats ok.

    using "CCP1CON = CCP1CON AND 0x10000101" had no effect.

    The code is identical between the 1938 and the 18856 except setting pir6 rather than pir1 for the interrupt reset.

    As far as timer1 goes, I'm using it for both chips. In capture mode, it only reads and stores timer1, but I don't use the results, I just wanted the interrupt.

    For what it's worth, I just tried it on an 18F27K42 and it didn't work on that chip either.

     
  • Anobium

    Anobium - 2019-11-11

    Oh dear.... I should have mentioned.

    PPS.... got this?

    CCP1PPS = 0x12   'RC2->CCP1:CCP1
    
     
  • Jim giordano

    Jim giordano - 2019-11-11

    According to the datasheet, CCP1 is on RC2 by default, do I really need to do a pps for it?

     
    • Anobium

      Anobium - 2019-11-11

      Oh yes.

       
  • Jim giordano

    Jim giordano - 2019-11-11

    ok,
    added the "CCP1PPS = 0x12 'RC2->CCP1:CCP1" line, but that didn't work.

    so deleted that line and added the full pps output-

        #startup InitPPS, 85
        #define PPSToolPart 16F18856
        Sub InitPPS
                'Module: CCP1
                CCP1PPS = 0x0012    'RC2 > CCP1
                RC2PPS = 0x0009    'CCP1 > RC2 (bi-directional)
        End Sub
    

    Still doesn't work.

     
  • Anobium

    Anobium - 2019-11-11

    Post the code.... the whole code. I am guessing to much

     
  • Jim giordano

    Jim giordano - 2019-11-11

    Give me a few minutes.

     
  • Anobium

    Anobium - 2019-11-11

    Guessing here.. cant see you code.

    Select timer1.

    C1TSEL = 0x01

     
  • Jim giordano

    Jim giordano - 2019-11-11

    Here's a test program I just ran. Works for 1938, not for 18856.

    ' Test of ccp1 on 16F18856
    ' turn on led if rc2 (pin13)  is captured by pressing switch hooked to +
    #option Explicit
    '#chip 16F1938, 32
    #chip 16F18856, 32
    '#chip 18F27K42, 32
    
        'Generated by PIC PPS Tool for Great Cow Basic
        'PPS Tool version: 0.0.5.28
        'PinManager data: v1.78.0
        'Generated for 16F18856
        #startup InitPPS, 85
        #define PPSToolPart 16F18856
        Sub InitPPS
                'Module: CCP1
                CCP1PPS = 0x0012    'RC2 > CCP1
                RC2PPS = 0x0009    'CCP1 > RC2 (bi-directional)
        End Sub
    
    dir rc3 out     ' indicator led for debug
    dir rc2 in      ' reset timer (using ioc)
    ' also 32k crystal on rc0-rc1 SOSC
    
    ' This is the way I use the timer in the full app
    InitTimer1 SOSC,0 ' 32768 crystal time keeper
    On Interrupt Timer1Overflow Call CheckClock
    StartTimer 1
    
    sub CheckClock
      TMR1L = 0
      TMR1H = 0x80    ' set up for one second delay
      ' real program sets flag here
    end sub
    
    TMR1L=0
    do while TMR1L=0: loop ' wait for timer to actually start, often takes 5 seconds
    
    On Interrupt CCP1 call GotReset  ' watch for reset signal
    'CCP1CON=b'00000101' 'every rising edge
    CCP1CON = CCP1CON AND 0x10000101 'enable and rising edge
    
    sub GotReset
      'PIR1.C1IF=0 ' reset interrupt (16f1938)
      PIR6.CCP1IF=0  ' 16f18856
      rc3=1  ' turn on led
    end sub
    
    do
    loop
    
    'Optimise code
        #define USE_Timer0 false
        #define USE_Timer2 false
        #define USE_Timer3 false
        #define USE_Timer4 false
        #define USE_Timer5 false
        #define USE_Timer6 false
    

    And as it said earlier, I'm only doing a capture, not a compare, so CCP only copies the value of timer1, and I don't use what it copies.

     
  • Jim giordano

    Jim giordano - 2019-11-11

    Just to add confusion, I did it again without using timer1 for my own purposes, and added the "C1TSEL = 0x01" line. The compiler didn't know what C1TSEL was, so I changed it to "CCPTMRS1 = CCPTMRS1 or 0x01"

    New program:

    ' Test of ccp1 on 16F18856
    ' turn on led if rc2 (pin13)  is captured by pressing switch hooked to +
    #option Explicit
    '#chip 16F1938, 32
    #chip 16F18856, 32
    '#chip 18F27K42, 32
    
        'Generated by PIC PPS Tool for Great Cow Basic
        'Generated for 16F18856
        #startup InitPPS, 85
        #define PPSToolPart 16F18856
        Sub InitPPS
                'Module: CCP1
                CCP1PPS = 0x0012    'RC2 > CCP1
                RC2PPS = 0x0009    'CCP1 > RC2 (bi-directional)
        End Sub
    
    dir rc3 out     ' indicator led for debug
    dir rc2 in      ' reset timer (using ioc)
    
    CCPTMRS1 = CCPTMRS1 or 0x01
    On Interrupt CCP1 call GotReset  ' watch for reset signal
    'CCP1CON=b'00000101' 'every rising edge
    CCP1CON = CCP1CON AND 0x10000101 'enable and rising edge
    
    sub GotReset
      'PIR1.C1IF=0 ' reset interrupt (16f1938)
      PIR6.CCP1IF=0  ' 16f18856
      rc3=1  ' turn on led
    end sub
    
    do
    loop
    

    Same results.

     
  • Anobium

    Anobium - 2019-11-11

    Version of Great Cow BASIC please.

     
  • Jim giordano

    Jim giordano - 2019-11-11

    ;Program compiled by Great Cow BASIC (0.98.06 2019-06-12 (Windows 32 bit))

     
  • Anobium

    Anobium - 2019-11-11

    Clocking Timer1 from the system clock (FOSC) should not be used in Capture mode. In order for Capture mode to recognize the trigger event on the CCPx pin, Timer1 must be clocked from the
    instruction clock (FOSC/4) or from an external clock source. But, I cannot get MPLAB-IDE to accept SOSC as a valid clock source for TMR1 which means an external source is forbidden. I can only select FOSC/4 in MPLAB-IDE as the clock source.

     
  • Anobium

    Anobium - 2019-11-11

    I think this is the issue.

    1938 is ECCP and the 18856 is CCP

    See http://ww1.microchip.com/downloads/en/devicedoc/30673a.pdf

    May be not.. but, I would follow the PDF

     
  • Jim giordano

    Jim giordano - 2019-11-11

    Ok, got it. Everything I was doing was okay and working, so GCB accept SOSC correctly, and MPLAB is wrong.

    Anyway, the fix you gave me earlier was the key.

    Had to set

    CCP1CON=b'10000101' 'every rising edge

    and it works.

    The line you game me,
    "CCP1CON = CCP1CON AND 0x10000101 'enable and rising edge"

    is wrong. That would just keep bits that were already on.

    I couldn't contruct a line with ands and ors that would work, but the simple line

    CCP1CON=b'10000101'

    works!

     
    • Chris Roper

      Chris Roper - 2019-11-11

      I think the Line Evan intended was:
      "CCP1CON = CCP1CON OR b’10000101’ 'enable and rising edge"

      That would Set the required Bits and Leave the rest unchanged.

       
      • Anobium

        Anobium - 2019-11-11

        Oh yes... dim

         
  • Jim giordano

    Jim giordano - 2019-11-11

    Final working test program:

    ' Test of ccp1 on 16F18856
    ' turns on led if rc2 (pin13) capture is triggered by pressing switch hooked to +
    #option Explicit
    #chip 16F18856, 32
    
    dir rc3 out     ' indicator led for debug
    dir rc2 in      ' reset timer (using ioc)
    
    On Interrupt CCP1 call GotReset  ' watch for reset signal
    CCP1CON=b'10000101' 'every rising edge
    
    sub GotReset
      PIR6.CCP1IF=0  ' reset interrupt
      rc3=1  ' turn on led
    end sub
    
    do
    loop
    

    Sorry about this messy thread, feel free to delete the whole mess.

    All caused by one messed up bit.

     

    Last edit: Jim giordano 2019-11-11
  • Jim giordano

    Jim giordano - 2019-11-11

    Just an OR isn't correct either. If mode was already set to 0x0111, capture every 16th for example, an or wouldn't change the mode.

    It would have to be something like
    CCP1CON=(CCP1CON and b'11110000') or b'10000101'

    Also notice that PPS is not required in this case since CPP1 is indeed already associated with RC2.

     

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.