variable frequency square wave - Page 1
Forum section: electronics / projects

author: dpenev
author_rank: Regular Contributor
timestamp: May 20, 2019, 07:32:10 am
content: Hello,I am designing a STM32L4 based MCU system.One of the requirement is to generate square wave with arbitrary frequency in the range 1KHz - 1MHz.I need something like 0.1% accuracy of the frequency control.Initially I thought that the PLL inside the STM32L4 will do but it looks as it is intended to clock the whole CPU (and I2S peripherals) only.This PLL is quite limited in terms of M/N counters.Then I tough that probably I can use one of the STM32L4 timers to improve the frequency I can get out of the PLL.Unfortunately the STM32L4 timers can be clocked from the PLL but only thru the system clock.So adjusting the frequency I will have to change the system clock as well. This means as special procedure..So I seems to give up with the pure STM32L4 solution.Then I have started to look at external PLL chips and I found Si5351.It looks as if will work for me.Anyone willing to suggest an alternative or just share some thoughts?Thank youDimitar

author: OM222O
author_rank: Frequent Contributor
timestamp: May 20, 2019, 07:50:26 am
content: why are you trying to reinvent the wheel? I haven't used the STM chips but the solution is pretty much standard. No need to use PLLs / change clock frequency, etcJust use the built in timers. There also usually exists a compare register (I will be extremely surprised if the STM MCUs don't have this, as even the cheapest MCUs have timer compare registers! arduino as an example and their lowest end micros: ATTINY10 have this!). Knowing the clock frequency of the timer register, you set the value at the comparator register, which then causes an interrupt at that set value. you then create an interrupt service routine to change the pin state high or low. the frequency of the output will be the easy to calculate based on the known factors and maybe a few clock cycles out due to instructions being carried out, but certainly much better than 0.1%Edit: here is an article from adafruit with detailed explanations for arduino, but you should be able to read the datasheet of the STM32 and easily figure out the details such as registers and whatnot:https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers

author: Kleinstein
author_rank: Super Contributor
timestamp: May 20, 2019, 07:57:01 am
content: One could use the timers to divide the system clock frequency. So one gets system clock divided by N .This gives good resolution at least for the lower frequencies. For the higher frequencies the resolution is limited however. This is a principle limit of the µC, as time steps are limited to the system clock.For higher resolution also at higher frequency, there are several options, e.g.:1) if only the average frequency needs to be right one could use a fractional divider - however this has quite some jitter.2) use an external PLL to multiply a frequency by something like a factor of e.g. 64 or 256 (fixed) for the highest frequencies.The divider in the µC could than also use a fractional divider as the PLL filters the jitter.3) Use DDS to generate a sine wave first and than convert to square with a comparator. The DDS part could be a special chip or possibly in software with the µC (could be tricky near 1 MHz).4) Use an VCO and external divider for the coarse part to generate the raw frequency and use the µC to do the PLL in software.

author: dpenev
author_rank: Regular Contributor
timestamp: May 20, 2019, 08:33:06 am
content: Hi Guys,@OM222O Thank you, I will take a look at your article to see if I can get rational out of it.@Kleinstein Thank you! I will comment your sentences as i think those are very relevant.QuoteIndeed my current solution is using 16MHz as base clock and by simple division I get something like 0.6% error at 100KHz and error goes more than 6% at 1MHzQuoteYes jitter will be a problem for my application. Also implementing of fractional divider for 1MHz output will be very difficult I believe.Any practical results about this on 32MHz ARM M4?QuoteWhat would be the benefits of generating 64/256 times bigger target clock first by the external PLL?(compared to the exact target clock)Do you consider PLL chip for 1KHz impractical, so that's why you suggest this?Or this will just reduce the jitter?I believe external PLL will generate signals with acceptable jiter for my application.QuoteInteresting! But I believe this will be an overkill for my application.QuoteDo you mean real PLL in software with phase detector or just a divider here?In fact can the STM32L4 timer system (input capture, output compare) is able to implement PLL efficiently?Unless efficient PLL can be implemented by the STM32L4 timer I believe that 2) (and external PLL) is my best option.Anyone willing to suggest an inexpensive PLL/controllable oscillator.My target output clock frequency is quite low. range (1kHz - 1MHz)Thank youDimitar

author: ogden
author_rank: Super Contributor
timestamp: May 20, 2019, 08:50:36 am
content: 1MHz with 0.1% precision using integer divider (of hardware timer) means 1GHz clock. I agree that Si5351 is best way to achieve needed performance. Other way around would be DDS IC (AD9837) + comparator for square wave output.

