Пролог

В математике есть такая тема как Диофантовы уравнения. В самом простом виде выглядят они так.

ax+by=d \qquad \qquad\qquad (1)

Тут одно уравнение и две неизвестные: x,y. При этом a, b, d - это известные константы.

На первый взгляд может показаться как бесполезная вещь для программирования Micro Controller Unit (MCU), но не тут-то было.

Когда программируешь микроконтроллер (MCU), то первое, что приходится делать - это конфигурировать тактирование процессорного ядра. Тактированием заправляет устройство с названием phase-locked loop (PLL/ФАПЧ). Это подсистема SoC(а).

И там надо подобрать три константы (натуральных числа): M, N и F. В микроконтроллере Artery, абстрактно изображая, эта электрическая цепь выглядит вот так. Умножители и делители частот.

По формуле (2)

\frac{(N\frac{F_{quartz}}{M})   }  {F} = F_{sys}    \qquad  \qquad  (2)

Вычисляется системная частота F_sys (sclk). Это уравнение (2) преобразуется в уравнение (3)

F_{quartz}   \frac{N}{M} -F_{sys}F     = 0   \qquad  \qquad  (3)

А уравнение (3), в свою очередь, это самое настоящее Диофантово уравнение! Да.. Тут F_quartz - это частота кварцевого резонатора, который задается схемотехникой электронной платы.
F_sys задается программистом для достижения желаемой производительности прошивки. Остаются целочисленные неизвестные N, M и F.

Далее накладываются ещё ограничения уже производителем микроконтроллера. Для Artery это

Переменная

Минимальное

Максимальное

M

1

15

N

31

500

FR (степени двойки)

1

32

Это ограничение даже прописано комментариями в исходных кодах на Cи, которые бесплатно предоставляет производитель Artery Tech.


/**
  *    config crm pll
  *                        pll_rcs_freq * pll_ns
  *         pll clock = --------------------------------
  *                           pll_ms * pll_fr_n
  *         attemtion:
  *                  31 <= pll_ns <= 500
  *                  1  <= pll_ms <= 15
  *
  *                       pll_rcs_freq
  *         2mhz <=  ---------------------- <= 16mhz
  *                          pll_ms
  *
  *                       pll_rcs_freq * pll_ns
  *         500mhz <=  -------------------------------- <= 1200mhz
  *                               pll_ms
  * @param  clock_source
  *         this parameter can be one of the following values:
  *         - CRM_PLL_SOURCE_HICK
  *         - CRM_PLL_SOURCE_HEXT
  * @param  pll_ns (31~500)
  * @param  pll_ms (1~15)
  * @param  pll_fr
  *         this parameter can be one of the following values:
  *         - CRM_PLL_FR_1
  *         - CRM_PLL_FR_2
  *         - CRM_PLL_FR_4
  *         - CRM_PLL_FR_8
  *         - CRM_PLL_FR_16
  *         - CRM_PLL_FR_32
  * @retval none
  */
void crm_pll_config(crm_pll_clock_source_type clock_source, 
                    uint16_t pll_ns, 
                    uint16_t pll_ms,
                    crm_pll_fr_type pll_fr)
  

Итак, постановка задачи:

Есть электронная плата с Artery MCU на борту. На PCB также припаян кварцевый резонатор c частотой 8 MHz и подключен к микроконтроллеру. Необходимо программно сконфигурировать PLL так чтобы базовая системная частота ядра стала ровно на 100 MHz.

Какими при этом должны быть коэффициенты PLL: N, M и RF?

Решение

По сути, задача свелась к тому чтобы решить Диофантово уравнение (4).

8000000 \frac{N}{M} -100000000F     = 0   \qquad  \qquad  (4)

Можно попробовать прибегнуть к помощи пресловутого Artificial intelligence (AI) на сайте Wolfram Alfa

Однако это не решение в частном виде. На практике же нужно именно численное решение, чтобы проинициализировать им аргументы функции crm_pll_config().

Однако нам повезло. В частности, тут область значений функции (2) достаточно маленькая, поэтому можно найти решение уравнения (3) обыкновенным перебором.

Для этого я написал свой простой численный решатель Диофантова уравнения для PLL прямо на Си.

