Комментарии 73
если есть хотя бы один вход (в идеале с триггером шмиддта) и питание CPU стабилизировано можно сделать такую схему:
вход переключается на "выход" и выдаёт "логический 0" и тем самым разряжает конденсатор к нему подключённый (разумеется требуется токоограничивающий резистор для этого).
пауза
вход переключается на "вход" и ожидается когда уровень сигнала дорастёт до логической "1", одновременно замеряя интервал времени от переключения, до появления единицы
затем вход снова переключается на "выход" и выдаёт "логический 0"
Далее по времени и известным R и C можно посчитать U.
Здесь, правда, нюанс: требуется точный C и чтобы убрать требования к точности C нужно два, а не один входа-выхода, но как метод "без АЦП" - вполне рабочая история.
Мы когда-то подобным способом термодатчики опрашивали/температуры вычисляли.
насколько неинтересно когда у процессора 128 ног и их можно подключить ко всей периферии
и насколько интересной становится жизнь, когда ног всего 8, две из которых - питание!
У мелких процессоров - свои конкурсы, у больших - свои
Несколько питаний (vcc, gnd) на SoC заводится с разных сторон, не с целью удобства, или еще чего.. А чтобы целесообразно "равномерно" распределить токи по всему кристаллу процессора.. как собственно и микроконтроллера..
Не маловажную роль, в данном случае, играет физическая архитектура, на уровне кристалла..
Не столько для распределения токов, сколько для подключения к этим местам на кристалле внешних фильтрующих конденсаторов. Поэтому на каждой паре таких выводов должно быть по конденсатору.
Именно для равномерного распределения токов по кресталу!!! И как выше говорил, тут не мало важную роль играет архитектура.. А конденсаторы, это правило.. Хоть выводов 2 (vcc, gnd), хоть выводов 50 (для питания).. А вообще, спорить не буду.. Не хочу разводить халивар.. Спасибо!
О каких распределениях тока идёт речь, когда потребление всего контроллера Ф1-серии 10...20 мА, а ног питания - 5...10 пар? Распределение только у больших процессоров, с амперным потреблением, где ноги питания идут полем из десятков штук, а не попарно.
Не маловажную роль, в данном случае, играет физическая архитектура, на уровне кристалла..
Думаю так было удобно проектировать топологию.. Где удобнее было подвести питание с разных сторон блоков.. А не реализовывать проброс питания внутри кристалла.. Думаю так, могу ошибаться..
Возникает другой вопрос: контроллеры/процессоры, множеством выводов питания.. эти выводы, они прозваниваются между собой? С не нулевым сопротивлением?.. Например vcc1 —> vcc2.. если с нулевым, очевидно внутри кристалла это одна цепь.. Если же присутствует сопротивления (к примеру порядка сотен ом).. Очевидно что целесообразно было подвести питание к блокам, с разных сторон..
Очевидно для gnd цепей, ситуация аналогичная.. И крайнее.. Насколько помню.. Именно к некоторым процессорам, может подвалиться питание разного уровня.. К примеру 5v, 3v3..
У STM32 сопротивления между ногами питания и земли менее 0,5 Ом. В даташите на рекомендуемой схеме подключения параллельно стоят 5 конденсаторов ёмкостью 0,1 мкф, что как бы намекает - по конденсатору на каждую пару ног.
Скажите это stm32g серии мк
У больших контроллеров свои приколы - в частности, если на 144-ногом STM32H7 подключить езернет, SDRAM и дисплей, то свободной остаётся только одна ножка АЦП.
Только вот конкретно эта "мало ног" у ATtiny 85 - это илюзия экономии и эффективности. Он стоит 200р, в то время как модуль esp12 с кучей ног стоит 100р.
А у кошки четыре ноги, вход выход, vcc и gnd
Еще интересней когда памяти МК всего 8кБ или вообще 1кБ)
а ещё 6-ногие есть, аттини и пик12
а у вас питание контроллера напрямую связано с аккумулятором? Без промежуточных стабилизаторов? Я когда-то в подобной ситуации, но со стабилизатором между VCC и аккумом, использовал временное переключение режима пина с выхода на вход, и подключением pull-up резистора к аккумулятору. Конечно точность невысокая, но для анализа заряда хватало.
подключением pull-up резистора к аккумулятору
Но в этом случае измеряемое напряжение выходит за границы диапазона АЦП. Значит напряжение нужно как-то поделить, но чтобы это незначительно повлияло на разряд аккумулятора.
Делить резисторами большого номинала нельзя, из-за низкого входного сопротивления АЦП. Для всяких решений с коммутацией нужны дополнительные выводы.
Кроме того может возникнуть проблема с фантомным питанием.
я не могу точно вам ответить, так как эту схему делал более 15 лет назад, но что помню из основного, делителя не было, понижал напряжение (вроде бы 4 или 5 элементов по 1.2В) при помощи нескольких последовательных диодов и одного pullup резистора. Измеряемое напряжение брал после ключа питания.
А что у вас за ацп с низким входным сопротивлением? Но какое бы оно ни было, влияет не оно, а токи утечки. Как правило резисторы в несколько мегаомм нормально работают. Для домашних самоделок сойдёт. В крайнем случае со стороны МК добавляется конденсатор. Для литиевых банок делал ключик на двух мосфетах (p+n) - он практически не вносит погрешности. Диапазон работы ключа можно расширить с помощью стабилитрона и резистора, но ни разу не пригодилось. Обычно если напряжение от 5 вольт и выше, то это не батарейка, и экономить микроамперы нет смысла.
А смысл что-то ещё мутить, батарейка 4.2в до 3.0в разряжается, стабилизатор отожрет ещё полтора вольта и получается нужно повышать с потерями, а все это при батарейном питании не очень. Китайские клоны ардуинки от 5 до 2,7в хавают, идеально для питания от лития. Но питание контролировать надо. Индикаторы на светодиодах и компараторе неточные, меньше 3.7 и уже говорят в морг. Вольтметры точнее, но как и первые жрут довольно много, от 20ма.
Кстати для Ардуино есть библиотека, которая именно по такой методике работает. Вот только LG8F328 немного не такой😥
Смысл есть, контроллер от 3.3в потребляет значительно меньший ток чем от 4.2. Так что применение даже линейного стабилизатора дает заметный выигрыш по потреблению. Есть дешевые LDO стабилизаторы типа xc6206, которые без проблем позволят разрядить литиевый аккумулятор почти полностью. Экономия во время разряда на напряжениях выше 3.5В будет больше, чем остаточная емкость.
У меня питание VCC идет от АКБ напрямую без стабилизатора (ну разве что конденсатор сглаживающий электролитический и цепь защиты при зарядке). Да и к тому же, ради одной такой функции ставить целый стабилизатор, как по мне, слишком жирно
Да еще и сам стабилизатор кушает питание (а если еще и делитель ставить, как много кто делает, так вообще...), а хотелось бы собрать автономное устройство. По-существу, этот способ можно было бы описать "как выжать из МК максимум без дополнительной обвязки"
если есть хотя бы один вход (в идеале с триггером шмиддта) и питание CPU стабилизировано можно сделать такую схему:
вход переключается на "выход" и выдаёт "логический 0" и тем самым разряжает конденсатор к нему подключённый (разумеется требуется токоограничивающий резистор для этого).
пауза
вход переключается на "вход" и ожидается когда уровень сигнала дорастёт до логической "1", одновременно замеряя интервал времени от переключения, до появления единицы
затем вход снова переключается на "выход" и выдаёт "логический 0"
Далее по времени и известным R и C можно посчитать U.
Здесь, правда, нюанс: требуется точный C и чтобы убрать требования к точности C нужно два, а не один входа-выхода, но как метод "без АЦП" - вполне рабочая история.
Мы когда-то подобным способом термодатчики опрашивали/температуры вычисляли.
Да, тоже читал о таком способе - и он довольно хороший в плане энергопотребления и компактности схемы. Как попробую, напишу статью и об этом. Но в данном случае придется думать о принципиальной схеме заранее))
Это не будет работать для данной задачи. Совсем.
Так как уровень логической единицы напрямую зависит от напряжения питания и время заряда до этого уровня будет постоянным
нет будет
смысл в том, что заряжать конденсатор резистором от входного напряжения, разумеется
в том сообщении на которое я отвечал, обсуждался pull-up резистор на Vbatt
Видимо имеется в виду, что данный метод показывает напряжение в процентах от Vcc. Если Vbatt=Vcc то будет показывать всё время одно и то же значение.
Плюс точность метода очень низкая (я обычно использую в случаях когда погрешность приемслема +/- 2 раза. Но обычно всё же использую прерывание от встроенного компаратора заведенного другим концом на встроенный же опорник. Тогда можно уложиться в 10% и нет такой жесткой привязки к Vcc.
Если идея уберечь аккумулятор от опасного разряда( около 3V ) то, возможно, внешняя схема с компаратором каким-нибудь была-бы уместнее, как мне кажется.
Так это ж штатная процедура, описанная в datasheet и с примером в refnotes, нет?
Можете поделиться ссылками? Лично я это "изобретал" лет 15 назад и тогда это было неочевидно (и в ДШ тоже не было) , сейчас, конечно, легко гуглится.
Лично примера я в datasheet не нашел, но в целом вы правы, просто обычно народ ставит делитель или стабилизатор, и хотелось бы показать еще один (не самый очевидный) способ.
Без стабилизатора сложно обойтись, если к микроконтроллеру что-то подключено, что требует этого самого стабильного напряжения, например, датчик какой-нибудь. А дальше сложно без делителя. А если ещё необходимо сверхнизкое потребление то схема измерения дорастает до 2х транзисторов и ~4 резисторов
Так что сама идея хорошая, но работает очень в ограниченных случаях
Чтобы измерить собственное напряжение питания у тиньки 85 нужно:
-включить ацп, режим однократного замера, предделитель высьавить в 128
-установить vcc как опорное напряжение
-включить ИОН 1.1в на вход ацп
-считать показания, перевести в вольты
Никакие доп. выводы не нужны.
Примерно так:
#define REFERENCE 1.10
float getADC( void ) {
ADCSRA = (0x01 << ADEN) | (0x01 << ADPS2) | (0x01 << ADPS1) | (0x01 << ADPS0);
ADMUX = (0x01 << MUX3) | (0x01 << MUX2);
delayms(2);
ADCSRA |= (0x01 << ADSC);
while (ADCSRA & (0x01 << ADSC));
return (REFERENCE * 1024.0) / ( (uint16_t)ADCL | ((uint16_t)ADCH << 8) );
}
Причем это, вместе с куском кода есть прямо в даташите - собственно, в чем проблема?
Ну или я неверно понял задачу...
О сколько нам открытий чудных приносит даташита текст...
Внутренний ИОН для того и придуман, чтобы не нужно было "подавать стабильное и заранее известное напряжение".
рубрика вредные советы онлайн?)))
внимательно прочитайте документацию, заметьте, что точность встроенного источника 20%, и измерения основанные на нем будут показывать погоду на Марсе

