SysInfo for Arduino
- Войдите на сайт для отправки комментариев
SysInfo for Arduino
Пришли ко мне с Алиэкспресс в одной посылке несколько Arduino Pro Mini 5В+16МГц и 3,3В+8МГц. Внешне абсолютно одинаковы, различаются лишь непонятными буковками на кварце и стабилизаторе напряжения.
Проблему с их определением, разумеется, я решил: подал 9В (от Кроны) на вход RAW и померил напряжение на VCC (получил 3,3 и 5 вольт).
Позже задался вопросом: можно ли с помощью самой Ардуины померить внешнее напряжение и частоту. Оказалось можно.
Для определения напряжения питания измеряется внутренний источник опорного напряжения 1,1В при внешнем опорном напряжении.
Для вычисления частоты запускается пустой цикл (на 10 тысяч значений) и измеряется время его работы.
Когда-то давным-давно на PC была лишь DOS, а для тестирования компьютера удобно было использовать Norton Utilities. В этот комплект входила утилита SysInfo, которая выдавала системную информацию о компьютере.
Вот и возникла идея: совместными усилиями сделать аналогичный скетч для Ардуино. По-моему он был бы более полезен, чем простой Blink.
Версия 1.00
Вместе с реальной частотой выводится программно задаваемая F_CPU.
Добавил тестирование пинов.
Версия 1.01
Какое-то немного странное тестирование.
Если контроллер сконфигурирован правильно (установка фьюзов и пр.), то результаты измерений, возможно, правильно отражают реальное положение дел. Если же нет - что мы получим, неизвестно. А.т.к. перепрошивка контроллера - стандартная процедура, вероятность того, что все сконфигурировано правильно, существенно ниже, чем было бы в случае с ПК.
По поводу частоты - есть еще один способ измерения, гораздо более быстрый: определяем, с какой дискретностью возвращается значение micros(): если 4, значит, 16 МГц, если 8 - 8 МГц.
Ну и наиболее интересная информация - тип процессора (объемы различных видов памяти, наличие дополнительной внешней памяти и пр.) вообще выпущены из внимания. Не говоря уже о характеристиках подключенной периферии.
Ну и наиболее интересная информация - тип процессора (объемы различных видов памяти, наличие дополнительной внешней памяти и пр.) вообще выпущены из внимания.
Вот именно. На форуме есть более крутые специалисты по процессорам и памяти чем я, поэтому и было предложено (в посте 0) совместно расширить данный скетч.
По поводу частоты - есть еще один способ измерения, гораздо более быстрый: определяем, с какой дискретностью возвращается значение micros(): если 4, значит, 16 МГц, если 8 - 8 МГц.
Если andriano приложит код, реализующий данный алгоритм, то добавим его в скетч.
Видите ли, arduinec, я предложил идею, основываясь исключительно на документации: https://www.arduino.cc/en/Reference/Micros
Идея, как мне кажется, изложена достаточно понятно, чтобы ее мог воплотить любой желающий.
Но если мы говорим о создании конкретного кода, то я к такому повороту не готов ввиду полного отсутствия у меня 8 МГц кристаллов - не на чем проверить.
Кстати, я тут подумал - действительно, Ваша идея не лишена рационального зерна. Хотя бы с точки зрения отработки решений при отсутствии подходящего "железа".
Посмотрел исходный код micros():
Там используется макрос:
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
F_CPU задаётся программно (при прошивке загрузчика) и нам известна, поэтому дискретность micros() нам ничего не даёт.
Значит, проще всего вывести в Serial значение F_CPU и не парить себе мозг.
Т.к. если эта константа определена не для нашего камня, то и результат измерения выполнения будет точно такой неправильный.
Другими словами, оба метода измерения дают один и тот же результат.
Значит, проще всего вывести в Serial значение F_CPU и не парить себе мозг.
F_CPU в сериал выводится вместе с рассчитанной частотой. Хотелось бы получить реальную частоту, не зависящую от F_CPU. Может специалисты по таймерам что-нибудь подскажут.
Провёл эксперимент. На макетной плате у меня стоит Atmega328p в DIP-корпусе с прошивкой Arduino Uno. Не меняя прошивку, поменял у неё кварц с 16 на 8 МГц. Для связи на COM-порте пришлось поменять скорость на 4800.
SysInfo выдала: Frequency = 16 MHz (F_CPU = 16000000).
Получается, что Ардуина сама не может определить свою частоту, а лишь руководствуется программно задаваемой F_CPU.
Навскидку - частоту реально посчитать таймером, если запустить Т2 в асинхронном режиме с внешним кварцем.
На STM32 видел реализацию просто на таймере, без доптактирования.
Навскидку - частоту реально посчитать таймером, если запустить Т2 в асинхронном режиме с внешним кварцем.
Я полагаю, что все таймеры и счётчики в Ардуине зависимы от F_CPU. Если только внешний таймер подключать или часы реального времени, но это уже совсем другая история...
Аппаратные таймеры атмеги не зависят от F_CPU. Они зависят от реальной тактовой частоты и настроек регистров.
чет не догоню, если бы была иная частота, то в сериал вы бы видели мусор. если вы видите читаемый текст для платы на 16Мгц, то там действительно 16.
есть идея как измерить частоту. с помощью собаки, как известно она тактируется 1 Мгц, надо завести любой другой таймер, разрешить собаку (подобрав предделители для обоих) и разрешить прерывание от собаки. Ну и методом расчетов, зная предделители обеих высчитать частоту. если дать команду сброса, то должно выйти на продолжение программы без сброса МК.
Получается, что Ардуина сама не может определить свою частоту, а лишь руководствуется программно задаваемой F_CPU.
а, должна уметь?
нужно подключать внешний девайс к поциенту и проводить замер нужных параметров.
а, если желается SysInfo, то достаточно считать сигнатуру чипа и фьюзы
Аппаратные таймеры атмеги не зависят от F_CPU. Они зависят от реальной тактовой частоты и настроек регистров.
А откуда таймеры узнают с какой частотой они работают?
чет не догоню, если бы была иная частота, то в сериал вы бы видели мусор. если вы видите читаемый текст для платы на 16Мгц, то там действительно 16.
В посте 9 указано, что скорость сериал-порта была уменьшена до 4800 (при 9600 был мусор).
есть идея как измерить частоту. с помощью собаки, как известно она тактируется 1 Мгц
А откуда она берёт частоту 1 МГц, если частота кварца неизвестна?
а, если желается SysInfo, то достаточно считать сигнатуру чипа и фьюзы
Если Клапауций 232 приложит код, реализующий данную идею, то добавим его в скетч.
Если Клапауций 232 приложит код, реализующий данную идею, то добавим его в скетч.
внешним программатором фьюзы и сигнатура читается.
А откуда она берёт частоту 1 МГц, если частота кварца неизвестна?
На то он и сторожевой таймер, у него собственный рц генератор. Кстати, крапаль обманул, у 328-й собака работает от 128кГц.
А откуда таймеры узнают с какой частотой они работают?
А они и не знают, с какой частотой они работают. Им не нужно знать - они просто тикают с той тактовой частотой, которая поступает на вход предделителя таймера, а затем на сам таймер.
Под фразой "Аппаратные таймеры атмеги не зависят от F_CPU" я имел в виду то, что в не зависимости от того, какое значение будет записано в F_CPU, частота тиканья таймера от этого не поменяется. Частота тиканья таймера может поменяться только в двух случаях: 1) Изменится тактовая частота, поступающая на вход предделителя таймера, 2) Изменится сам предделитель таймера (через настройки регистров).
То есть: если настроить таймер; включить прерывание от таймера; написать обработчик прерывания, в котором дергать ножку светодиода - то светодиод будет моргать всегда одинаково, в не зависимости от значения F_CPU.
внешним программатором фьюзы и сигнатура читается.
Про внешний программатор я знаю. Надеялся, что Клапауций 232 знает какой-нибудь хитрый способ прочитать фьюзы в скетче.
То есть: если настроить таймер; включить прерывание от таймера; написать обработчик прерывания, в котором дергать ножку светодиода - то светодиод будет моргать всегда одинаково, в не зависимости от значения F_CPU.
Остался вопрос: как с помощью таймеров определить частоту кварца Ардуины.
Функции Wiring типа micros() и delay() зависят от F_CPU - может это как-то использовать (ломаю голову).
я же вроде отвечал, с помощью сторожевого таймера и одного из обычных.
Остался вопрос: как с помощью таймеров определить частоту кварца Ардуины.
Функции Wiring типа micros() и delay() зависят от F_CPU - может это как-то использовать (ломаю голову).
считать что-то таймером и пулять в сериал - последнее максимальное значение должно быть искомым числом пропорциональным частоте.
я же вроде отвечал, с помощью сторожевого таймера и одного из обычных.
Если __Alexander приложит код, реализующий данный способ определения частоты, то добавим его в скетч.
Мыслм вслух (по поводу обычных таймеров, с watchdog пока не экспериментировал):
Исходные параметры: кварц 16 МГц и F_CPU=16000000. Запускаем таймер на подсчёт частоты кварца. Делаем с помощью фунций Wiring задержку на 10 микросекунд и проверяем таймер. Он сосчитает до 160.
Меняем кварц на 8 МГц не меняя F_CPU=16000000. Таймер будет тикать в два раза медленнее, но функции Wiring не знают, что кварц поменялся. Поэтому задержка растянется до 20 мкс, и таймер сосчитает опять до 160.
Если arduinec расскажет, как часто он приобретает неопознанные девайсы...
Если __Alexander приложит код, реализующий данный способ определения частоты, то добавим его в скетч.
А авторские права? ))))))
Тут смотри в чем загвоздка, это надо делать первоначально и вычислить результат для всех взможных кварцев, потом уже, когда цифры будут известны, то настраивать уарт на 9600 при любом кварце, т.е. надо ввести таблицу.
зы. И еще, надо сначала выключить все таймеры, которые по умолчанию включает иде, и еще не факт что сериал заработает, надо будет работать напрямую с реистрами уарта.
Если arduinec расскажет, как часто он приобретает неопознанные девайсы...
В нулевом посте написано, что девайсы мне удалось опознать. А уже потом появилась идея сделать совместными усилиями информационно-тестирующий скетч для Ардуино.
Кстати, код так никто и не выложил, в том числе и Клапауций 232.
Кстати, код так никто и не выложил, в том числе и Клапауций 232.
мои рекомендации не предусматривают прошивки контроллера каким либо кодом
разрешаю считывать фьюзы и сигнатуру с голого контроллера.
Тут смотри в чем загвоздка, это надо делать первоначально и вычислить результат для всех взможных кварцев, потом уже, когда цифры будут известны, то настраивать уарт на 9600 при любом кварце, т.е. надо ввести таблицу.
зы. И еще, надо сначала выключить все таймеры, которые по умолчанию включает иде, и еще не факт что сериал заработает, надо будет работать напрямую с реистрами уарта.
Я думал проще: запустить таймер watchdog и за определённое время посчитать количество импульсов кварца. Я сам с watchdog не работал, полез пока в документацию по нему.
Я думал проще: запустить таймер watchdog и за определённое время посчитать количество импульсов кварца. Я сам с watchdog не работал, полез пока в документацию по нему.
Ну по сути так и есть, запускаете ватчдог на нужное время и считатете сколько за это время протикал другой таймер и вычисляете. Я вроде так и сказал. Сложность в том, чтобы вывести в уарт читабельную информацию, надо сначала вычислить частоту, но ардуино иде такая кака, что если выключить все таймеры, то сериал ваш работать не будет. надо с нуля его инициализировать и выдавать информацию. Усекаете? У вас терминал работает на 9600, на разных кварцах у вас будет выводится всякий бред.
У вас терминал работает на 9600, на разных кварцах у вас будет выводится всякий бред.
как вариант писать в EEPROM в лупе и считывать при инициализации - после первой перезагрузки будет актуальное значение.
только не очень часто писать. :D
ну, ок. предположим, мы определились с методами и написали код, который нужно залить в плату...
а, как? если
У вас терминал работает на 9600, на разных кварцах у вас будет выводится всякий бред.
Та не, зачем? Собака работет на одной и той же частоте (с поправкой на температуру и вольтаж), просто посидеть с полчасика и переписать значения для всех "стандартных частот" и всех "стандартных" скоростей уарта. Просто сделать табличку или просто сравнением:
if (TCNT1 > 56 && TCNT1 < 61) то частота кварца 16Мгц и UBRRL0 = 103.
if (TCNT1 > 25 && TCNT1 < 31) то частота кварца 8Мгц и UBRRL0 = 51.
И тогда вывод в уарт будет всегда читабельным.
И тогда вывод в уарт будет всегда читабельным.
ок. и, как это туда воткнуть, если мы можем узнать скорость порта только после прошивки, а для прошивки нужно знать скорость порта.
это какая-то рекурсия.
ок. и, как это туда воткнуть, если мы можем узнать скорость порта только после прошивки, а для прошивки нужно знать скорость порта.
это какая-то рекурсия.
А за бутлодырь речи вроде как и не было, ясен пень, что заменив кварц на другой бут работать не будет.
А за бутлодырь речи вроде как и не было, ясен пень, что заменив кварц на другой бут работать не будет.
тогда вообще не интересно - залить блинк с интервалом в 1 секунду и медитировать на результат.
тогда вообще не интересно - залить блинк с интервалом в 1 секунду и медитировать на результат.
Работал лет десят назад с бутом, который по длине стартового импульса настраивал скорость автоматом, в проге надо было просто указать порт.
А с другой стороны, очень даже полезный способ отладки, особенно на расстоянии, перегрузился от неожиданности МК по собаке, а в прерывании от нее сохранили в эпром номер учаска кода... удобная штука.
Сложность в том, чтобы вывести в уарт читабельную информацию, надо сначала вычислить частоту, но ардуино иде такая кака, что если выключить все таймеры, то сериал ваш работать не будет. надо с нуля его инициализировать и выдавать информацию. Усекаете? У вас терминал работает на 9600, на разных кварцах у вас будет выводится всякий бред.
Если мы будем знать частоту кварца, то сможем и любые тайминги нужным образом выставить, в том числе и Serial.begin(). Кроме того, информацию можно выводить и на дисплей.
Если мы будем знать частоту кварца,
...то тему можно закрывать.
Последний раз для особых оптимистов. Ардуино ИДЕ настраивает переферию как ей захочется, так отследить частоту невозможно, т.к. в прерывании одного из таймеров вызываются куча нахер ненужных функций. Работу таймеров надо запрещать. Но какого-то юха, запрет таймеров влияет на работу вашего Serial.begin(). Я хз. Может я не по русски пишу, но надо вместо Serial.begin() работать напрямую с регистрами, которые написаны в datasheet на МК. Может так понятнее станет.
http://dropmefiles.com/sYsZ5
а ну скажи число в терминале при 16мгц кварце.
http://dropmefiles.com/sYsZ5
а ну скажи число в терминале при 16мгц кварце.
кто скажи и у кого возникнет желание что-то скачать с помойки?
кто скажи и у кого возникнет желание что-то скачать с помойки?
Та мне как-то насрать. Ну если что, то подскажи где крутые пацаны выкладывают файлики?
Та мне как-то насрать. Ну если что, то подскажи где крутые пацаны выкладывают файлики?
не важно где - важно описание и желательна прямая ссылка.
ну, как самый популярный www.dropbox.com
где крутые пацаны выкладывают файлики?
На yandex.ru вместе с почтовым ящиком бесплатно 10 Гб для хранения файлов дают.
Про внешний программатор я знаю. Надеялся, что Клапауций 232 знает какой-нибудь хитрый способ прочитать фьюзы в скетче.
Для этого есть штатные дуиновские функции. Правда они нигде не описаны.. :) Кстати ещё в тему - есть способ, который без внешних девайсов позволит узнать тактовую частоту. Правда весьма примерно. Собака тактируется от своего независимого RC-генератора, можно запустить один из таймеров , на время, отсчитанное собакой, и посмотреть сколько насчитал таймер. По этим цифрам расситать частоту. Я даже скетч такой писал, правда назначение было другим -расчёт точности собаки. Но удобнее всего ткнуть осциллом в кварц и измерить. Если кварца нет, значит частота 8 или 1 Мгц :), можно прочесть фузы и узнать. Или ещё изящный вариант -включить фуз CKOUT и тактовая появиться на ноге PB0.
Добавил вывод фьюзов.
Версия 1.02