View previous topic :: View next topic |
Author |
Message |
ljbeng
Joined: 10 Feb 2004 Posts: 205
|
Pulse width measure |
Posted: Thu Aug 11, 2005 10:23 am |
|
|
Here is a screen shot from my DigiView analyzer....
SAF is RA4 pulse width and these pulses are 8.3333ms apart.
LOWVOLT is PIN_A0
RA4 increments TIMER0.
I have the 18F2620 and it runs at 4.096Mhz.
Can someone explain why there is a 137.52us delay from when SAFIN goes high to PIN_A0 going high? That computes to 140 instruction cycles.
Inside the TIMER0 interrupt, I want to measure RA4 pulse width. When I interrupt, I ignore the pulse that caused the interrupt and wait for the next pulse. I disable TIMER0 interrupt while waiting. Here is some of the code I use...
Code: | //wait for low pulse to pass
while(!input(safin)) restart_wdt();
voltcnt = 0;
//actually count and find pulse width here
output_high(pin_a0);
while(input(safin)){
voltcnt++;
if (bit_test(voltcnt,8)) goto safopen;
}
output_low(pin_a0);
|
Here is the listing:
Code: | .................... //actually count and find pulse width here
.................... output_high(pin_a0);
182C: BSF F89.0
.................... while(input(safin)){
182E: BTFSS F80.4
1830: BRA 1840
.................... voltcnt++;
1832: INCF xA2,F
1834: BTFSC FD8.2
1836: INCF xA3,F
.................... if (bit_test(voltcnt,8)) goto safopen;
1838: BTFSS xA3.0
183A: BRA 183E
183C: BRA 18D2
.................... }
183E: BRA 182E
.................... output_low(pin_a0);
1840: BCF F89.0
|
|
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Aug 11, 2005 10:51 am |
|
|
I don't think you have really given us enough of the program to say for sure but you are looking for a rising edge so you must make sure the signal is not already high.
Code: |
//make sure that the signal is not high
while(input(safin)) restart_wdt();
//wait for low pulse to pass
while(!input(safin)) restart_wdt();
voltcnt = 0;
//actually count and find pulse width here
output_high(pin_a0);
while(input(safin)){
voltcnt++;
if (bit_test(voltcnt,8)) goto safopen;
}
output_low(pin_a0); |
|
|
|
ljbeng
Joined: 10 Feb 2004 Posts: 205
|
|
Posted: Thu Aug 11, 2005 1:17 pm |
|
|
Here is the full timer0 interrupt. I preset timer0 to 255 so it overflows every 8.333ms on the rising edge....
Code: | #int_TIMER0
TIMER0_isr(){
//interrupts every 120Hz from ac in h11aa1
// safety ac input has no filter capacitor so it send a 60 hz (x2) pulse to
// Ra4 input which increments timer0. Timer0 is preset to 255 so this interrupt
// occurs on every rising pulse....
t0intcnt++;
// check pulse width every 60 interrupts, or 2 per second
if ((t0intcnt == 60) && (lvoltset != 100)){
output_high(pin_a0);
if (strrely) {
t0intcnt = 0;
goto safcnt;
}
t0intcnt = 0;
disable_interrupts(int_timer0);
voltcnt = 0;
//wait here to ignore 1 pulse if interrupt started in mid high pulse...
while(input(safin)){
voltcnt++;
restart_wdt();
if (voltcnt > 200) goto safopen;
}
//wait for low pulse to pass
output_low(pin_a0);
while(!input(safin)) restart_wdt();
voltcnt = 0;
//actually count and find pulse width here
output_high(pin_a0);
while(input(safin)){
voltcnt++;
if (bit_test(voltcnt,8)) goto safopen;
}
output_low(pin_a0);
voltchck = voltcnt;
if (voltcnt > lvoltset) intlowvolt = 1;
if (voltcnt < lvoltset - 5) intlowvolt = 0;
//if (voltcnt > 84) intlowvolt = 1;
//if (voltcnt < 80) intlowvolt = 0;
goto sout;
}
if (lvoltset == 100) intlowvolt = 0;
safcnt:
for (voltcnt = 0; voltcnt < 200; voltcnt++){
if(!input(safin)) goto safgood;
}
goto safopen;
safgood:
lvoltage = voltcnt;
if (scan1) {
if (!safintstat && aron && autorevc0) lgtowar = 1;
safintstat = 1; //Good
}
goto sout;
safopen:
t0intcnt = 0;
if (safintstat){
bit_clear(pacio,fwdout);
bit_clear(pacio,revout);
sendrelayio();
safintstat = 0; //Open
scan1 = 0;
}
sout:
sfft = 0;
set_timer0(255);
enable_interrupts(int_timer0);
}
|
Here is a newer pulse update.. The left brown pulse is the one that caused the interrupt (I also pulse PIN_A0), you can see the interrupt latency of A->B or 159us. When the brown pulse goes low, I am still inside the interrupt waiting for the pulse to go high. When it goes high again, I am setting pin_a0, and this is where there is a 116us delay (X->Y). I can't explain it because the assembly shows only a few lines of code between checking for SAFIN going high and PIN_A0 is commanded high.
|
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Aug 11, 2005 1:47 pm |
|
|
According to your waveforms, I see 2 consecutive LOWVOLT pulses. But how is that possible from
Code: |
// check pulse width every 60 interrupts, or 2 per second
if ((t0intcnt == 60) && (lvoltset != 100))
|
|
|
|
ljbeng
Joined: 10 Feb 2004 Posts: 205
|
|
Posted: Thu Aug 11, 2005 1:57 pm |
|
|
LOWVOLT is sort of a misnomer. It is really just a marker so I know when the interrupts occurred. It will eventually be taken out. The interrupts only occur on the brown pulses and every 60th pulse, I measure the width.... |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Aug 11, 2005 3:03 pm |
|
|
You stated that LOWVOLT is PIN_A0.
I see this waveform with a period of 8.3ms.
You are only measuring every 60th one or 500ms.
Something does not add up. |
|
|
ljbeng
Joined: 10 Feb 2004 Posts: 205
|
|
Posted: Thu Aug 11, 2005 3:47 pm |
|
|
I am not controlling SAFIN, it is pulsing every 8.333ms always...
I AM controlling PIN_A0 (LOWVOLT) so I can put my scope on that line to see when the interrupt occurrs..... |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Aug 11, 2005 4:55 pm |
|
|
I don't think that you are following me. What is the time between pulses on LOWVOLT? I expect it to be 500ms but I am seeing 8.3ms. How is this possible. |
|
|
ljbeng
Joined: 10 Feb 2004 Posts: 205
|
|
Posted: Mon Aug 15, 2005 8:08 am |
|
|
Ok, I see.... Looking at my second posted picture, that is the 60th SAFIN pulse, when the interrupt actually gets serviced, I pulse pin_a0 high and then low when the 60th pulse ends. I then stay inside the interrupt routine, looping, waiting for the 61st pulse and when I see that pulse, I set pin_a0 high again, and this is where I am seeing a long delay and I am not measuring the full pulse width... |
|
|
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
|
Posted: Mon Aug 15, 2005 8:55 am |
|
|
I havn't looked at your code too closely, but is it possible that your count is expiring and leaving the interrupt?
Code: | while(input(safin)){
voltcnt++;
restart_wdt();
if (voltcnt > 200) goto safopen;
} |
_________________ -Matt |
|
|
|