Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] controlling timing accurately for fixed duty cycle variable period

Status
Not open for further replies.

tinkerer73

Member level 3
Member level 3
Joined
Apr 5, 2011
Messages
65
Helped
3
Reputation
6
Reaction score
3
Trophy points
1,288
Visit site
Activity points
1,892
Hello,

I'm trying to set up a simple program which will cycle through a set of specified time periods for a 50% duty cycle pulse. I have the calculations for the delay period, but I'm not confident on how to set up the program for accurate timing.

I have at my disposal currently PIC12F1501, PIC16F628, PIC16F1829, and PIC18F44K22 chips. I'm assuming I can do what I want with any of them, but the smallest interval I need to be able to do is a 9ms period, so 4.5ms changes (high-->low or low-->high)

I'm using XC8, but if someone can help with ASM if it's better, I am open to learning. I am pretty rough with assembly still, but I know I'll need to learn to be more proficient to write the programs I want to write.

Thanks in advance for any help that can guide me in the right direction.
 

Hi,

Get it started and simulate your code on MPSIM and Proteus. You can start projects using assembly language and with the most basic experiment of LED blinking. With PIC16F devices be careful about the bank selection. A simpler use of MPSIM is mentioned in
HTML:
http://embeddedinterconnects.blogspot.com/
. You can then verify your code on Proteus and then the real hardware. If you are getting problem paste you code here. Lots of people will help you, but at least "start".

enjoy!
 

Are you talking about using the chip's PWM module or a completely software driven PWM?

If the former, then this link may help: https://www.micro-examples.com/public/microex-navig/doc/097-pwm-calculator.html

Try some numbers in it, and you will see that to get the low frequencies you apparently want, you will have to run the PIC at a fairly low clock. What range of PWM frequencies do you want? Are you willing to used another chip, such as a flip flop, to get a divide-by-two result? The latter approach will give a 50% cycle, so you can then concentrate on just creating the 2X starting frequency. You could do that with the PWM module and a slow clock, or use a faster clock and software (i.e., set pin high, delay, set pin low, delay etc.). A look-up table could e used for the delay constants.

John
 

I'm talking about software, because I want to be able to control the period of the PWM for specific, exact timings. Ultimately my program will cycle through 10 different settings, staying on each one for around 10 seconds.

I don't have frequencies, per se, that I need, but here are the 10 periods I need, in milliseconds:
90, 45, 30, 22.5, 18, 15, 12.86, 11.25, 10, 9

I am familiar with creating software PWM, but until now, I have had no reason to have a specific period. My PWM routines have been:

set pin high
check if duty cycle reached, if so, set pin low

This one, as you say, will simply be:

set pin high
delay (1/2 period)
set pin low
delay (1/2 period)

My question is, how do I set my period to output the exact timing I want? I know I'm going to have to scale my timer for interrupts, but I'm not sure exactly how I can do this. Forgive me, but I'm quite a novice with programming microcontrollers, so I've got a lot to learn, which is why I'm here.

- - - Updated - - -

OK, I'm trying to work through this, and I need to know if I'm on the right track. Please check my math and set me right if I'm not calculating correctly.

With an 8mhz clock, each clock tick takes 0.000125ms, correct?
So if I want a period of 90ms, with a 50% duty cycle, I'm looking to have the interrupts give me a trigger for the flip-flop at 360000ms intervals? This would mean a 16 bit timer set to 0xEA60 (60000) would need a prescaler of 6? Am I on the right track here? Also, am I correct in assuming that because I'm resetting the timer manually within my subroutine, I'm going to need to be very careful to subtract from my timer reset the offset for the instruction cycles that preceed the reset (so that I don't end up with the effective interrupt being 60012, 60016, etc)? Am I making sense?
 

I'm talking about software, because I want to be able to control the period of the PWM for specific, exact timings. Ultimately my program will cycle through 10 different settings, staying on each one for around 10 seconds.

If you want exact 50%, use the divide-by-two method I mentioned. Here is one link: **broken link removed** I strongly suggest that you Google on it. There are other ways and many links.


I don't have frequencies, per se, that I need, but here are the 10 periods I need, in milliseconds:
90, 45, 30, 22.5, 18, 15, 12.86, 11.25, 10, 9

Divide 1 by the time in mS to get Hertz (i.e., 1/sec = 1 Hz). Your frequencies are roughly 11.1111 Hz to 111.111 Hz. Of course your attainable accuracy is limited by the accuracy and frequency of your clock. What sort of accuracy do you need in ppm?

As for how to set up your MCU, the divide-by-two may well give more accuracy for the 50% duty cycle than trying to do it the way you describe. Yes, when setting timing, you need to consider all steps. Sometimes the error is trivial, but sometimes it is not. If you look at the Delay Code Generator on PicList, you will see that NOP's are added for some values.

John

Edit:

With an 8mhz clock, each clock tick takes 0.000125ms, correct?

Of course, that is the time for one oscillator cycle. What is important is the time for one instruction cycle, which is 4X that, or 0.5 µS per instruction cycle. Also forgot to add that you could use a look-up table for the constants (probably 3) needed for each delay, if you use the PicList approach. Since for 50% duty cycle, on and off are equal, that table would only need 30 values.
 
Last edited:

Thanks for the info. I'll check out the flip-flop and PicList.

I do need this to be pretty accurate. It's going to be used for calibration purposes, but it's not critical. a 5% margin of error isn't going to kill me, but I'd like to try to nail it. This is being used to calibrate a vechile speedometer, which expects a 4000 pulse per mile signal at 5v to the input.

You're right, the frequencies are all multiples of 1.11111111: 11.111111, 22.222222, 33.33333, etc... this will give me 10mph, 20mph, 30 mph, etc.. My plan is to have it set to each one and hold there for approximately 5 seconds.

If there's a subroutine for setting frequencies, than that would work, but I'm assuming for the simply PICs I have available right now, it would be better to think in terms of clock timing.

And yes, I know most instructions are 4 clock ticks, with branching being 8, but I wanted to make sure I'm on the right track with my math.
 

For 5% accuracy (i.e., 50,000 ppm), I'd forget about the divide-by-two or counter and just do as you suggest, because you are comfortable with that method. Just checked the delay code generator (), and your longest delay needs only two constants.

You might be able to write a general routine and get those constants from a table or use a macro, since only 10 different delays are needed.

John
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top