Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

CCP2 Capture in PIC18F23F22

Status
Not open for further replies.
Hi Max,
I have used capture mode (Not on a PIC18 but on a PIC16F628 ) to measure RPM. If the time of a revolution is less than about 0.5 seconds (120 RPM) then it waits for the next revolution after 0.5 second has elapsed and divides the elapsed time by the number of revolutions thus averaging over between 0.5 and 1 second. The source code is here.
Les.
The original design was based around this article pub. in Electronic Design but Capture and Interrupt added, also LCD display.
Max.
 

Attachments

  • 8513_tach.pdf
    1 MB · Views: 338
Recently, I was using the CCP module in Compare mode. Specifically , I used mode 9 of compare (initialize CCP high, clear on match). That worked for one capture, then nothing, even though the pin went back high. After much reading, I found a comment to the effect that between successive compares one needed to change modes. That was a personal communication from a Microchip tech to the user who reported it. That requirement is not documented in the datasheet. Instead of changing modes, I just reset compare, which also worked.

Since no one has found the critical error in your code, and it has been around awhile, my advice would be to use a standard troubleshooting procedure and go to a know working system. If it were me, I would clock TMR1 to the system instruction clock and switch modes from rising to falling edges alternately. Once I had that working, I would change my clock to what you intend with the external oscillator. If that works, then I would try it using only the rising edge.

John
 
That requirement is not documented in the datasheet. Instead of changing modes, I just reset compare, which also worked.
John
Do you mean the apply reset to the CCP2CON in my case?
I don't seem to be able to find a 'working capture system' for the 18F23k22 series in Assembly and I have tried several sources!
Max.
 
Do you mean the apply reset to the CCP2CON in my case?
I don't seem to be able to find a 'working capture system' for the 18F23k22 series in Assembly and I have tried several sources!
Max.
The example on the Microchip site is in assembler for the pic17c42... Can you adapt it?
 
That would work, but just changing the mode from rising edge to falling edge would probably work as well. In my case, it was easier to reset by clearing CCP2CON. Here's the code I used with a 12F1840 to capture a PWM signal, which might be easily translated to 18F:

Code:
    clrf        TMR1H          ;                                                 |B0
    clrf        TMR1L          ;                                                 |B0
     Banksel   CCP1CON        ;                                                 |B5
     movlw     b'00000101'    ;                                                 |B5
     movwf     CCP1CON        ;CCP1 rising edge capture                         |B5
_Data                         ;TMR1 runs continuously                        
     Banksel   PIR1           ;                                                 |B0
     bcf       PIR1,CCP1IF    ;flag must be cleared after mode change           |B0
     btfss     PIR1,CCP1IF    ;test CCP1 interrupt flag (interrupt not enabled) |B0
     goto      $-1            ;                                                 |B0  
     Banksel   CCP1CON        ;                                                 |B5  
     movf      CCPR1H,w       ;start time high byte                             |B5
     movwf     CCP_T1H        ;save value in shadow register                    |B?
     movf      CCPR1L,w       ;start time low byte                              |B5
     movwf     CCP_T1L        ;save value in shadow register                    |B5
     bcf       CCP1CON,0      ;change interrupt flag to falling edge            |B5
     Banksel   PIR1           ;                                                 |B0
     bcf       PIR1,CCP1IF    ;clear flag                                       |B0
     btfss     PIR1,CCP1IF    ;test CCP1 falling edge interrupt flag            |B0
     goto      $-1            ;                                                 |B0
     Banksel   CCP1CON        ;                                                 |B5
     movf      CCPR1H,w       ;stop time high byte                              |B5
     movwf     CCP_T2H        ;save value in shadow register                    |B5
     movf      CCPR1L,w       ;stop time low byte                               |B5  
     movwf     CCP_T2L        ;save value in shadow register                    |B5
     bsf       CCP1CON,0      ;change interrupt flag to rising edge             |B5
     Banksel   PIR1           ;                                                 |B0
     bcf       PIR1,CCP1IF    ;clear flag                                       |B0

The signal was quite a bit faster than your pulse per revolution at 6000 rpm, but I am assuming you are actually simulating that signal anyway.

John
 
The signal was quite a bit faster than your pulse per revolution at 6000 rpm, but I am assuming you are actually simulating that signal anyway.

John
No I have my Pickit 3 hooked up to my actual final board, so I can input motor tach signals direct.
I have an ICP socket so I can program and debug the PIC on board.
Max.
 
With your pre-scale and a 20 MHz clock, TMR1 won't overflow with a 10 ms (i.e., 6000 rpm) signal.

John
 
