STM8L Мониторинг питающего напряжения без использования АЦП

Микроконтроллеры STM8L предназначены, прежде всего, для устройств с батарейным питанием. Поэтому часто бывает нужно следить за степенью разряда батарей. Это можно делать при помощи АЦП. Если АЦП полностью занят выполнением основной задачи, то мониторинг питания можно поручить системе Programmable voltage detector (PVD).

Обычно PVD используют для определения порога малого заряда батареи, после чего предпринимают определённые действия, пока питание не пропало совсем.
Мы же будем использовать PVD для отображения текущего заряда батареи на светодиодной шкале в диапазоне 1,7 …. 3,05 V.

Для работы мы возьмём плату STM8L-Discovery с микроконтроллером STM8L152C6T6.
LCD индикатор аккуратно вынимаем и откладываем в сторону.

Для подключения светодиодной шкалы нам понадобится весь порт B. Вместо светодиодной шкалы можно просто взять 8 светодиодов. Катодами мы подключим их к общему проводу, а анодами к выходам PB0 … PB7 порта B через резисторы по 2КОм.

К выводам 3,3V и GND на плате Discovery подпаяем колодку для подключения внешнего источника питания. (внешний источник питания пока не подключаем!) Вот, собственно, и все приготовления.



Программа написана в IAR без использования стандартных библиотек:

Будем тестировать PVD на максимальной частоте 16 МГц;
Настраиваем порт B на выход;
Переключаем порт B в режим push-pull
Запускаем PVD установкой бита PVDE в регистре PWR_CSR1:


CLK_CKDIVR = 0x00; 
PB_DDR = 0xFF;        
PB_CR1 = 0xFF;
PWR_CSR1_bit.PVDE = 1;


Внутри бесконечного цикла начинаем измерение напряжения питания:


while (1)
{    
     uint8_t Port_B = 0x01;  // 0 бит порта B всегда в "1" - показывает питание
     
     for (uint8_t n=0; n<=6; n++) 
     {       
       PWR_CSR1_bit.PLS = n;  // последовательно устанавливаем пороги  PVD       
       Delay(4);      // задержка > 50 uS перед чтением  PWR_CSR1_bit.PVDOF
                      // флага готовности, к сожалению, нет
       if ( PWR_CSR1_bit.PVDOF == 0 )  // порог ещё не достигнут
       {          
         Port_B |= (1<<(n+1));   // записываем "1" в соответствующие пороги +1         
       }       
       else break; // когда порог превышен, прерываем цикл 
     } 
  PB_ODR = Port_B;  // загораются светодиоды, соответствующие порогу
}    


Прежде всего, запишем «1» в 0 бит порта B. Когда напряжение питания поднимется до 1,7 V микроконтроллер заработает и светодиод в младшем разряде загорится.

Теперь в цикле будем последовательно поднимать порог от 0 до 6 в регистре PWR_CSR1 бит PLS. Пороги соответствуют следующим напряжениям:



Если бит PVDOF в регистре PWR_CSR1 равен «0», это значит что напряжение питания выше порога и в соответствующий бит порта B пишется «1». Когда порог окажется выше напряжения питания бит PVDOF в регистре PWR_CSR1 станет равен «1» и цикл прервётся. Таким образом, включенные биты порта B покажут текущее напряжение питания. Перед тем, как читать бит PVDOF нужна задержка > 50 uS, чтобы порог успел установиться. Флага готовности, к сожалению, нет. Задержка > 50 uS установлена опытным путём.
Чтобы не тормозить программу, задержку можно организовать на таймере. Полный текст программы для IAR во вложении.

Прошиваем программу — должны загореться 7 светодиодов, что соответствует уровню 2,85… 3,05V. Такое напряжение приходит на микроконтроллер при питании от USB. Остальные биты в регистре PWR_CSR1, отвечающие за прерывания, мы в этом примере не трогаем.

Отсоединяем шнур USB и подключаем внешний источник питания. Плавно увеличиваем напряжение от 0 до 3,3V. На фото хорошо видно, как работает схема:

  • ?
  • 13 марта 2019, 00:09
  • CreLis
  • 1
Файлы в топике: PVD_STM8_L.zip

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

RSS свернуть / развернуть
Это наверное будет звучать как «нашел к чему придраться», но мне больно смотреть на кусок кода с совершенно хаотичными отступами. Хотелось бы хотя бы в статьях видеть нормальное форматирование кода
0
Подровнял. Спасибо!
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.