Some fun calculus

Fun with STC goes on. This time it came down to a nice&shiny maths task. So. The Host computer determines the frequency the MCU is running at using 8 16-bit numbers transmitted in the infopacket. These are the raw timer values of 8 samples, that measure some part of a timing diagram. What part of 2 bytes being transmitted ( {0x7f, 0x7f} ) is measured – we do not yet know. From these we have to determine the MCU frequency. Fun calculus under teh break.

The time to transmit n bits идущих at known baudrate is measured 8 times
That timer that does teh heavylifting has a prescaler. The value that’s set up we don’t yet know.
We have to determine the MCU Frecuency (Fmcu).
Let’s throw up a few equations .

  T * average\_counter\_value = \frac{n}{baudrate} \hfill (1)

Where T – is the period of the counter clock. Now, let’s take prescaler into account and remember how frequency and period depends on each other:

  T = \frac{1}{F/prescaler} = \frac{prescaler}{F} \hfill (2)

From (1) and (2) we have:

  \frac{prescaler}{Fmcu} = \frac{n}{baudrate * average\_counter\_value}

Looks delicios, let’s tidy it up:

  Fmcu = \frac{baudrate * average\_counter\_value * prescaler}{ n } Hz


  Fmcu = \frac{baudrate * average\_counter\_value * prescaler}{ n * 1000000} MHz

We’re still missing 2 parameters: n and prescaler.
We can just call these alpha, and determine experimentally, but that’s no fun and will likely add some rounding error.
Luckily I notied, that at 12M crystal the 16-bit values are the time of 7-bit HIGH level in the diagram above. (Say thanks for Saleae for making those nice things!)
=> n = 7 (Well, that was kind-of obvious)
And giving a quick look at the datasheet we have a prescaler of 1 or 12 avaliable for timer0. Done!
=> prescaler = 12.
We also have the system clock prescaler, but that is not used.
testing that I got a lifelike values, but a deviation from wht STC ISP Tool says. So I deciced to double check things. Prescaler is not likely wrong, so let’s find ‘n’

Official tool says: 12.03912 Mhz
Logical analyzer sniffs:

0x16b 0x16b 0x16b 0x16b 0x16b 0x16b 0x16b 0x16c

Let’s convert to float, take the average:

float avg = ( (float) (0x16c * 7) + (float) 0x16d )/ 8.0;
(Everyone remembers why I added 1 to each sample here ? )

That gives 364.125000 average, so let’s find n.
Saving a few moments – n = 6.968482746247234, that’s close enough to 7. So I just used 6.97 as a coefficient, to match the behavior of STC ISP tool,but we should understand here, that quite a few things make up the error here.:

  • The actual baudrate deviation from what we expect, due to the prescaler in the usb<-->uart dongle
  • The deviation of the crystal oscillator that clocks the usb<-->uart dongle from the nominal value (No one is gonna put an extra precise one there)
  • Extra deviation due to the design of the dongle, out board design and other factors we forgot to mention (if any)

If you are out for an ultra-precise frequency measurement, you’ll have to throw up a usb<-->uart dongl with an extra precise crystal, calibrate delays on all baudrates for your dongle… Anybody insane enough to do so?
So, my implementation of the above maths can be found at my github page


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.