author: Kleinstein
author_rank: Super Contributor
timestamp: May 20, 2019, 09:12:19 am
content: The Si5351 may indeed be a good solution. Either directly with an extra divider (e.g. /4) or to provide a variable system clock to the µC (not sure how well the µC likes clock steps).Doing a PLL in software is quite some effort. There can be some support from the input capture, but likely not that much. So the control loop would need to be relatively slow.The idea of an external fixed PLL (e.g. 4046 + divider) would be to generate a lower frequency with sufficient resolution by the µC. For a lower frequency (e.g. some 50-100 kHz) a fractional divider is feasible. Still it's a quite some extra HW and SW.

author: MasterT
author_rank: Frequent Contributor
timestamp: May 20, 2019, 09:47:04 am
content: Quote from: dpenev on May 20, 2019, 07:32:10 amYes, this upsets me too. The options is to route I2S pll output externally to one of the timers input capture pin.

author: dpenev
author_rank: Regular Contributor
timestamp: May 20, 2019, 11:03:28 am
content: Quote from: MasterT on May 20, 2019, 09:47:04 amHmm this may be actually a very good solution! Thank you!MCO output pin probably can be used as well (instead of I2S).I hope I will be able to clock the STM32L4 timer by an external 40MHz clock?

author: MasterT
author_rank: Frequent Contributor
timestamp: May 20, 2019, 02:14:47 pm
content: Should be 40 for sysclk = 80, likely synchronization I/O logic 'd limit any input frequency to 1 /2.

author: Kleinstein
author_rank: Super Contributor
timestamp: May 20, 2019, 03:55:03 pm
content: I don't think using an external clock to the µC timer will help. The timer output will very likely be synchronized to the µC system clock. So if it works at all the output would be with high jitter, just like a fractional divider on the µC.For the combination with the Si5351, I see 3 options:1) Use the Si5351 to provide the system clock to the µC and than use the µC timer for coarse adjust and the PLL for fine adjust.2) Use the Si5351 output with an extra divider (e.g. 74HCT74 or similar). AFAIK the Si5351 only goes down to some 3 kHz.3) Use the Si5351 for the higher frequencies and the µC internal timer for the lower ones (use different outputs or a switch/mux to choose)

author: dpenev
author_rank: Regular Contributor
timestamp: May 23, 2019, 03:07:18 pm
content: Hi Kleinstein,Sorry for the late response. I have rushed for the SI5351 testing.I have connected Adafrut Si5351 board to my CPU and I am able to talk to the Si5351 already.Quote from: Kleinstein on May 20, 2019, 03:55:03 pmI am afraid this can be the case. However I was not 100% and I have this in my todo.Anyone having direct experience with synchronizing any of the TMS32L4 peripheral from the external clock?Quote from: Kleinstein on May 20, 2019, 03:55:03 pmI am trying to avoid adjusting the MCU system clock on the fly.Quote from: Kleinstein on May 20, 2019, 03:55:03 pmI may actually require frequencies lower than I have initial requested in my first message. So external divider may require to be big.Quote from: Kleinstein on May 20, 2019, 03:55:03 pmThis was my initial intention but I drifted in favor of having MCU post divider with the MCU timer.Now after your message I may reconsider.Having big flexible post counter is a benefit but if it introduce a jitter is not a solution for me.Thank you Kleinstein once again.Dimitar

author: ogden
author_rank: Super Contributor
timestamp: May 23, 2019, 03:33:28 pm
content: Quote from: dpenev on May 23, 2019, 03:07:18 pmExternal clock of stm32 timers are resynchronized to timer bus clock. It means that external clock is useless in frequency generation application. Attach: figure from ST appnote AN4776

