Аппаратная ревизия платы с помощью делителя напряжения и АЦП

Введение

При разработке электронных устройств, как правило, возникает несколько последовательных версий (ревизий/выпусков) одной и той же печатной платы, по сути это инженерные образцы. Кроме этого на рынок также могут выпускаться различные версии устройства ( РЕВ1, РЕВ2, РЕВ3...), которые должны поддерживаться.

Тестер светодиодов с экраном ч.1 🧨 OLED и питанием LiIon 18650 (проектирование, схема, плата)
⭐Светодиодный тестер ч.2 (запуск преобразователя и тесты на светодиодах)

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

Примеры:
– изменился уровень управления чем-либо (стал обратным);
– в обновленной добавились новые датчики/управляемые части;
– изменилась ножка управления (была GPIO2, а стала GPIO43).

Схема электрическая принципиальная

Простым решением для аппаратного определения ревизии является делитель напряжения на резисторах, который устанавливает определенный уровень, интерпретируемый как определенная ревизия.

Конечно, не нужно делать шаг слишком маленький, поэтому считаю разбиение на 16 частей (шаг 256) вполне приемлемым для надежного считывания 12-ти разрядным АЦП и достаточного количества возможных ревизий (по опыту).

Плата

Не плате займет много места, особенно если использовать два резистора типоразмера 0402 (1.00 мм х 0.50 мм):

Код

Вот такой пример можно использовать с 12-ти разрядным АЦП и 17 возможными ревизиями.

#include <stdio.h> #include <stdint.h> /* HW Revision configuration BEGIN */ #define HW_REV_NUM 16 #define HW_REV_ADC_MAX 4095.0 /* 12-bit ADC ((2^12)-1) */ #define HW_REV_STEP (HW_REV_ADC_MAX/HW_REV_NUM) /* HW Revision configuration END */ int round_number(double n); uint8_t getHwRev (uint16_t adc_val); int main () { /* Enter value 0-4095 */ uint8_t hwrev = getHwRev (4000); printf("BOARD REVISION: %d\n", hwrev); /* e.g. in case of 12-bit ADC: REV1 - 0; REV2 - 256; REV3 - 512; REV4 - 768 REV5 - 1024; REV6 - 1280; REV7 - 1536 ;REV8 - 1792 REV9 - 2048; REV10 - 2304; REV11 - 2560; REV12 - 2816 REV13 - 3072; REV14 - 3328; REV15 - 3584; REV16 - 3840; REV17 - 4095 */ } /** * @brief Identify board revision using ADC value * @note Should be configurated using defines * @retval 1-255; 0 - error */ uint8_t getHwRev (uint16_t adc_val) { uint8_t hw_rev = 0; hw_rev = round_number((adc_val/HW_REV_STEP)) + 1; return hw_rev; } int round_number(double n){ int trunc = (int) n; double diff = n - (double) trunc; if(diff < 0.5){ return trunc; } else { return trunc+1; } }

Пример 1

Пример 2

Пример 3

Выводы

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

При использовании МК с 12-ти разрядным АЦП (STM32, ESP32) и при разбиении диапазона на 256 получаем 17 ревизий, чего должно хватить для большинства проектов.

Все, что нужно сделать, это считать сырое значение с АЦП (0-4095) и запульнуть его в функцию getHwRev, она возвратит ревизию в виде числа.

Если плата питается от химического источника тока (ХИТа) подключайте делитель через управляемый источник питания, чтобы не потреблять энергию во время простоя (также нужно не забывать его включать перед считыванием).

341
RSS
Нет комментариев. Ваш будет первым!
Загрузка...