uint64_t ipow(uint32_t base, uint32_t exponenta) {
	uint64_t ret = 1, i = 0;
    if(0 != exponenta) {
        for(i = 1; i <= exponenta; i++) {
            ret *= base;
        }
    }
    return ret;
}

typedef struct{
    uint32_t ms;
    uint32_t ns;
    uint32_t fr;
}PllArtety_t;

bool pll_calc_artery(uint32_t freq_xtal_hz, 
                     uint32_t freq_sys_hz, 
                     PllArtety_t* const PllArtety) {
    bool res = false;

    LOG_INFO(PLL_CALC, "FreqXtal:%u Hz,FreqSys:%u  Hz", 
             freq_xtal_hz, freq_sys_hz);
    cli_printf("{ [ (  {Xtal:%uHz} /M )*N ]/FR  }= Sys:%u Hz" CRLF, 
               freq_xtal_hz, freq_sys_hz);
    uint32_t solution_cnt = 0;
    if(PllArtety) {
        uint32_t m = 0;
        uint32_t temp_hz = 0;
        uint32_t temp_m_hz = 0;
        uint32_t cur_freq_sys_hz = 0;
        for(m = 1; m <= 15; m++) {
            uint32_t n = 0;
            temp_m_hz = freq_xtal_hz/m;
            if(2000000<=temp_m_hz) {
                if(temp_m_hz<=16000000){
                    for(n = 31; n <= 500; n++) {
                        uint32_t f = 0;
                        for(f = 0; f <= 5; f++) {
                            uint32_t fr = ipow(2, f);
                            cur_freq_sys_hz = ((n * freq_xtal_hz) / (m * fr));
                            if(freq_sys_hz == cur_freq_sys_hz) {
                                temp_hz = freq_xtal_hz * n / m;
                               /*condition from Artery New Clock Config*/
                                if(500000000 <= temp_hz) {
                                    if(temp_hz <= 1200000000) {
                                        solution_cnt++;
                                        cli_printf("%u: MS:%2u,NS:%3u,FR:%2u" CRLF,
                                                   solution_cnt, m, n, fr);
                                        PllArtety->ms = m;
                                        PllArtety->ns = n;
                                        PllArtety->fr = fr;
                                        res = true;
                                    }
                                }
                            }
                        }
                    }
            	}
            }
        }
    }
    if(res) {
        LOG_INFO(PLL_CALC, "SpotPllVals! %u Solutions",solution_cnt);
    } else {
        LOG_ERROR(PLL_CALC, "NoPllVals!");
    }
    return res;
}

Отладка

Вот так, в UART-CLI прошивки я исполнил команду обсчета PLL и получил аж 4 решения на выбор.

Вот эти решения:

1: MS:1, NS:100, FR:8
2: MS:2, NS:200, FR:8
3: MS:3, NS:300, FR:8
4: MS:4, NS:400, FR:8

Далее подставив четвёртое решение в утилиту проверки PLL я увидел, что конфиг валидный!

Успех!

Итоги

Как видите, программирование микроконтроллеров требует математической подготовки. А как Вы хотели?

Благодаря способности решать Диофантовы уравнения, Вы можете переконфигурировать частоту процессора далеко в run-time.

Можно, например, перейти в режим энергосбережения специально понизив частоту ядра. Или увеличить для ускорения расчета какой-то сложной математической процедуры.

Вот так..

Links/URLs

https://www.wolframalpha.com/input?i=8000000x-100000000y%3D0

http://latex.codecogs.com/eqneditor/editor.php

https://ru.wikipedia.org/wiki/Диофантово_уравнение