author: IDEngineer
author_rank: Super Contributor
timestamp: May 24, 2019, 03:50:38 pm
content: Quote from: OM222O on May 20, 2019, 07:50:26 amExactly this! In fact, better than this. I too haven't worked with the STM's but in Microchip PIC's this takes about half a dozen instructions and then it's all done in HARDWARE. It uses a single timer and two CCP modules. No interrupt service routine at all. The first CCP module acts as the preloader for the timer, and the second uses one of its many Compare modes - in this case the "toggle" mode, which toggles its output pin on every match - to generate your output signal. The resulting output frequency is controlled by your selection of prescaler and comparison values. Effectively zero jitter since there's no software in the loop. Frequency accuracy, short and long term, is determined by the MCU's clock source (likely a crystal). 1MHz and down is easily achievable, and in fact you can go above 1MHz easily too.Seriously, this could hardly be any simpler. No need for external components at all. Half a dozen lines of setup code and this would be off and running, with the MCU idling with zero workload since the hardware would be handling everything.I share OM222O's astonishment that the STM's would not already have this capability. It's been a fundamental baseline feature of MCU's for years and years. I'm going to download an STM32 spec sheet right now and take a look, just to satisfy my curiosity. Hopefully others who are already familiar with the STM32's can chime in and resolve the question.EDIT: I grabbed an STM32 spec sheet fromhttps://www.st.com/resource/en/datasheet/stm32l471re.pdf. There are many devices, this appeared to be a "lesser" one. Generally the peripherals are common across a given family, differing primarily in how many of each type are on the chip, so the specs for a given peripheral in this spec sheet are likely to be common to the same peripheral in other STM32's.Turning in our hymnals to section 3.32.2 (page 47), it describes "General-purpose timers (TIM2, TIM3, TIM4, TIM5, TIM15, TIM16, TIM17)". I skipped ahead to the description of TIM15, 16, and 17 which reads:QuoteI've bolded those features that may bear directly on the question at hand. Auto-reload suggests the timers can be configured to repeat at a given, selectable frequency (e.g. they have an internal comparator register). Prescaler suggests a very wide range of frequencies can be derived from the system oscillator. Output compare suggests they can emit a signal when compare occurs. If that can't repeat on every cycle, there's also the one-pulse mode output which suggests it will pulse when compare occurs. That "one-shot" like behavior may then be driven by a second timer, via the Timer Link feature and its suggestively-named event chaining, to repeatedly generate the pulse (and in this mode, you'd be able to use the first timer to set the pulse width while the second controls the frequency, giving you an additional degree of control over the resulting output).Sounds to me like a solution is waiting in the STM32 hardware, all that's required is some quality time with the spec sheet. Please report back!

author: ogden
author_rank: Super Contributor
timestamp: May 24, 2019, 04:10:34 pm
content: Quote from: IDEngineer on May 24, 2019, 03:50:38 pmAre you absolutely sure that PIC or STM32 can generate any arbitrary frequency up-to 1MHz with 0.1% accuracy? Before you answer - take some time and do some math

author: IDEngineer
author_rank: Super Contributor
timestamp: May 24, 2019, 04:49:30 pm
content: Quote from: ogden on May 24, 2019, 04:10:34 pmIf by "accuracy" you mean "lack of jitter", yes - the PIC's will do it because it's all in hardware. I've seen it on the scope. This isn't rocket science... it's not difficult for digital logic to stay within 1KHz on a 1MHz fundamental (which is 0.1%).If by "accuracy" you mean "absolute frequency", as noted that's dependent upon the oscillator source and is unrelated to the choice of MCU, hardware vs. software, etc.

author: ogden
author_rank: Super Contributor
timestamp: May 24, 2019, 05:05:43 pm
content: Quote from: IDEngineer on May 24, 2019, 04:49:30 pmFine. Let's take timer that is running at (precise) 72 MHz. Now please show how to generate 993 KHz, with 0.1% accuracy. By accuracy I mean frequency accuracy, output obviously w/o significant jitter.

author: NorthGuy
author_rank: Super Contributor
timestamp: May 24, 2019, 05:18:33 pm
content: Quote from: ogden on May 24, 2019, 04:10:34 pmThere are some PICs designed for high frequency PWM. They can do much better actually. For example, dsPIC33CK256MP508 family can produce 250 ps PWM resolution.Of course, rare MCU can produce sub-ns rise/fall times, so the wave you generate will not be very square if you look at it with 1 ns resolution. Thus, the 0.1% accuracy of 1MHz wave is a moot point. It all depends on the purpose of the generated square wave.

author: ogden
author_rank: Super Contributor
timestamp: May 24, 2019, 05:39:53 pm
content: Quote from: NorthGuy on May 24, 2019, 05:18:33 pmYes, There are few STM32 chips as well, yet HR timers as you already mention are made for PWM, not frequency division/generation. Proper way of generating arbitrary frequency clock is DDS. Second best way is programmable clock IC like mentioned Si5351.Quote from: NorthGuy on May 24, 2019, 05:18:33 pmRequirements are clearly stated in the OP: "0.1% accuracy of the frequency control".

