Измерение потребления МК - B7-35 (после ЦЛИТа, спец. настройка и калибровка)
Atmega328P
Минимальное потребление в режеме PowerSave при запущенном TIMER2 в асинхронном режиме (часы с внешним кварцем) - ~1.1 мкА
WATCHDOG - потребляет ~5,2 мкА
BodLevel (Контроль питания) - ~60 мкА
Запущенный АЦП - ~1.45 mА
Исходник'===============================================================================
$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 '230400Config Com1 = Baud , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Ucsr0a.1 = 1 ' Двойная скорость работы USART, скорость трансляции = $baud * 2On Utxc Передача_по_usart_закончена Nosave
Dim Флаг_можно_поспать As ByteGosub Причина_сброса_atmega328p
'===============================================================================
' Н А С Т Р О Й К А АЦП
'===============================================================================
Dim Флаг_данные_ацп As ByteDim Данные_ацп_мк_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 IfPower 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 IfIf Причина_сброса_мк.2 = 1 Then
Print "Reset от снижения питания"
Причина_сброса_мк.2 = 0
Mcusr.2 = 0
Waitms 5
End IfIf Причина_сброса_мк.1 = 1 Then
Print "Reset от кнопки"
Причина_сброса_мк.1 = 0
Mcusr.1 = 0
Waitms 5
End IfIf Причина_сброса_мк.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
'===============================================================================