Измерение потребления МК -  B7-35 (после ЦЛИТа, спец. настройка и калибровка)

Atmega328P

Минимальное потребление в режеме PowerSave при запущенном TIMER2 в асинхронном режиме (часы с внешним кварцем)  -  ~1.1 мкА

WATCHDOG  -  потребляет ~5,2 мкА

BodLevel (Контроль питания)  -  ~60 мкА

Запущенный АЦП  -  ~1.45 mА

Atmega328P
Исходник

'===============================================================================
  $map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "m328pdef.dat"       ' Используемый контроллер
  $crystal = 1000000       ' 1 МГц    , кварц для стабильной работы USART во всём диапазоне скоростей передачи и приёма
  $framesize = 32       'размер области используемой и необходимой для преобразований
  $hwstack = 40       ' Размер аппаратного стека
  $swstack = 16       ' Размер программного стека

  Config Portb = Output : Reset Portb

  Dim Val_byte As Byte

'===============================================================================
'                  Узнаём причину сброса МК
'===============================================================================
  Dim Причина_сброса_мк As Byte
  Dim Регистр_причины_сброса As Byte

  !sts {Регистр_причины_сброса} , R0
  Причина_сброса_мк = Регистр_причины_сброса

'===============================================================================
'Всё включено ~ 2 mA

'~ 1.47 mA
'  Didr0.adc0d = 1
'  Didr0.adc1d = 1
'  Didr0.adc2d = 1
'  Didr0.adc3d = 1
'  Didr0.adc4d = 1
'  Didr0.adc5d = 1

'  Didr1.ain0d = 1
'  Didr1.ain1d = 1

'~ 930 мкA
  Ddrb = &B_1111_1111 : Portb = &B_0000_0000
  Ddrc = &B_1111_1111 : Portc = &B_0000_0000
  Ddrd = &B_1111_1111 : Portd = &B_0000_0000

'===============================================================================
'               Конфигурация питания аппаратных модулей МК
'===============================================================================
' PRR – Регистр управления питанием аппаратных средств МК
' Начальное значение регистра PRR = &B00000000       ' Регистр управления питанием аппаратных средств МК

'~ 860 мкА
  Prr = &B_1011_1110
'         |||| ||||
'         |||| |||+--- 0 - PRADC    - если 1, то модуль ADC (АЦП) выключен
'         |||| ||+---- 1 - PRUSART0 - если 1, то модуль USART выключен
'         |||| |+----- 2 - PRSPI    - если 1, то модуль SPI выключен
'         |||| +------ 3 - PRTIM1   - если 1, то Timer1/Counter1 выключен
'         |||+-------- 4 - PRUSART1 - если 1, то модуль USART1 выключен
'         ||+--------- 5 - PRTIM0   - если 1, то Timer0/Counter0 выключен
'         |+---------- 6 - PRTIM2   - если 1, то Timer2/Counter2 выключен
'         +----------- 7 - PRTWI    - если 1, то модуль TWI (I2c) выключен, после включени обязательна повторная инициализация
' Примечание:

'===============================================================================
'            Конфигурация TIMER2, пробуждение и временные интервалы
'==============================================================================
  Config Timer2 = Timer , Async = On , Prescale = 1024       ' Делитель 32768 / 128 / 256 = 1 сек (прерывание TIMER2 = 1 раз в секунду)
  'Const Количество_срабатываний_timer2 = 1       ' Значение константы используется в подпрограмме "Обработка_прерывания_timer2"
'Ссылка на подпрограмму обработчика прерывания TIMER2, для работы часов
  On Timer2 Обработка_прерывания_timer2 Nosave       ' Ссылка на подпрограмму обработчика прерывания TIMER2
  Dim Флаг_есть_прерывание_timer2 As Byte
  Stop Timer2
  Timer2 = 0

'---------------  Настройка пониженного энергопотребления МК  ------------------
  Assr.3 = 1 : Waitms 50       ' Включить НЧ-генератор AS2 и подождать стабилизации амплитуды генератора
'При включении  бита AS2 (3) в регистре ASSR (ASSR.3), становится возможным применение режима
'"Powersave" - разновидность спящего режима. Пробуждение МК от TIMER2

'===============================================================================
'                      Конфигурация USART
'===============================================================================
  $baud = 38400       '19200     '38400     '57600     '76800     '115200    '230400

  Config Com1 = Baud , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
  Ucsr0a.1 = 1       ' Двойная скорость работы USART, скорость трансляции = $baud * 2

  On Utxc Передача_по_usart_закончена Nosave
  Dim Флаг_можно_поспать As Byte

  Gosub Причина_сброса_atmega328p

'===============================================================================
'                      Н А С Т Р О Й К А     АЦП
'===============================================================================
  Dim Флаг_данные_ацп As Byte

  Dim Данные_ацп_мк_word As Word       ': Данные_ацп_мк_word = 0
  Dim Данные_ацп_мк_single As Single       ' : Данные_ацп_мк_single = 0
  Dim Данные_ацп_мк_str As String * 10       ' : Данные_ацп_мк_str = "-.-"
'  Dim Уровень_батареи_str As String * 1       ' : Уровень_батареи_str = "0"