Well I managed to get back to this, and after perusing the help codes posted, I tried a simple start TMR1 wait for a first pulse, CCP2 and Interupt and capture TMR1, then halt.
TMR2 rolls over after 2 seconds so it gives time for a test input before this occurs.
I see the interrupt occur when input occurs, and the timer1 value at that point, but still no transfer.
In this case there should be virtually no difference between TMR1 value and the capture value so I may just end up using TMR1H/L, it is just frustrating that after appearing to follow all the right settings that the capture is not seen!!.
Another anomaly is when using ICD mode, and monitoring CCP2RH/L IMO they should highlight when a capture occurs, but only TMR1H/L does, this indicates to me that although a capture interrupt occurs the register transfers do not??:(
Max.
 
Yes, the registers should highlight. Here is an example from a working simulation:
upload_2015-9-12_15-55-13.png


John
 
Yes, that is kind of thing I expected, I see there is a 2 bit difference but this was with a high TMR1 clock maybe?
Max.
 
The breakpoint was at the next instruction. In the "run" mode, I don't think live updates work, and even if they did, my reflexes are too slow at 8 MHz. ;) Changes since last breakpoint are highlighted.

John
 
The example above is for the 12F683. I was just playing with the same code translated for the 12F1840, and it didn't work in simulation with MPLab SIM. Then my old memory was jarred back when I saw a little program I had written for the 16F1519 to simulate that function for the 12F1840. MPLab SIM will not properly simulate capture (and other peripherals) with some chips. There is actually a lengthy thread on that very subject here: https://www.microchip.com/forums/m854549.aspx

Two viable options:
1) Take that section of your program and test it with a chip that will simulate properly like I did with the 16F1519; or
2) Try to get MPLabX to work with Assembly. There is no guarantee it will simulate properly, but MC claims it will.

BTW, TMR1 is 2 Tcy greater than CCPR1 because btfss takes 2 cycles when there is a change in PC, as there was in jumping to the breakpoint.
Code:
btfss      PIR1,CCP1IF
goto       $-1
next step (breakpoint)
TMR1 runs continuously; CCPR1 was captured before the breakpoint. I didn't mean to be flippant with that answer before.

John
 
Hi Max,

If you are still interested in using capture, I did not have your chip to play with, but I did have some enhanced mid-range chips to test. As mentioned above, the 12F1840 won't simulate capture with MPLab SIM, but the 16F1519 will. So I used that chip. The capture worked well as describe above, but I didn't have the patience to try to clock TMR1 at a lower frequency and did not have a decent signal generator to trust the hardware simulation with the ICD3 simulator. So, I went ahead and set up a breadboard with a 32.768 kHz watch crystal and ran the chip with its internal oscillator at 16 MHz. Input frequency was determined with my uncalibrated o'scope. Here are my results:

upload_2015-9-15_15-39-26.png


The code is a bit messy, as I had to add a print function to print the results on an LCD, which messed up allowing TMR1 to run continuously. If you are still interested, let me know. I don't think it is significantly different than what you did, except I waited for the external timer to stabilize.

John
 
John, Thanks for the efforts, I have not got back to it yet apart from checking the one time capture, which also failed.
Were these results obtained from CCPR capture registers?
I have a LCD display option, I intend making a single capture and displaying it after turning off the CCP2 interrupt until I decide to enable it again, as I do not want fast continuous overwriting of the value when it fluctuates , obscuring the reading.
So for now it would be one time capture/display value at a time.
The capture code examples out there are for previous chips, I have pored over all the relevant registers for this Pic, but I cannot see why the capture does not occur, when the interrupt does?
Max.
 
Yes, the results are from CCP capture registers (my function: PrntReg), but printing to the LCD is at 9600 baud and then there is a 300 ms delay so I can read the result. Actailly, the printed results were quite stable, just +/-1. All told, you can't do that and let TMR1 run. In another application (with the 12F1840) the capture registers are transmitted at 9600 baud to another device. Frequency of the signal being captured in that ap. is only 100 Hz, so there is plenty of time to transmit 4 registers without stopping TMR1.

After you enable TMR1 for the secondary clock, are you waiting for it it stabilize?

John
 
Well like I said, it does not seem like a TMR1 issue per-se, but one of capture, the TMR1 values seen are what Should appear in the CCPRH/L registers and are consistent and appear accurate.
At this point I would like to see SOMEthing in the CCPR2 registers, even a wrong value, anything but zero!!
From the manual, the system clock transfers/clocks whatever is in the TMR1 registers to the CCPR2 regs at capture time, at least that is the way I have always interpreted it?
Max.
 
Well like I said, it does not seem like a TMR1 issue per-se, but one of capture, the TMR1 values seen are what Should appear in the CCPRH/L registers and are consistent and appear accurate.
At this point I would like to see SOMEthing in the CCPR2 registers, even a wrong value, anything but zero!!
From the manual, the system clock transfers/clocks whatever is in the TMR1 registers to the CCPR2 regs at capture time, at least that is the way I have always interpreted it?
Max.

That is my whole point! Are you sure capture is simulated? Write a routine to print the capture window in real life, like I did. I am quite confident that your chip properly performs a capture. I also added an LED blink to let me know the the chip decided the external oscillator was stable. It can take quite a while.

When you think about compare, capture, and PWM, they have a lot in common. If it can't compare, then it can't do PWM. And compare is simply the reverse of capture.

John
 
Status
Not open for further replies.

Latest threads

Back
Top