bjox1 said:Sorry Nigel, I am finding very hard to analyse ur solution. Please enlighten me.
I may have explained it wrongly. That’s the whole task:
1) User will choose any frequency from 500 Hz to 10kHz.
2) Then same frequency signal will be tap down to TWO signals. One will be the reference and the other will go through this unknown delay circuit.
3) My aim will be to find the value of the phase difference hence determining the unknown circuit [phase value].
Nigel Goodwin said:Check the spec on the CCP module, you certainly can't get 277nS resolution with a 4MHz clock.
Nigel Goodwin said:If you're using different frquencies you need to measure both the HIGH period and the LOW period, the phase difference is the ratio between them.
Sounds like a job for a PLL (Phase Locked Loop) using the reference signal the PLL will output a signal proportional to the phase error. PLL are used in things like instrument tuners, indicating whether a played note is higher or lower than the reference.
bjox1 said:Nigel,
Mate if I use a 20MHz XT?? Is it possible to do it in this way?? if so then how can I implement in a code?
mike50 said:The 16F876 has two CCP modules. Why not use one module to Capture the leading edge of one of the signals and the other module to Capture the leading edge of the other. Then you don't need any external XOR function; you can compute the frequency and the phase directly with the 200 ns resolution.
Mike
Mike, Sorry for being so slow but could you check my following steps:you can compute the frequency and the phase directly with the 200 ns resolution.
bjox1 said:Mike,
Mate it sounds perfect but I haven't got that much experience in writing this sort of code. I have done a few LED blinking codes and can attempt this CCP if I get a little bit of help.
Mike, Sorry for being so slow but could you check my following steps:
1) Configure CCP [capture] for the reference signal.
2)Configure CCP for the delay signal.
But what do I have to write in my code to get the phase value which will be independent of the signal frequency??
I would appreciate any help on this.
Thanks in advance.
mike50 said:
- Run the PIC at 20 Mhz.
- You need to configure Timer1 to count instruction cycles (200 ns).
- You need to setup CCP1 to capture the leading edge of signal 1.
- You need to setup CCP2 to capture the leading edge of signal 2.
- Each time a capture occurs save the captured time from CCP1 and/or CCP2 (whichever caused the interrupt)
- Each time you get an interrupt for a capture of CCP1, subtract the previous value that you captured from CCP1. This will give you the time between leading edges of the signal (in units of 200 ns)
- 5,000,000 divided by this time will give the frequency in Hz.
- You could do the same with the times from CCP2 to verify that the frequencies are the same.
- Subtracting the most recent CCP2 time from the most recent CCP1 time will give you the time between the edges of the two signals. Take this time interval and multiply it by 360 and then divide by the period (the time you measured in step 5 above) and you will have the phase angle in degrees.
This technique will work for signals down to about 77 Hz. Below that, Timer1 will overflow between pulses and you will get incorrect values. You don't ever have to stop Timer1, just let it run free. It is okay for Timer1 to overflow as long as it doesn't overflow more than once between captures on either timer....and that won't happen for frequencies above 77 Hz.
Mike
You wouldn't have to use an interrupt. Your main application could just stay in a loop watching the CCP1IF bit in PIR1 and the CCP2IF bit in PIR2. When CCP1IF changes to 1, then read out the CCPR1H and CCPR1L to get the captured value. Then turn off the CCP1IF bit in PIR1. Likewise, when CCP2IF changes to 1, then read out the CCPR1H and CCPR1L to get that captured value. Don't forget to turn off the CCP2IF bit in PIR2.bjox1 said:Mike,
I have no words to thank you for being so down-to-earth and for being so helpful.
Just before I try this, is there any example code anywhere similar to this??
I mean it would really help me in learning [I really don’t know how to use an interrupt to capture the time].
Well, you can't use two timers. Both CCP1 and CCP2 capture modes use Timer1. But that works fine for you.bjox1 said:As u have suggested that there will be two capture times for signal1 i.e. CCP1a for the first rising edge and CCP1b for the second rising edge. And then CCP2 will be used to get the time for the first rising edge on signal2.
My question is, do I need to use two different Timers for this??
Timer1 just runs all the time. Whatever value it has when you capture the rising edge of signal1 is the start time. Later when you capture signal1's rising edge again you will get some other value. The difference between these is the time for one cycle. It doesn't matter where Timer1 starts nor whether it overflows (as long as the total time is less than 65,536 * 200ns - which is why 77 Hz is the lowest frequency you could capture).bjox1 said:i.e. -Timer1 [T1] will be clear at the first rising edge of signal1 and it will count till the next rising edge arrives. This gives the value T1 [or period of the signal1].
You don't "move" to CCP2, both CCP modules are capturing all the time. At any time, the most recent CCP1 and CCP2 captured values will represent the time between the leading edges of the two signals.bjox1 said:- Now as soon as we move to Pin2 for CCP2, the second counter [T2] will start counting till the next rising edge on signal2.
Imagine that you keep the last two times captured from CCP1 in SIG1x and SIG1y (with SIG1y being the most recent) and that you keep the last time captured from CCP2 in SIG2. Then right after capturing CCP2 in SIG2 you can computebjox1 said:Lastly - T2 / T1 will be my phase value in time.
Please please suggest if I am on the right track??
Cheers Mike.
You might take a look at which does a 16-bit by 16-bit multiply with a 32-bit result.bjox1 said:Hey Mike,
I have no words to thank you again. You are just like an angel sent.
Mate, I am using ASM language. I spent last night figuring out how to do a 16 bit subtraction in assembly. I found a few help links on the internet to do that.I have done that successfully.
I am all puzzled about the division now.
You do not want to change CCP1CON to look for the falling edge. Once you set it up to look for leading edges, leave it alone. The time you want is the time between two successive leading edges.bjox1 said:Mike I will be grateful if you could double check the following steps:
- Setup CCP1CON for the rising edge. [Set input pins as well]
- Setup T1CON for free running.
- Check for CCP1IF flag to set.
- Save the capture time T1H and T1L in Memory reg.[This is CCP1a]
- NOW setup CCP1CON for the falling edge.
- Check again for CCP1IF flag to set.
- Save the capture values again. [This is CCP1b]
- Do 16 bit subtraction and save the result in 16 bit memory reg.
- Configure the pins - disable analog inputs and set TRIS regs
- Setup T1CON for free running.
- Setup CCP1CON for the rising edge.
- Setup CCP2CON for the rising edge.
- Set CCP1IH to 0
- Set CCP2IH to 0
- outer loop
- Inner loop 1
- If CCP1IH = 0 then goto Inner loop 1
- Copy CCPR1H to CCP1aH
- Copy CCPR1L to CCP1aL
- Set CCP1IH = 0
- Inner loop 2
- If CCP1IH = 0 then goto Inner loop 2
- Set CCP2IH = 0 ; make sure to capture CCP2 after second CCP1 capture
- Copy CCPR1H to CCP1bH
- Copy CCPR1L to CCP1bL
- Set CCP1IH = 0
- Inner loop 3
- If CCP2IH = 0 then goto Inner loop 3
- Copy CCPR2H to CCP2aH
- Copy CCPR2L to CCP2aL
- Set CCP2IH = 0
- time = CCP1b - CCP1a (use 16-bit subtract)
- frequency = 5000000 / time (use 32 by 16 divide - since 5000000 won't fit in 16 bits)
- phase = 360 * ( CCP2a - CCP1b ) / time (use 16 bit subtract, then 16-bit by 16-bit multiply, then 32-bit by 16-bit divide)
- output frequency and phase as necessary
- goto outer loop
As I showed above, do all the setup at the start.bjox1 said:Mike, I am all stuck after this. Please advise on this:
- Now at this time Timer1 will still be running so setup CCP2CON for the rising edge on CCP2 pin.
- Save CCP2 capture value.
- Thus do CCP2 - CCP1b.
Am I on the right track mike??
bjox1 said:I really appreciate all ur suggestions.
Awaiting ur reply.
Thanks again.
<edit> Please please help me on this!!
list p=16f877a
include "p16f877a.inc"
__config _LVP_OFF & _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _BODEN_OFF & _DEBUG_OFF
cblock 0x020 ;start of general purpose registers
H1
H2
L1
L2
AnsH
AnsL
endc
; Start at the reset vector
org 0x000
goto Start
Start org 0x010
clrf PORTB
clrf PORTD
clrf PORTC
clrf H1
clrf H2
clrf L1
clrf L2
clrf AnsH
clrf AnsL
clrf TMR1H
clrf TMR1L
; clrf CCP1CON
clrf CCPR1H
clrf CCPR1L
bsf STATUS,RP0 ;bank 1
bcf STATUS,RP1
movlw b'00000100'
movwf TRISC
movlw b'00000000'
movwf TRISB ;portb [7-0] outputs
movlw b'00000000'
movwf TRISD ;portd output
bcf STATUS,RP0 ;bank0
; bcf PIR1,CCP1IF
;**********************************************
Main: movlw b'00000001' ;timer 1 using to capture, prescaler 1:1
movwf T1CON
;bsf T1CON,TMR1ON
movlw b'00000101'
movwf CCP1CON ;start with rising CAPTURE
Wait:
btfss PIR1,CCP1IF
goto Wait
movf CCPR1H,H2 ;save the value in H2 and L2 {lower value}
movf CCPR1L,L2
bcf PIR1,CCP1IF
;
movlw b'00000100' ;config CCP1 to faling
movwf CCP1CON
Wait1:
btfss PIR1,CCP1IF
goto Wait1
movf CCPR1H,H1 ;save now the value in H1,L1
movf CCPR1L,L1
bcf PIR1,CCP1IF ;clr flag CCP1
;SUB lower value H2,L2 from current value H1,L1
SUB:
movf L2,W
subwf L1,W
movwf AnsL
movwf PORTB
btfss STATUS, C
goto BORROW
goto SUB_1
BORROW:
decf H1, F
SUB_1: movf H2,W
subwf H1,W
movwf AnsH
movwf PORTD
; goto Main
;************************************************
end
movf CCPR1H,H1 ;save now the value in H1,L1
movf CCPR1L,L1
movf CCPR1H,W ;save now the value in H1,L1
movwf H1
movf CCPR1L,W
movwf H1
movf CCPR1H,H2 ;save the value in H2 and L2 {lower value}
movf CCPR1H,w ; copy the value into the W reg
movwf H2 ; and then into H2
movfw CCPR1H ; copy the value into the W reg
movwf H2 ; and then into H2
loop goto loop
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?