• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Generating a frequency or multiple frequencies with a Microcontroller's output pins

Status
Not open for further replies.

halflife

New Member
I am a newb and just started to learn programming with Microcontrollers. I don't know whether I should use BINARY or C Programming on MPLAB. I want to generate frequencies between 1Hz to 1Mhz on the pin outputs of a Microcontroller. The frequency has to be very accurate and I want to use a quartz crystal along with the frequencies so they may be highly accurate.

An example I would like to accomplish.

- A microcontroller having 1 output pin as 10Hz
- A microcontroller having 3 output pins as 10Hz, 30,000Hz(30khz) and 2000Hz(2khz)

Also, may someone recommend me a Microchip Microcontroller that is not too expensive but cheap and can do the job for generating frequencies?

Thank you.
 

AnalogKid

Well-Known Member
Most Helpful Member
Is there a reason it has to be done with a uC? Three crystal oscillators are not expensive and can be running in 5 minutes.

Also, even with a 20 MHz clock, a uC making a 1 MHz output on an I/O pin will not be able to do much of anything else.

ak
 

halflife

New Member
Is there a reason it has to be done with a uC? Three crystal oscillators are not expensive and can be running in 5 minutes.

Also, even with a 20 MHz clock, a uC making a 1 MHz output on an I/O pin will not be able to do much of anything else.

ak
Thank you for the reply.

As I learned, instead of using a 555 timer to accomplish frequencies which become inaccurate after around 20 minutes, a Microcontroller is a better option along with a quartz crystal to get a high accuracy of frequency outputs.

Is it possible to use a 4Mhz crystal oscillator to obtain all 3 frequencies instead of using more than one?
 

jpanhalt

Well-Known Member
Most Helpful Member
I would use a cheap DDS module and control it with a microcontroller. I posted an example using a PIC MCU and a cheap DDS module here: http://www.electro-tech-online.com/articles/demo-assembly-code-ad9850-dds-signal-generator.755/

The accuracy is dependent on the crystal, but you can easily get fractional Hz up to about 1/4 or more (as I recall) of the timing crystal. The example is programmed in Assembly, which is perhaps what you mean by "binary," but C, if you know it, would be almost as easy.

If you do not need at lot of funny values, then a crystal-controlled MCU is suitable, but you will be limited to "binary" (or integral) multiples and divisions of the base frequency available from the various timers in the MCU, unless you use something like Mike (K8LH) has presented here for a cycle accurate timer.

In sum, I would recommend the DDS as a starter.

John
 
Last edited:
If you can find a micro with four or more autonomous timer-outputs, you might get lucky
A 3-phase PWM generator will provide three.
The MK20DX256VLH7 (link)has a total of 12, although you'll probably be limited to two or three different prescalers
 
Last edited:

halflife

New Member
I would use a cheap DDS module and control it with a microcontroller. I posted an example using a PIC MCU and a cheap DDS module here: http://www.electro-tech-online.com/articles/demo-assembly-code-ad9850-dds-signal-generator.755/

The accuracy is dependent on the crystal, but you can easily get fractional Hz up to about 1/4 or more (as I recall) of the timing crystal. The example is programmed in Assembly, which is perhaps what you mean by "binary," but C, if you know it, would be almost as easy.

If you do not need at lot of funny values, then a crystal-controlled MCU is suitable, but you will be limited to "binary" (or integral) multiples and divisions of the base frequency available from the various timers in the MCU, unless you use something like Mike (K8LH) has presented here for a cycle accurate timer.

In sum, I would recommend the DDS as a starter.

John
Thank you for the reply. Yes, I meant ASSEMBLY, not BINARY.
I am definitely thinking to use a crystal controlled MCU as you said, but if it is that difficult to obtain multiple frequencies based on the various timers on a single uC, I will start off with a single frequency output on a microcontroller with 32.768khz crystal to get a 30khz output. Would this be ok? Can you recommend me a uC from Microchip?

Would you recommend ASSEMBLY to program this or C language?
 

jpanhalt

Well-Known Member
Most Helpful Member
There are many PIC's to chose from. Look at the "timer2" module , which gives 1:1 to 1:16 divisions by 1's. Mid-range, 8-bit PIC's offer that, but I prefer the enhanced mid-range that are about the same price (or less) as they have other features and an enhanced instruction set.

Just figure out how many pins you need. 10F3xx are the smallest, 12F1840 (etc.) are 8 pin, and 16F1xxx have more pins.

John
 

ronsimpson

Well-Known Member
Most Helpful Member
microcontroller with 32.768khz crystal to get a 30khz output.
NO! Not going to happen.
1) Many micros have a hardware counter that; (crystal/4)/(2 to 255)
....So the 4mhz crystal frequency becomes 1mhz....Then the 1mhz goes to a divider in the range of 2 through 255.
....Many different types (some are 16 bit)
2) In software you can count 100 cycles, IO pin = high, count 100 cycles, IO pin = low, loop.

In both cases you want the crystal as high as possible so you can divide down to the frequency you want.
Starting at 32758 and dividing to 30000 can not happen.