'Значение константы * 3 такта. Время ожидания стабилизации внутреннего источники опорного напряжения 1.1V
'http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf
'стр.305
'Table 29-11
'Bandgap reference start-up time
'1,08545 V - расчётное значение опорного напряжения тестового МК Atmega328P
  Const Const_ожидание_готовности_1_1v = 45       'Значение * 3 такта. Время ожидания стабилизации внутреннего источники опорного напряжения 1.1V
'Зависит от конкретного экземпляра МК, температуры и напряжения питания, чем больше Uпит, тем дольше надо ждать, пока внутренний источник опорного напряжения выйдет на рабочий уровень

  Const Const_коэффициент_перещета_1_1v = 1111.5       'Зависит от конкретного экземпляра МК, т.к., согласно документации 1...1.2V

'Ссылка на обработчик прерывания АЦП
  On Adc Опрос_ацп Nosave

  'Config Aci = Off , Compare = Off , Trigger = Toggle
  Acsr = &B_1000_0001

'Config Adc = Single , Prescaler = 2 , Reference = Avcc , (ADC14)
  Admux = &B_0100_1110
  Adcsra = &B_1100_0001
  Adcsrb = &B_0000_0000

'Ждём первого измерения, чтобы исключить неверные значения
Ждем_измерение:
  !lds R16 , ADCSRA
'Ждём флага готового измерения АЦП (Bit 4 – ADIF: ADC Interrupt Flag)
  !SBRs R16 , ADIF
  !rjmp Ждем_измерение
  !lds R17 , adcl
  !lds R17 , adch
  !andi R16 , &B_0000_0111
  !sts ADCSRA , R16

'--------------  Разрешаем работу необходимых прерываний  ----------------------
  Enable Adc       ' : Adcsra.adif = 0
  Enable Timer2       'Tifr2 = &B_0000_0000 :
  Start Timer2
'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts
'===============================================================================
'                   Г Л А В Н Ы Й         Ц И К Л
  Главный_цикл:
'===============================================================================

      If Флаг_есть_прерывание_timer2 > 0 Then

         'Замеряем собственное напряжение питания МК
         'Включаем АЦП
          Adcsra.aden = 1       ' Включаем АЦП

         'Waitus 121       ' граница 121 при Uпит = 4.1V
          !ldi R16 , Const_Ожидание_готовности_1_1V
         Пауза_125_циклов:
          !dec R16
          !brne Пауза_125_циклов

         'ADC Noise Reduction
          !ldi R16 , &B_0000_0011       ' ADC Noise Reduction
          !sts smcr , R16
          !sleep

         'Выключаем АЦП
          Adcsra.aden = 0       ' Выключаем АЦП

         'Занимаемся расчётами и отображением значений на LCD TIC-5234
          'Config Single = Scientific , Digits = 3
          'Данные_ацп_мк_single = Данные_ацп_мк_word * 0.00106       'Const_коэффициент_перещета_1_1v / Данные_ацп_мк_word       ' U пит. = 1024 * 1.1 / ADC
          Данные_ацп_мк_single = Const_коэффициент_перещета_1_1v / Данные_ацп_мк_word
          'Данные_ацп_мк_str = Str(данные_ацп_мк_single)
          Данные_ацп_мк_str = Fusing(данные_ацп_мк_single , "&.&&&")
          Данные_ацп_мк_str = Format(данные_ацп_мк_str , "     0")

          Print Данные_ацп_мк_str

          Val_byte = Rnd(63)
          Portb = Val_byte

          Флаг_есть_прерывание_timer2 = 0
          Goto Главный_цикл
      End If

    Power Powersave

'===============================================================================
  Goto Главный_цикл
' End
'                        П О Д П Р О Г Р А М М Ы
'===============================================================================

'===============================================================================
  Опрос_ацп:
'-------------------------------------------------------------------------------
    !push R16
    !lds R16 , adcl
    !sts {Данные_ацп_мк_word} , R16
    !lds R16 , adch
    !sts {Данные_ацп_мк_word + 1} , R16
    !pop R16
    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
' Подпрограмма обработки прерывания TIMER2, происходит 1 или 2 раза в секунду, в зависимости от настроек TIMER2
'===============================================================================
  Обработка_прерывания_timer2:
'-------------------------------------------------------------------------------
    !push R16
    !ldi R16 , 1
    !sts {Флаг_есть_прерывание_timer2} , R16
    !pop R16
    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Причина_сброса_atmega328p:
'-------------------------------------------------------------------------------
    If Причина_сброса_мк.3 = 1 Then
        Print "Reset от Watchdog"
        Причина_сброса_мк.3 = 0
        Mcusr.3 = 0
        Waitms 5
    End If

    If Причина_сброса_мк.2 = 1 Then
        Print "Reset от снижения питания"
        Причина_сброса_мк.2 = 0
        Mcusr.2 = 0
        Waitms 5
    End If

    If Причина_сброса_мк.1 = 1 Then
        Print "Reset от кнопки"
        Причина_сброса_мк.1 = 0
        Mcusr.1 = 0
        Waitms 5
    End If

    If Причина_сброса_мк.0 = 1 Then
        Print "Reset от подачи питания"
        Причина_сброса_мк.0 = 0
        Mcusr.0 = 0
        Waitms 5
    End If
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Передача_по_usart_закончена:
'-------------------------------------------------------------------------------
    !push R16
    !ldi R16 , 1
'    !sts {Флаг_можно_поспать} , R16
    !pop R16
    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================