author: IDEngineer
author_rank: Super Contributor
timestamp: May 24, 2019, 05:50:01 pm
content: Quote from: ogden on May 24, 2019, 05:05:43 pmOh, I see what you're asking. You want infinitely small increments of frequency. Sounds like you're headed for a pure analog solution!NorthGuy has already pointed out that PWM's often have much finer increment control. And looking back at the section of the STM32's spec sheet that I quoted, you'll note it specifically mentions "PWM" as another mode it supports. I just glanced at that spec sheet again, and PWM is offered not only on those timers, but others that are included in the STM32 family as well."By accuracy I mean frequency accuracy" (your words to me) is different from "arbitrarily small frequencyincrements". I stand by my earlier comment that a hardware timer-based approach can, indeed, deliver 0.1% frequency accuracy for those quantum frequencies it can select. However, if your definition of "frequency accuracy" is now changing to "arbitrarily small frequency increments" then you're going to need analog because no digital approach - not even a dedicated DDS chip - has infinitely small quanta.EDIT: Perhaps we can all get off the pedantic train here and wait for the OP to more clearly define his needs.

author: ogden
author_rank: Super Contributor
timestamp: May 24, 2019, 06:01:32 pm
content: Quote from: IDEngineer on May 24, 2019, 05:50:01 pmHe did define his needs clearly enough, in first few sentences of his post:Quote from: dpenev on May 20, 2019, 07:32:10 am What you say about DDS is so wrong:QuoteTuning granularity even for cheapest, most basic DDS IC AD9837 is (excerpt from DS):The frequency registers are 28 bits wide: with a 16 MHz clock rate, resolution of 0.06 Hz can be achieved.

author: IDEngineer
author_rank: Super Contributor
timestamp: May 24, 2019, 06:10:56 pm
content: "Arbitrary frequency" and "something like 0.1% accuracy of the frequency control" aren't necessarily the same thing, which is why we've got different interpretations running through this thread.But OK, let's run with it. Your example of 72MHz timer frequency isn't cast in stone. Remember (using the STM32 in this case), there's a 16 bit prescaler AND a 16 bit preload/comparator. Sometimes to get intermediate frequencies you need to vary both parameters, running the timer at a different frequency so the resulting divide yields the result you seek. We'd have to study the architecture of the STM32's timer system, but this potentially yields you (16 + 16 =) 32 bits of potential resolution off the original clock source to the timer module. Using your example of 72MHz and (to quote you again) "doing some math", that's (72MHz / (2^32) =) 0.017Hz per LSb, which is better than 0.1%resolution(if that's how the OP's comments are now being interpreted) at any frequency above 17Hz, almost two orders of magnitude below his 1KHz bottom end.

author: ogden
author_rank: Super Contributor
timestamp: May 24, 2019, 06:35:18 pm
content: Quote from: IDEngineer on May 24, 2019, 06:10:56 pmArbitrary frequency is what it is - *any* frequency. If you do not understand what "0.1% accuracy of the frequency control" means then I wonder - are we on the same page here?QuoteHe did not say 0.1% resolution just for bottom end.So please be so kind and do your math for frequency I did mention, 993 KHz. Hint: 72MHz divided by 72 is 1MHz but divided by 73 is... 986 KHz which is 0.68% away from 993 KHz.

author: IDEngineer
author_rank: Super Contributor
timestamp: May 24, 2019, 06:43:02 pm
content: Quote from: ogden on May 24, 2019, 06:35:18 pmYou're not getting it. Continuing with your 72MHz example, the 0.017Hz increment is aconstantwith 32 bits of divisor. I calculated and gave you the minimum frequency that would satisfy his 0.1% error. The error gets increasingly better at increasing frequencies. "Doing some math" again, the error at his bottom end of 1KHz would be 0.0017% and at his top end of 1MHz it would be 1.7^-08%.EDIT: It appears you need more explicit examples. Using your clock, 72MHz, with 32 bits of resolution means the LSb is 0.017Hz. Your target frequency is 993KHz. Divide that by the LSb and you get 59,234,757.3. This means you need a divisor of 59,234,757. Factor that number into two values that can be represented by 16 bit integers (range 0-65535) and there you are. There's an error of 0.3 LSb, which (if you "do the math" again) you'll discover is well within the 0.1% requested. In fact, an entire LSb is within the spec, which is exactly the point and why you can truncate the fractional part (or, if you want to be really detailed, do proper rounding).

author: bson
author_rank: Unknown
timestamp: May 24, 2019, 06:59:42 pm
content: Quote from: dpenev on May 20, 2019, 08:33:06 amFrom a 16MHz crystal? Really?

author: ogden
author_rank: Super Contributor
timestamp: May 24, 2019, 07:00:02 pm
content: Quote from: IDEngineer on May 24, 2019, 06:43:02 pmDivisor 59,234,757 to get what exactly??? 72000000/59234757 =1.2155 Hz. It is way off 993000 Hz I asked for.