Do you want a square wave? or a sign wave?
 

halflife

New Member
NO! Not going to happen.
1) Many micros have a hardware counter that; (crystal/4)/(2 to 255)
....So the 4mhz crystal frequency becomes 1mhz....Then the 1mhz goes to a divider in the range of 2 through 255.
....Many different types (some are 16 bit)
2) In software you can count 100 cycles, IO pin = high, count 100 cycles, IO pin = low, loop.

In both cases you want the crystal as high as possible so you can divide down to the frequency you want.
Starting at 32758 and dividing to 30000 can not happen.

Do you want a square wave? or a sign wave?
I would like a square wave output.

As for your point #2, is counting cycles in software a lot easier to make a frequency on an output pin? How would I do this with 30khz? I am assuming it would be 30,000 cycles in IO pin high, and then IO Low ends up looping back to IO High to restart 30,000 cycles again.
 

AnalogKid

Well-Known Member
Most Helpful Member
I forgot to mention that uC internal peripheral, such as a programmable prescaler, could generate fairly high frequencies without tying up the cpu. Separate from that, Using a 32.768 kHz source to generate a 30.000 kHz output will not work well as there is no common multiplier or divisor. Better to start with a 3.000 MHz crystal, use a prescaler to divide it down to 30.000 kHz, and use software to divide that down to 2.000 kHz and 10 Hz.

ak
 

jpanhalt

Well-Known Member
Most Helpful Member
As mentioned, a DDS will give in all likelihood better resolution. With a PIC at 4 MHz it might be a complicated to get exactly 30 kHz, if even possible. However, at 3 MHz, you can get exactly 30 kHz from the PWM CCP module (compare/capture/pwm). Register settings for a 50% duty cycle are (decimal):
PR2=24; T2CON=4;CCPR1L=12;CCP1CON=28; and TMR2 prescale =1 -- just for example.

Perhaps a place to start would be for you (halflife) to describe what you need it for, how precise you need each frequency (e.g., is 30.30303 kHz close enough to 30 kHz for your example?), and what frequencies you need.

John
 

OBW0549

Active Member
Rather than trying to generate frequencies in software, or via one of the timer/counter peripherals (a major challenge, if you are trying to generate several frequencies simultaneously), you might consider using one of the PIC microcontrollers that contain what Microchip calls the "Numerically Controlled Oscillator" peripheral, or "NCO." The NCO is basically the frequency-determining core of a DDS device, but without the sine lookup table that DDS chips such as the AD9850 have for generating sine waves; the NCO only generates square waves.

It turns out that several of the cheapest PIC chips are equipped with an NCO; the PIC10F322 in particular, is so inexpensive (≈ $0.50 US each at Digi-Key) that you could have one PIC dedicated to each frequency. Alternatively, if you don't need simultaneous generation of multiple outputs, you could program the PIC to load various frequency control words into the NCO based on the state of one or more PIC input pins.

Read the PIC10F322 data sheet to see how this could work.
 

ronsimpson

Well-Known Member
Most Helpful Member
As for your point #2, is counting cycles in software a lot easier to make a frequency on an output pin? How would I do this with 30khz? I am assuming it would be 30,000 cycles in IO pin high, and then IO Low ends up looping back to IO High to restart 30,000 cycles again.
The computer is counting TIME not FREQUENCY. You know t=1/f
Example: 4mhz crystal, 4 clocks/instruction, 1,000,000. instructions/second, 1u second/instruction.
30,000hz=33.333uS for the period, 15uS low + 15uS high = 30,303hz. not exactly 30khz but as close as you can get with that crystal.
Now if you used a 8mhz crystal you could get closer because every instruction is 0.5uS.
A 16mhz crystal will give you 0.25uS steps.
 

halflife

New Member
The computer is counting TIME not FREQUENCY. You know t=1/f
Example: 4mhz crystal, 4 clocks/instruction, 1,000,000. instructions/second, 1u second/instruction.
30,000hz=33.333uS for the period, 15uS low + 15uS high = 30,303hz. not exactly 30khz but as close as you can get with that crystal.
Now if you used a 8mhz crystal you could get closer because every instruction is 0.5uS.
A 16mhz crystal will give you 0.25uS steps.
That makes a lot more sense to me now.

Im assuming the only way to use 3 frequencies on a microcontroller with limited prescalers is to program arrays and use a tact button and press it 3 times so it switches to a different frequency on a single pin, if that is a lot easier to do.
 

jpanhalt

Well-Known Member
Most Helpful Member
Three very cheap DDS modules or a two MCU's (operating with dual timers) will will give you at least three independent frequencies.

Why do you want to make it difficult?
 

Pommie

Well-Known Member
Most Helpful Member
If uS accuracy is acceptable then a 16F18324 could easily generate the required frequencies with a 4MHz crystal. Using the 3 16 bit timers along with 3 CCP modules in compare mode would give accurate frequencies to a resolution of 1μS.

The code would be fairly simple but not really for a beginner.

Mike.
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top