еще раз перечитайте, посмотрите графики ухода этого напряжения, еще раз подумайте и никогда не используйте...)))
ps: очень с ним намучился, пока не перешел на микроконтроллеры с 1% ИОН
точность встроенного источника 20%,
с точки зрения инженерной точности - нормально же

Вообще-то погрешность на вашем скриншоте 10%.
Спросим DeepSeek.
Напиши программу на си измерения напряжения питания микроконтроллера ATtiny85
DeepSeek отвечает:
Программа измерения напряжения питания ATtiny85 на Си
Вот программа для измерения напряжения питания ATtiny85 с использованием внутреннего источника опорного напряжения 1.1В:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
// Настройка UART для вывода результатов (если нужен вывод на компьютер)
#define BAUD 9600
#define UBRR_VALUE ((F_CPU / 16 / BAUD) - 1)
void uart_init() {
UBRRH = (uint8_t)(UBRR_VALUE >> 8);
UBRRL = (uint8_t)UBRR_VALUE;
UCSRB = (1 << TXEN);
UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
}
void uart_putc(char c) {
while (!(UCSRA & (1 << UDRE)));
UDR = c;
}
void uart_puts(const char* str) {
while (*str) {
uart_putc(*str++);
}
}
void uart_put_hex(uint8_t value) {
const char hex_digits[] = "0123456789ABCDEF";
uart_putc(hex_digits[value >> 4]);
uart_putc(hex_digits[value & 0x0F]);
}
void uart_put_uint16(uint16_t value) {
char buffer[6];
uint8_t i = 0;
do {
buffer[i++] = '0' + (value % 10);
value /= 10;
} while (value > 0);
while (i > 0) {
uart_putc(buffer[--i]);
}
}
// Функция инициализации АЦП
void adc_init() {
ADMUX = (1 << MUX3) | (1 << MUX2); // Выбираем VCC как вход (1.1V reference)
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // Включить АЦП, предделитель 64
}
// Функция чтения АЦП
uint16_t adc_read() {
ADCSRA |= (1 << ADSC); // Начать преобразование
while (ADCSRA & (1 << ADSC)); // Ждем окончания преобразования
return ADC;
}
int main(void) {
// Инициализация
uart_init();
adc_init();
// Разрешаем прерывания
sei();
uart_puts("ATtiny85 VCC measurement\r\n");
while (1) {
// Читаем значение АЦП
uint16_t adc_value = adc_read();
// Рассчитываем напряжение питания в милливольтах
// VCC = (1.1V * 1024) / ADC_value
uint32_t vcc_mv = (1126UL * 1024UL) / adc_value; // 1.1V * 1024 = 1126 (корректировка)
// Выводим результат
uart_puts("VCC: ");
uart_put_uint16(vcc_mv);
uart_puts(" mV\r\n");
// Задержка между измерениями
_delay_ms(1000);
}
return 0;
}
Объяснение работы программы:
Программа использует внутренний источник опорного напряжения 1.1В для измерения напряжения питания VCC.
Алгоритм измерения:
Источником измерения выбирается внутренний источник 1.1В
Входом АЦП выбирается VCC через внутренний делитель
Измеренное значение АЦП позволяет вычислить фактическое напряжение питания
Формула расчета:
VCC = (1.1V * 1024) / ADC_value
Программа выводит результат в милливольтах через UART (если подключен).
Важные замечания:
Для работы UART вам понадобится подключение к компьютеру через USB-UART преобразователь.
Если вывод через UART не нужен, можно заменить вывод на мигание светодиодом или другие индикаторы.
В ATtiny85 нет аппаратного UART, поэтому используется программная реализация (библиотека SoftwareSerial или аналогичная).
Для более точных измерений может потребоваться калибровка внутреннего источника 1.1В.
Не забудьте установить правильную частоту F_CPU в настройках проекта (должна соответствовать частоте вашего микроконтроллера).
------------------------------
Спросим DeepSeek.
С какой погрешностью будет измерено напряжение питания по этой программе
DeepSeek отвечает:
Точность измерения напряжения питания ATtiny85 по предложенной программе зависит от нескольких факторов. Давайте разберём основные источники погрешности и оценим общую точность:
Основные источники погрешности:
Точность внутреннего ИОН 1.1В:
Типичная погрешность: ±10% (по datasheet)
После калибровки можно достичь: ±1-2%
Это главный источник погрешности
Разрешение АЦП:
10-битный АЦП (1024 уровня)
Теоретическая погрешность квантования: ±0.1% (1/1024)
На практике из-за шумов: ±2-3 младших бита (±0.3%)
Температурная стабильность:
ИОН имеет температурный дрейф: ±0.5-1%/°C
При изменении температуры на 10°C: дополнительно ±5-10%
Напряжение насыщения АЦП:
АЦП не может измерить напряжение вблизи VCC
Добавляет небольшую погрешность (±0.5%)
Точность вычислений:
Использование целочисленной арифметики
Погрешность округления: ±0.1-0.2%
Оценка общей погрешности:
Без калибровки:
Худший случай: до ±12%
Типичный случай: ±5-8%
С калибровкой ИОН:
Худший случай: ±3-4%
Типичный случай: ±1-2%
С калибровкой и температурной компенсацией:
Можно достичь: ±1% в стабильных условиях
Как улучшить точность:
Калибровка ИОН:
// Добавьте калибровочное значение (уникально для каждого чипа) #define VREF_CALIBRATION 1126 // Пример: 1.100В * 1024 = 1126.4
Усреднение измерений:
uint16_t adc_read_avg(uint8_t samples) { uint32_t sum = 0; for(uint8_t i = 0; i < samples; i++) { sum += adc_read(); _delay_ms(1); } return sum / samples; }
Температурная компенсация (если измеряете температуру).
Использование внешнего точного ИОН (если требуется высокая точность).
Практический пример:
При VCC = 5.00В:
Без калибровки: показания 4.6-5.4В (±8%)
С калибровкой: показания 4.95-5.05В (±1%)
Вывод: предложенный метод хорош для мониторинга питания, но если нужна высокая точность (лучше ±1%), потребуется калибровка каждого конкретного экземпляра микроконтроллера.
--------------------
Рад был помочь! Если в будущем понадобится доработать программу под конкретные задачи (например, увеличить точность, добавить вывод на дисплей или реализовать пороговые сигналы), обращайтесь.
Краткий итог по измерению VCC на ATtiny85:
Простота: Метод не требует внешних компонентов
Точность: ±1-2% с калибровкой, ±5-10% без нее
Оптимизации: Усреднение, калибровка, температурная стабильность
Успешных проектов! 😊
P.S. Для самых критичных измерений можно рассмотреть внешние АЦП (например, ADS1115) или прецизионные ИОН.
в этом и есть коварство этого ужасного ИОН, вам кажется, что с ним можно работать, но по мере работы с ним выясняется, что это нестабильный источник напряжения где-то около 1.1В. (насколько я понимаю, он используется для определения порогов напряжения включения микросхемы, а бонусом его завели на опору ADC)
еще раз подумайте и никогда не используйте...)))
Такая точность вполне пойдет для показометра заряда аккумулятора, как у автора поста. Или, как у меня в фонарике, для ограничения максимальной яркости по мере расхода батареи.
в этом и есть вредность совета, завтра молодой инженер зайдет на хабр и прочитает эту статью, и разработает схему на этом ИОН, потому что так рекомендовали на хабре. В итоге схема в серии работать не будет. Это я не вам в комментариях пишу, а этому инженеру, которым был я...
ps: простой и эффективный способ использовать качественные линейные стабилизаторы, в ответственных применениях прицезионные ИОН.
завтра молодой инженер зайдет на хабр и прочитает эту статью, и разработает схему на этом ИОН, потому что так рекомендовали на хабре
На заборе много чего рекомендуют пишут. Если этот ваш инженер такой впечатлительный, он может и в когтеточечный бизнес удариться.
еще раз поясню, что пишу не для вас, а для тех, кто прочитает статью и захочет использовать этот нестабильный ИОН в своих проектах, это вредный совет, которому более 10 лет и инженеры постоянно наступают на эти грабли и все равно приходят к тому, чтобы использовать внешние источники опорного напряжения, никакие калибровки не помогут.
pss: в современных реалиях attiny25/85 не перспективные морально устаревшие контроллеры, ценник на который сильно завышен, есть более удачные со стабильным ИОН, точным стабильным встроенным генератором, большей памятью за цену меньше бакса. Много кодил под tiny, когда перешел на современные - с облегчением выдохнул...
ps: а когтеточный бизнес чем плох?) вот та статья была хороша))
Он вполне стабильный и точный для измерения заряда батареи. Но нужна калибровка и чтение даташита обязательно
Согласен с вами, тем более что можно сделать усреднение, например, по 30 значениям, и перевести так называемый заряд в процентах в "палки" от 1 до 4. Этого более чем хватит для примерного уровня, чтобы +- понимать заряд. Лично я сделал его отображение кратным 5, и меня это вполне устраивает. Устройство работает более месяца, и какая-то там погрешность мне неважна
для тех, кто прочитает статью и захочет использовать этот нестабильный ИОН в своих проектах
Для них придумали даташиты. Инженер он же обучен читать документацию, правда? (ц) принцесса Падме.
А какой смысл в 21 веке в новых разработках использовать tiny 85?
Эта проблема удобно решена в контроллерах STM32 в которых есть зашитое с завода калибровочное значение внутреннего опорного напряжения VREFINT_CAL при точном известном Vdd (+- 10 mV). Считав его и измерив АЦП свое опорное получаем весьма точное напряжение питания МК.
Вполне себе элегантное решение! Возьму на заметку. Жаль только, что опорник калибровать нужно прямо на каждом экземпляре. Сталкивался с подобной ситуацией, на той же тиньке, правда с выводами было чуть проще, и я задолбался все 25 устройств калибровать. Правда потом выяснилось, что виной плывущей калибровки был плохо отмытый флюс, который остался под корпусом контроллера после сборщиков. Отмыл всё ещё раз в уз и спирту, всё полетело
Вариант из каких-то примеров применения atmel. Без индивидуальной калибровки каждого чипа не годится, у atmega опорное напряжение с точностью +/-10%. Калибровку можно автоматизировать, подав точное напряжение питания например 4.00V и нажав какую-то кнопку, но это костыль. Лучше использовать внешний ИОН, даже TL431 и то будет лучше.
физика нужна 😁
ChatGPT выдаёт то же самое решение с первого промпта, только без ошибок и с более элегантным и надежным кодом. https://chatgpt.com/share/681d1ad9-ba0c-8000-bf4e-0a180a3047e2
Соль этой статьи в том, что нужно догадаться о том, что подобное решение ВОЗМОЖНО. Не прочитав эту статью Вы бы не задали бы эту задачу chatgpt и у Вас бы не получилось "с первого промпта": просто этого промпта бы не было.
Лично мое мнение: да, можно скормить какой-нибудь код нейросети, но, как по мне, это мышление школьника, поскольку машина пишет код уж точно не лучше образованного инженера, и так вы ничему не научитесь сами. Программировать на профессиональном уровне СТМ или ПЛИС та еще задача, посмотрите сами вакансии.
К слову, ардуино можно тоже отнести к этому - подключаем библиотеку, пишем loop() и все готово, а как оно том ядро и фьюзы выставляет, это не важно. Только вот чтобы понять архитектуру МК этого недостаточно.
Это решение из какой-то appnotes Atmel, когда она ещё была Atmel, а ардуино ещё не было. ChatGPT с первого промпта выдаёт решение потому что это стандартный способ измерить питание проца и исходников на эту тему в сети навалом.
Ну есть даташит, остальное достаточно очевидно.
"Статью" (на самом деле нейросетевой мусор) можно сократить до одного предложения.
Не думаю, что какая-то сетка поможет вам написать код под МК PIC (а они все еще существуют) или под ALTERA. Есть очень сложные задачи в производстве, где задачи "поморгать светодиодом" на 32кБ микроконтроллере явно не будет. Поэтому я лично вообще нейросеть не смотрю - оно никак не развивает навыки мышления
Измерение собственного напряжения питания микроконтроллера