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

Timing two pulses on two pins

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







Timing two pulses on two pins
PostPosted: Fri Nov 05, 2004 11:32 pm     Reply with quote

Hi- I am a newbie

I would like to use the PIC16F84A to time as accurately as possible two duty cycles (high and low). The pulses come from two different sensors.
Could any one help me please- I have been trying to use interupts and counters with no success. If someone has a code snippet, and could tell me what pins on the pic I can use, I would greately appreciate it.

Thanking you in advance.

arrow
Ttelmah
Guest







Re: Timing two pulses on two pins
PostPosted: Sat Nov 06, 2004 3:07 am     Reply with quote

arrow wrote:
Hi- I am a newbie

I would like to use the PIC16F84A to time as accurately as possible two duty cycles (high and low). The pulses come from two different sensors.
Could any one help me please- I have been trying to use interupts and counters with no success. If someone has a code snippet, and could tell me what pins on the pic I can use, I would greately appreciate it.

Thanking you in advance.

arrow

To get a reasonable answer, you need to say what clock rate the chip is, what the likely rate/wdth of the pulses is, and whether anything else needs to happen at the same time.
Realistically, if the likely minimum width is less than perhaps 100 clock ccles, you would be much wiser, to consier a different chip, select one with dual CCP modules, and do the timing in hardware. For low rate pulses, you'd probably get the best results from the 84, by simply 'polling' the lines, but it is not the best chip for this application.

Best Wishes
Trampas



Joined: 04 Sep 2004
Posts: 89
Location: NC

View user's profile Send private message MSN Messenger

PostPosted: Sat Nov 06, 2004 6:37 am     Reply with quote

One of the easiest methods is to use the KBI (Key board interrupts) or the external interrupts.

The key board interrupts work well as you get trigger on both edges of the signal. The external interrupt you have to change edge on each interrupt.

So here is the rough flow chart. You initlize the processor and also configure a timer. I use a 16 bit timer runnint at instruction clock speed and then have another 16 bits which is incremented on over flow. Thus giving me 32 bit timer.

Code:


//This code will not compile, just for reference
volatile UWORD freq;
volatile UWORD duty;

void isr()
{
    static UWORD high=0; //time of last high edge
    UWORD temp;

    temp=timer0; //read your timer

    //read your input pin to see if positive or negative edge
    if (KBI0)
    {
        //we have a high edge
        if (temp>high)         //the timer will overflow so check it.
            Freq=temp-high;   
     }else
     {
          //we have a low edge
          if (temp>high)       //Again timer could have overflowed
            duty=temp-high;
      }
      //do any clean up needed
}


This system will work really well for most applications as long as the signal is not faster than the ISR routine. The only further recommendation is that when you read the frequency or duty cycle global variable, disable the interrupt before doing so. Since these variables in my example are 16 bit you could read half of data and get interrupt, then second half is corrupt.

I use this method in my project running at Fosc=40Mhz and can measure frequencies up to 10Khz, with no optimization of the code.

Trampas
arrow
Guest







PostPosted: Sat Nov 06, 2004 11:45 pm     Reply with quote

Hi Tampas

Thank you for your reply and code snippet. I think I will be OK since the frequency of my pulses is about 1kHz, and can be run even slower, I can run with a 20MHz clock speed, my duty cycle might be say 10%.

What I would like to ask you though, is what is KBIO in your code?
I have 2 pulses comming in from 2 different sensors.
How do I make sure that the two signals are not mixed up. (I think I need to use 2 different input pins?)

All the best
arrow
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Sun Nov 07, 2004 8:45 am     Reply with quote

Keyboard Interrupts as he calls them are usually associated with some pins on portb. You get an int whenever one of the pins changes. You will have to detect which one by storing the last state. If you are monitoring 2 inputs, then you would have KBI0 and KBI1. These are just declared and pins on portb.
Ttelmah
Guest







PostPosted: Sun Nov 07, 2004 11:30 am     Reply with quote

Mark wrote:
Keyboard Interrupts as he calls them are usually associated with some pins on portb. You get an int whenever one of the pins changes. You will have to detect which one by storing the last state. If you are monitoring 2 inputs, then you would have KBI0 and KBI1. These are just declared and pins on portb.

The classic problem though is latency.
Any interrupt on th PIC with CCS, involves about 30 instruction cycles of latency, before the routine itself is reached. If you then sample the input, to see which inputs have changed, and assume that two have, you cannot tell to within the latency time, when they each changed. One triggered the interrupt, but you have no way to know which one. Hence the best possible accuracy, is in the order of perhaps 30 instruction times (which is why I said that about 100 clock cycles was the closest I'd suspect you could get). The poster talking about sampling 10KHz, on a 40Mhz clock, is up at 100 instruction times (400 clock cycles). Polling would get closer, by just sitting in a tight loop, reading the input, and then the RTC. If the value on the RTC, is less than the last reading, increment a 'wrap' counter, so you have a larger counter to measure the time with. Generate a value based on the two 'last reading' bits, and the two 'current reading' bits. This gives just 16 possible states, and branch on the basis of these states. All the ones where the readings are the same, can simply keep looping. The ones with a change, just record the current time. According to which edge it is, you can then either keep looping, or output the required time. Done tightly, I suspect you could get resolution down to perhaps typically about 20 instructions. This is 80 clock cycles, and is about as close as the hardware is really capable of going.

Best Wishes
Trampas



Joined: 04 Sep 2004
Posts: 89
Location: NC

View user's profile Send private message MSN Messenger

PostPosted: Sun Nov 07, 2004 2:50 pm     Reply with quote

Since the orignal poster mentioned that the signal was 1Khz the interrupt latency is not an issue. But you are correct a tight polling loop is much faster, as long as you do not need to do anything else with the processor.

The interrupts works well as the latency will be pretty constant, thus the accuracy is pretty good. Now detecting the excate edge is a bit delayed but depending on the design this might not be a problem.

I have also noticed that when a keyboard interrupt is triggered on the 18F8680 I sometimes get a edge detection on the external interrupts, even though they are tied through a 6K resistor to Vcc. I did put a 200MHz scope on the pin and found no signal level change, thus I assume it is a internal processor problem. I found that the interrupt latency is actually a good thing, in this case, as I use for the software debounce. That is check the pin level, if not what expected assume it was some noise bounce. Again I do not need every pulse accuracy for my application.

Trampas
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