CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Pulse width measure

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ljbeng



Joined: 10 Feb 2004
Posts: 205

View user's profile Send private message

Pulse width measure
PostPosted: Thu Aug 11, 2005 10:23 am     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Thu Aug 11, 2005 10:51 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Aug 11, 2005 1:17 pm     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Thu Aug 11, 2005 1:47 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Aug 11, 2005 1:57 pm     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Thu Aug 11, 2005 3:03 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Aug 11, 2005 3:47 pm     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Thu Aug 11, 2005 4:55 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Aug 15, 2005 8:08 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Aug 15, 2005 8:55 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group