Занимательная математика

Продолжаю веселиться с микроконтроллерами STC, и опять попалась интересная задачка. В общем, частота на которой работает мк определяется хост компьютером по 8ми 16-битным числам, которые передает хосту контроллер в инфопакете. MCU измеряет какую-то часть временной диаграммы последовательности двух байт {0x7f, 0x7f} и передает 8 измерений хосту в инфопакете вместе с другими настройками. Из них надо получить частоту кварца/RC осциллятора в мегагерцах. Получилась хорошая задачка решающаяся небольшим количеством школьной математики.

Время передачи нескольких (n) бит идущих с известным баудрейтом измеряется 8 раз
У таймера который их меряет есть прескейлер, делящий частоту мк в сколько раз.
Надо найти частоту мк.
Давайте теперь запилим небольшое уравнение с парой параметров

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

Где T — период с которым считает счетчик. Теперь, учтем наличие прескейлера и вспомним как связаны частота и период:

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

Из (1) и (2) имеем:

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

Здесь Fmcu — искомая частота камня. Выглядит аппетитно, едем дальше и приводим это к божескому виду.

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

Или

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

Осталось определить два параметра: n и prescaler.
Можно на это, конечно забить, обозвать альфа и вычислить экспериментально,
Но это «не тру, не метально круто и не замогильно ужастно» (с). И даст ошибку округления. Но по счастью я заметил, что при кварце на 12M значение счетчика является временем 7 битного высокого уровня (лог. анализатор — хорошая штука!)
=> n = 7 (что кстати было очевидно с самого начала)
А раскурив даташит узнаем, что прескейлер таймера может быть либо 1 либо 12.
Есть еще прескейлер системного клока, но как видно из вышесказанного — он не используется.
=> prescaler = 12.

Отсюда получаем частоту, и переводим в мегагерцы. И оно дает правдоподобные значения, хотя и дает некоторое отклонение от того, что говорит официальная софтина.
Потому, я решил перепроверить:

Официальная тула сказала: 12.03912 Mhz
Логический анализатор выдал:

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

Преобразуем в флоат, берем среднее

float avg = ( (float) (0x16c * 7) + (float) 0x16d )/ 8.0;
(Все помнят зачем я добавил +1 ? )

Это дает нам 364.125000, запишем теперь наше уравнение и найдем n
Получилось, что n = 6.968482746247234, что достаточно близко к 7. Отклонение где-то 0.03. Потому я тупо забил 6.97 как коэффицент, чтобы поведение было как у STC ISP tool, но тут надо понимать, что ошибку нам дают:

  • Отклонение баудрейта от заданного, вызванного тем, как работает баудрейт прескейлер в преобразователе с usb на уарт.
  • Погрешность кварца, который тактирует наш преобразователь (сверхточный кварц туда никто в здравом уме ставить не будет)
  • Погрешность которую может вызвать сам дизайн преобразователя, задержки на мосфетах и т.п.

Можно конечно спаять для таких измерений донгл с точным кристаллом, откалибровать как следует и выяснить коэффицент сверхточно и только для этого сверхточного донгла…
Но оно вообще надо?

Моя реализация вышеуказанного матана тихонечко лежит на шитхабе

 

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.