author: NorthGuy
author_rank: Super Contributor
timestamp: May 24, 2019, 07:12:14 pm
content: Quote from: ogden on May 24, 2019, 05:39:53 pmIf only the frequency must be accurate, then many MCUs have NCO or DCO peripherals which can generate frequency very accurately, at the expense of higher jitter.

author: ogden
author_rank: Super Contributor
timestamp: May 24, 2019, 07:16:26 pm
content: Quote from: NorthGuy on May 24, 2019, 07:12:14 pmThose usually are kinda fractional frequency dividers, right? Yes, that's option indeed - in case jitter of +/- clock cycle (of divider) is acceptable.

author: IDEngineer
author_rank: Super Contributor
timestamp: May 24, 2019, 07:22:03 pm
content: Quote from: ogden on May 24, 2019, 07:00:02 pmOMG.I'll try one more time.Your 72MHz clock scaled by 32 bits yields an LSb of 0.017Hz. Your desired frequency of 993KHz means you need (993000 / 0.017Hz) LSb's. Do that equation and see what number you get. Then calculate the error of that "missing" 0.3 LSb.EDIT: I just know you're going to freak out over your answer being different than the number I gave. The reason is because my number comes from doing precise math, while in my equation above I rounded the value of the LSb. The exact equation is:(993000 / (72^06 / (2^32)))...which yields my earlier value. QED.

author: ogden
author_rank: Super Contributor
timestamp: May 24, 2019, 08:00:56 pm
content: Quote from: IDEngineer on May 24, 2019, 07:22:03 pmLOL. No horses were harmed in this most ridiculous calculation of frequency division, ever. Do you even know how timer peripheral or any other discrete frequency divider works? BTW I did provide hint for you, "Hint: 72MHz divided by 72 is 1MHz but divided by 73 is... 986 KHz which is 0.68% away from 993 KHz."

author: IDEngineer
author_rank: Super Contributor
timestamp: May 24, 2019, 08:03:04 pm
content: Anyone else want to try explaining prescalers to this guy? I've taken my turn in the barrel, ready to sit back and.

author: ogden
author_rank: Super Contributor
timestamp: May 25, 2019, 08:15:29 am
content: Quote from: IDEngineer on May 24, 2019, 08:03:04 pmPrescaler of stm32 timer is just clock divider. It candivideclock (and obviously frequency)by integer number. In frequency generation applications timer is integer divider as well. Your math of frequency dividers from alternate universe contains multiplierQuote from: ogden on May 24, 2019, 08:00:56 pmFact that you are able to write equation does not mean that timer is able to operate accordingly

author: mark03
author_rank: Frequent Contributor
timestamp: May 26, 2019, 12:36:18 am
content: Guys... (assuming you are both guys due to the apparent fragility of egos!)I think a bit of reflection will show that the frequency resolution of any MCU timer-based divider scheme is(In other words, @ogden is correct.)It's too bad there is so much noise in this thread because the underlying question is actually very interesting. I posed a similar question a while back (https://www.eevblog.com/forum/microcontrollers/square-wave-synthesis-with-high-frequency-resolution/msg897489/#msg897489). The boring answer is "just use a DDS and square-up the sinusoid" but there are applications where it would be really nice to do all of this inside an FPGA. I still intend to look into this further, although that project is clearly on the back burner---the thread is more than three years old!!I wish there were a nice technical write-up on the design of the Si5351, describing how the topology was chosen, how it works, the key technical challenges and how they were solved, etc.

author: NorthGuy
author_rank: Super Contributor
timestamp: May 26, 2019, 04:11:53 am
content: Quote from: ogden on May 24, 2019, 07:16:26 pmSince jitter is not specified, then obviously any jitter is acceptable. Otherwise, you need to have full specs first - jitter, rise/fall times, distortions - everything which is needed for the applications. Then you can think of the best method. It is silly to design something without specs, then rejects it because it doesn't meet unspecified specs.

author: Kleinstein
author_rank: Super Contributor
timestamp: May 26, 2019, 07:10:21 am
content: Quote from: ogden on May 24, 2019, 07:16:26 pmThe NCOs are more like DDS related, counting up the phase at a given rate and than directly give out the upper bit. Fractional dividers are similar, but updating the adder at a variable rate, set by the integer divider part. So the jitter is essentially the same, just a different control and implementation.

author: ogden
author_rank: Super Contributor
timestamp: May 28, 2019, 12:05:52 pm
content: Quote from: mark03 on May 26, 2019, 12:36:18 amSi5351 is nothing special. PLL+VCO with 600-900 Mhz range and dividers. Such clock generation approach is widely used since yr 1970 or so. Perhaps TI have more info in their documentation of clock IC'shttp://www.ti.com/product/CDCE913