Комментарии (53)


  1. ExternalWayfarer
    28.03.2024 21:31
    +1

    Ничего не понятно, но очень интересно


    1. aabzel Автор
      28.03.2024 21:31
      +4

      Да что тут может быть не понятно?
      Надо настроить электрическую цепочку (PLL) которая выдает на выходе мегагерцовую частоту .

      Есть три ручки N M и F.

      Надо прописать нужные циферки (натуральные числа ) и всё заработает само.


      1. iqp
        28.03.2024 21:31

        Есть три ручки N M и F.

        Надо прописать нужные циферки (натуральные числа ) и всё заработает само.

        Ну так какие N, M и F у вас получились? Несколько страниц разговоров, куча кода, какие-то картинки а ответ-то где - три int N, M и F, эти самые нужные циферки ?


        1. aabzel Автор
          28.03.2024 21:31
          +1

          На скриншоте решения показаны.


          1. iqp
            28.03.2024 21:31
            +1

            На скриншоте решения показаны.

            Там много чего показано, вам уже в первом комменте сказали, что ничего не понятно. Напишите здесь в комментах эти три значения N, M и F , plz, всего три числа, ведь это ваш код и ваши скриншоты, извлечь оттуда эти три числа не должно быть слишком утомительно.


            1. iqp
              28.03.2024 21:31

              Вот эти решения:

              1: MS:1, NS:100, FR:8
              2: MS:2, NS:200, FR:8
              3: MS:3, NS:300, FR:8
              4: MS:4, NS:400, FR:8

              В условиях N M и F, а не MS, NS, FR.

              Ну ладно, просто здравый смысл без вольфрамов и диафантов интересуется, если у вас такое узкое окно перед постскэйлером F от 500 MHz до 1200 MHz, почти двойка, то в ответе почти всегда будет только одно значение F, очень изредка 2 значения F. Зачем нужно тащить внутрь самого внутреннего цикла многократное возведение в степень двойки? Просто посчитайте этот постскэйлер и забудьте про степени.

              Дальше, посчитали постскэйлер, запустили цикл от 1 до 15 по M. Зачем, о джизус, внутри этого цикла цикл от 31 до 500 по N? Просто выходную частоту 100 MHz умноженную уже известный постскэйлер F делите на (входную частоту, деленную на M). Будет возможно нецелый результат от деления, берете ближайшее целое для N.

              Заметьте, по этой логике вы получаете результат меньше чем за минуту вручную даже без калькулятора, не говоря уже о вольфрамах с диафантами.


  1. Yuri0128
    28.03.2024 21:31
    +4

    Все бы ничего, но зачем это все осчитывать в контроллере? Кварц ведь никто на ходу не перепаивает. Соответственно - все конфиги заранее известны и считаются 1 раз. Нафига козе баян?


    1. aabzel Автор
      28.03.2024 21:31
      +1

      Кварц ведь никто на ходу не перепаивает.

      Кварц не перепаивают, а вот PLL перенастроить и прописать в NVRAM новый конфиг - это запросто.


    1. Sun-ami
      28.03.2024 21:31
      +4

      Во-первых кварца в системе может и не быть - контроллер может работать от внутреннего RC-генератора, а для повышения точности системной частоты можно подстраивать PLL на ходу в зависимости от температуры, по обобщённому или индивидуальному профилю зависимости частоты от температуры, полученному в ходе калибровки.

      Во-вторых допустимая частота часто зависит от напряжения питания, а может быть ещё и от температуры контроллера. Если стоит задача выжать максимум производительности из микроконтроллера, запитанного напрямую от батареи - теоретически можно перестраивать PLL по мере разряда батареи и изменения температуры. Но на практике это сложнее, потому что кроме PLL часто нужно перестраивать и множество других делителей частоты в микроконтроллере.


      1. longclaps
        28.03.2024 21:31
        +5

        ...а для повышения точности системной частоты...

        Влепить RC-генератор, затем калибровать его к температуре (а есть датчик?) - ради чего? Чтобы сэкономить на кварце? Рука-лицо.


        1. AndronNSK
          28.03.2024 21:31
          +4

          Зато на хабре статью можно будет написать.


        1. jar_ohty
          28.03.2024 21:31
          +5

          Иногда кварц просто не предусмотрен: у многих малоногих МК вход и выход под кварц не разварены на ноги корпуса. Иногда надо, чтобы генератор запускался предельно быстро, за несколько тактов, а это может только RC. Иногда - надо обеспечить живучесть при ударах и перегрузках, с чем у кварцев плохо.


          1. NickDoom
            28.03.2024 21:31
            +1

            Абсолютно так. У меня где-то валяется недорисованный проект кухонного таймера на кучу каналов, в основе которого — тинька без кварца, и вот там я закладывал регулярное измерение температуры (кухня же!) и коррекцию того, сколько тактов в секунде.

            Там вообще всё предельно ужато было по ногам, чтобы показывать минуты и обрабатывать достаточно удобные кнопки.


        1. Sun-ami
          28.03.2024 21:31
          +2

          Например ради компактности. Установка кварца требует площадь на плате, сравнимую с площадью микроконтроллеров в самых компактных корпусах WLCSP18(1,8х2,1 мм) или WLCSP25 (2,3х2,5 мм). А ещё кварцевый генератор больше потребляет и требует использования 2 выводов микроконтроллера, что может в некоторых случаях потребовать взять больший корпус. А датчик температуры встроен во многие микроконтроллеры, например в большинство STM32.


    1. Sun-ami
      28.03.2024 21:31
      +1

      Могут ещё быть случаи, когда нужно настроить частоту тактирования периферии на заранее неизвестное значение, причём делители частоты периферии не позволяют сделать это с нужной точностью. Например, если нужно принять данные по UART на частоте, близкой к предельной. Часто в этом случае делитель частоты для UART позволяет установить только некоторые фиксированные бодрейты, зато с помощью системного PLL можно даже выполнить сканирование диапазона бодрейтов для автоподбора.


    1. poulch
      28.03.2024 21:31
      +1

      кроме кварца это может быть стабильный clock от кварцевого генератора которым можно управлять,а еще и через плис прошедший....


  1. JustCat
    28.03.2024 21:31
    +4

    Я бы ещё добавил про то, что частота после каждой отдельной операции умножения/деления в ФАПЧ должна оставаться в некоторой области допустимых значений. Что собственно в конце и упоминается как "проверка на валидность". Можно сразу добавить её в решатель, чтобы после перебора выбрасывать не валидные значения. Те которые математически верны, но ФАПЧ не сможет реализовать.


  1. vk6677
    28.03.2024 21:31
    +3

    Утилита Artery сама не считает делители ? Если просто вписать 100 МГц и нажать "ввод".


    1. aabzel Автор
      28.03.2024 21:31
      +3

      Утилита Artery сама не считает делители ?

      Утилита Artery-то считает.
      Дело в том, что у нас на работе нельзя устанавливать ПО из интернетов.

      Также нельзя прописывать переменную Path, открывать диспетчер задач и прочие ограничения на локальных PC.

      Вот и остается самому писать калькуляторы для настройки PLL, аналоговых фильтров, делителей напряжений и прочего, и прочего.


      1. NutsUnderline
        28.03.2024 21:31
        +4

        это прямо таки тема для отдельного обсуждения


      1. AndronNSK
        28.03.2024 21:31
        +1

        Интернеты из дома на дискетках флешках приносите?

        Я так делал в 00х...


        1. aabzel Автор
          28.03.2024 21:31

          Ну принес я дистрибутив.
          А установить не могу так как надо админский логин и пароль набрать. А у меня его нет.


  1. HEXFFFFFFFF
    28.03.2024 21:31
    +13

    Это вообще такая частность и такая мелоч на которую квалифицированный программист даже не должен обращать внимания. Если у программиста даже подбор множителей и делителей тактовый частоты вызвывет "зависания" вплоть до написания статей то как же он дальше продвинется? В 99% случаев эти цифры подбираются руками за минуту, в оставшемся 1% пишется скрипт перебора на любом языке за 5 минут. Лезть в дебри математики тут излишнее усложнение и пустая трата времени.


    1. Radisto
      28.03.2024 21:31
      +4

      пишется скрипт перебора на любом языке за 5 минут

      Ну, он его и написал. Просто на этом же контроллере, но тут на чем хочет, на том и считает. Хотя, справедливости ради, при определенном соотношении коэффициентов тупой перебор "в лоб" может занять очень много времени даже на довольно мощной системе, поэтому в таких случаях лучше все же заморочиться с математикой. Диафантовы уравнения - такая штука, коварная. Конкретно для этой задачи это возможно и из пушки по воробьям, тут подводных камней в области математики не видать, но если в общем говорить...


    1. me21
      28.03.2024 21:31
      +2

      Да какой там перебор, за пару минут на глаз делители подбираются и по формуле проверяется результат.


    1. NickDoom
      28.03.2024 21:31
      +1

      Руками за минуту — это и есть математика, только отработанная до автоматизма :)


    1. aabzel Автор
      28.03.2024 21:31
      +1

      Большинство программистов мк с которыми я обшался( у каждого по 7+лет опыта) на вопрос какая у вас сейчас частота ядра? Разводили руками.


      1. ktod
        28.03.2024 21:31
        +2

        Это как так "разводили руками"? От частоты ядра, так или иначе, зависит чуть более чем все.


        1. aabzel Автор
          28.03.2024 21:31

          Это как так "разводили руками"?

          Они не знали на какой частоте у них микроконтроллер тактируется.


        1. iqp
          28.03.2024 21:31
          +1

          От частоты ядра, так или иначе, зависит чуть более чем все.

          Плюсанул, но хотелось бы отметить, что чуть более чем всё - не совсем корректно как по мне, - или просто всё, или чуть менее, чем всё. Я понимаю, что сленг с лурки или откуда-то еще, но тем не менее.


        1. NickDoom
          28.03.2024 21:31
          +1

          О Ардуино, Ардуино, надо быть тупым для всех,

          Для Ардуино, Ардуино, есть одна награда — смерть :-D

          Да, я знаю, что у него есть своя экологическая ниша. Это система для пивоваров, которые автоматизируют домашнюю пивоварню, не становясь ради этого программистами МК. Собственно, оно придумано, чтобы не становиться программистом МК и человек, работающий с ним, не является программистом МК.


        1. Zuy
          28.03.2024 21:31

          Это очень зависит от типа микроконтроллера и решаемых задач. Бывает, что от частоты работы ядра в общем-то ничего и не зависит особо если в предел производительности не упереться.


          1. aabzel Автор
            28.03.2024 21:31

             Бывает, что от частоты работы ядра в общем-то ничего и не зависит особо

            Что это за задачи такие?
            Без знания частоты ядра даже HeartBeat LED не настроить.


            1. Zuy
              28.03.2024 21:31
              +1

              Ну например если системный фреймворк в компании делает отдельная команда и разработчики логики уже получают микроконтроллер на котором круттится таже FreeRTOS. Возьмите к примеру SDK который c ESP32 идет. Там в общем никакой разницы нет ядро на 180 или 200MHz работает. Примерно так же во многих компаниях делается. Небольшая команда запускает собственный фреймворк на новом MCU, а дальше команда работающая над целевым устройством это использует.
              Ну и потом, есть системы где частота ядра вообще динамически меняется в процессе работы. Завязываться на нее смысла вообще нет.


          1. aabzel Автор
            28.03.2024 21:31

            Если цель прошивки опрашивать кнопку и по нажатию выполнить функцию, то да. Частота не важна.

            Прошивка - мина.


            1. Zuy
              28.03.2024 21:31
              +1

              Как раз таки если цель прошивки опрашивать кнопку и мигать диодом то да частота ядра может и важна.
              А если у вас команда разработчиков и каждая группа работает над своей частью функционала, то да, многие могут и не знать какая-там частота у ядра. Многие даже не знают сколько их там тех ядер.


              1. aabzel Автор
                28.03.2024 21:31
                +1

                 команда разработчиков и каждая группа работает над своей частью функционала, то да, многие могут и не знать какая-там частота у ядра. Многие даже не знают сколько их там тех ядер.


                Да ладно уж, мелочиться...

                --Многие даже не знают названия микроконтроллера,
                --не имеют ни малейшего представления о схемотехнике электронной платы,
                --не догадываются какой компилятор
                --никогда не слышали слов "система сборки"
                --не догадываются о существовании bin и hex файлов, переменных окружения, препроцессора, консолей, datasheet(ов), NVRAM, конечных автоматов, модульных тестов и прочего

                Из embedded инструментов-примочек на столе только бубен.

                И тем не менее такие тоже являются как бы программистами разработчиками. Причем я видел таких "художников-абстракционистов" даже яндексе.


  1. PeeWeee
    28.03.2024 21:31
    +4

    На третьем ходу выяснилось, что гроссмейстер играет восемнадцать испанских партий. В остальных двенадцати черные применили хотя и устаревшую, но довольно верную защиту Филидора. Если б Остап узнал, что он играет такие мудреные партии и сталкивается с такой испытанной защитой, он крайне бы удивился.


  1. NutsUnderline
    28.03.2024 21:31
    +1

    Схемы формирования частот нонче навороченные пошли, на Atmega можно было обойтись калькулятором, а то и в уме две цифры поделить.

    Что то подобное сейчас уже засовывают в system.c для микроконтроллеров. Хотя более правильно, на мой взгляд, было бы просто пощелкать опциями в визуальном конфигураторе, раз он уж есть, и лучше понять как все это работает, а не мистический черный ящик с настройками.


  1. Colorbit
    28.03.2024 21:31
    +1

    В Wolfram Mathematica можно решить в пару строк:

    sol = Solve[8000000 n/m - 100000000 f == 0, {n, m, f}, 
       Integers] //. {C[1] -> c1, C[2] -> c2}
    Multicolumn[
     TableView[#, Headers -> {{с1, c2, m, n, f}}, Alignment -> Center] & /@
       Table[{c1, c2, m, n, f} //. sol[[1]], {c1, 1, 10, 1},
    {c2, 1, 10,1}],2]
    Изображения
    Аналитическое решение
    Аналитическое решение
    Результаты расчета
    Результаты расчета


    1. iqp
      28.03.2024 21:31

      Если я правильно понял, F по условиям задачи "степени двойки" от 1 до 32 То есть 1,2,4,8,16,32. А у вас F четные от 2 до 20


      1. Colorbit
        28.03.2024 21:31
        +1

        Полученное решение данных уравнений более полное. Все "степени двойки" четные и содержаться в полученном ряду.


        1. iqp
          28.03.2024 21:31

          Полученное решение данных уравнений более полное. Все "степени двойки" четные и содержаться в полученном ряду.

          Здесь постскэйлер - делитель на 2 или 4 или 8 и т.д. Не надо более полное решение, оно аппаратно нереализуемо. Оставьте только те значения, которые имеют отношение к условиям задачи.


  1. smart_alex
    28.03.2024 21:31
    +3

    Подобный стиль подачи материала — это лучший способ навсегда отбить желание даже близко подходить к программированию микроконтроллеров.


    1. aabzel Автор
      28.03.2024 21:31

      Тогда Вам надо вот этот текст.

      Вы в Самом Деле Хотите Стать Программистом Микроконтроллеров? https://habr.com/ru/articles/668368/

      Как раз недавно пару параграфов и картинок добавил.


      1. smart_alex
        28.03.2024 21:31
        +2

        Вы в Самом Деле Хотите Стать Программистом Микроконтроллеров?

        Уважаемый @aabzel , я автор десятка дистрибутивов ОС для микроконтроллеров (Mega, Due, 101, M0, ESP8266, ESP32 и т.д.) и автор десятков проектов на них.

        А вот если бы я начал знакомство с программированием микроконтролеров с подобных статей, то на этом бы всё и закончилось.

        (а против математики я ничего не имею)


    1. aabzel Автор
      28.03.2024 21:31
      +2

      Напрасно Вы так. @smart_alex На самом деле в программировании микроконтроллеров целая куча всяческой математики, как школьной так и ВУЗ(овской).

      Вот подборка текстов в доказательство:

      --Зачем Программисту Микроконтроллеров Численные Методы?
      https://habr.com/ru/articles/700394/

      --Зачем Программисту Микроконтроллеров Математическая Статистика? (или так ли хороши UWB трансиверы?)
      https://habr.com/ru/articles/712616/

      --Зачем программисту микроконтроллеров тригонометрия? (или Обзор Усилителя Звука из Apple AirTag)

      https://habr.com/ru/articles/767386/

      --Зачем программисту микроконтроллеров комплексные числа (или обзор MEMS микрофона MP23DB01HPTR)
      https://habr.com/ru/articles/765896/

      --Комбинаторика нужна для модульных тестов
      https://habr.com/ru/articles/762142/
      https://habr.com/ru/articles/709374/

      --Грамматики Хомского
      https://habr.com/ru/articles/757122/

      --Математическая индукция
      Сканирование шины RS485
      https://habr.com/ru/articles/752292/

      --Спец разделы мат. анализа: Ряды
      Ряд Фурье как Фильтр Нижних Частот
      https://habr.com/ru/articles/748334/
      https://habr.com/ru/articles/687640/

      --Бинарные деревья поиска
      NVRAM Поверх off-chip SPI-NOR Flash
      https://habr.com/ru/articles/732442/

      --Высший пилотаж алгебры
      Вывод формулы для двустороннего определения дальности между UWB трансиверами
      https://habr.com/ru/articles/723594/

      --Интегралы
      Теория управления шаговым двигателем (или как вертеть PTZ камеру)
      https://habr.com/ru/articles/709500/

      --Сферическая Геометрия Римана
      https://habr.com/ru/articles/649163/
      https://habr.com/ru/articles/648247/

      И это только то с чем я столкнулся. Может ещё что-то надо из математики.


    1. NutsUnderline
      28.03.2024 21:31

      язык математики вообще очень даже не для всех, но для сложных задач так или иначе придется запеть и эту песню. к тому же в школе и ВУЗах этому учат (ну надеюсь) .

      Можно найти немало серьезных проектов в ардуино с огромными наборами формул. авторы этих проектов возможно даже и не замарачивались как там внутри таймер тикает, и кстати - на какой частоте, они решают свои задачи.. и это работает


      1. aabzel Автор
        28.03.2024 21:31

        Можно найти немало серьезных проектов в ардуино с огромными наборами формул

        Есть примеры?


        1. NutsUnderline
          28.03.2024 21:31

          я сейчас уже не вспомню где я видел я прям совсем лютую портянку, но как пример это проекты связанные с gps и pid регулированием. Примерно как SoftRF, 360gts или здесь на хабре было управление протезом якобы взглядом (на самом деле акселерометры).

          Да даже возмем обычный бародатчик с 6 коэффициентами поправки. Там немаленькие формулы чуть ли не с плавающей запятой. Вполне даже можно абстрагирироваться от их физического смысла, но даже чисто математику перевести в целочисленное будет способен явно не каждый программист МК, хотя нарисовать по результату красивый график у кого то получается и эффективнее и красивше.


    1. iqp
      28.03.2024 21:31

      Подобный стиль подачи материала — это лучший способ навсегда отбить желание даже близко подходить к программированию микроконтроллеров.

      Выпад в сторону автора посильнее моего, за который я словил минус в карму. Прикольно, так карма 92, однако. Статьи - много по модулям с мк, ага "раскуриваем трубку Гейгера-Мюллера" - это после которой я сразу побежал в гараж искать трубку Гейгера, должна была где-то там быть с советских времен, слава богу не нашел, умеет автор "раскуриваем трубку" зарядить энтузиазмом.

      Своего рода эталон упомянутая статья для тех, кто пишет статьи по аппаратным средствам, и для тех, кто начинает и для тех, кто уже собаку съел на этом деле, так сказать. Хорошо структурирована, логичная последовательность блоков текста, содержательные названия блоков, сам текст по существу и на впечатляющем художественном уровне, не каждому дано, прямая противоположность статьи, под которой эти комменты.


  1. iShrimp
    28.03.2024 21:31
    +2

    Автор привёл простейший пример, который легко решается в уме. Но стоит добавить пару ограничений (что для нас более важно - стабильная частота или низкое энергопотребление?), и задача превращается в задачу оптимизации.

    А что если требуемую частоту нельзя получить точно, а можно только приближенно? Попробуйте найти наиболее точное приближение для частоты 87,654321 МГц. (Подсказка: цепные дроби).


    1. iqp
      28.03.2024 21:31

      Но стоит добавить пару ограничений (что для нас более важно - стабильная частота или низкое энергопотребление?)

      Еще оптимизацию по фазовому шуму можно добавить, не совсем то же самое, что стабильная частота.