PowerSave - при внешнем тактировании пониженое энергопотребление, в зависимости от МК и U питания, достижимое значение < 1 мкА
Исследование PowerSave
Сообщений 1 страница 4 из 4
Поделиться22016-06-07 04:51:17
. ! Внимание !
Atmega8A, после обновления документации, изменились биты в регистре MCUCR
Rev.: Atmel-8159F-8-bit AVR Microcontroller_Datasheet_Complete-09/2015 Rev.: 2486AA–AVR–02/2013
![]()
. ! Внимание !
Поделиться32016-06-07 07:00:44
Atmega8A
частота кварца 32,768 кГц
частота работы МК 8 МГц
Просыпаемся 1 раз в 8 секунд, что-то делаем (в исходнике просто пауза 4 сек) и снова идём спать.
Время сна настраивается в исходнике, переменная "Значение_таймера" и константа "Razmer_timer2"
максимальное время сна, с очень кратковременным просыпанием для подсчёта таймера:
= 524 288 секунд ~ 8738 минут ~ 145 часов
8 сек (Prescale = 1024) * 65535 (Const Razmer_timer2 = 1; Значение_таймера = 65535) = 524 288 секунд ~ 8738 минут ~ 145 часов
U питания = 4 V
Потребление МК в режиме сна < 10 мкА
После просыпания > 6 mА
'===============================================================================
$initmicro 'Переходит в подпрограмму "_init_micro:" раньше сброса Watchdog, сразу после инициализации SPL; SPH
'===============================================================================
$map ' Получаем карту распределения памяти компилятором Bascom
$regfile = "m8def.dat"
$crystal = 8000000 ' 8 МГц
$framesize = 64 ' Размер области используемой и необходимой для преобразований
$hwstack = 64 ' Размер аппаратного стека
$swstack = 64 ' Размер программного стека'===============================================================================
' Настройка вывода МК для питания внешней периферии (напрямую или через полевик)
'===============================================================================
Питание_перифирии Alias Portb.0 : Config Питание_перифирии = Output : Питание_перифирии = 1'===============================================================================
' Настройка TIMER2 в асинхронном режиме, работа от внешнего кварца
'===============================================================================' Делитель 32768 / 64 / 256 = 0,5 сек (прерывание TIMER2 = 2 раза в секунду)
' Делитель 32768 / 128 / 256 = 1 сек (прерывание TIMER2 = 1 раз в 1 секунду)
' Делитель 32768 / 256 / 256 = 2 сек (прерывание TIMER2 = 1 раз в 2 секунды)
' Делитель 32768 / 1024 / 256 = 8 сек (прерывание TIMER2 = 1 раз в 8 секунд)Config Timer2 = Timer , Async = On , Prescale = 1024 ' Делитель 32768 / 1024 / 256 = 8 сек (прерывание TIMER2 = 1 раз в 8 секунд)
' Ссылка на подпрограмму обработчика прерывания TIMER2, для работы часов
' Используемая переменная в обработчике прерывания
Const Razmer_timer2 = 0 '0 - Byte; 1 - Word#if Razmer_timer2 = 0
On Timer2 Обработка_прерывания_timer2_byte Nosave ' Ссылка на подпрограмму обработчика прерывания TIMER2
Dim Таймер As Byte
Dim Значение_таймера As Byte
#else
On Timer2 Обработка_прерывания_timer2_word Nosave ' Ссылка на подпрограмму обработчика прерывания TIMER2
Dim Таймер As Word
Dim Значение_таймера As Word
#endifЗначение_таймера = 1 'Необходимое значение * (f кварца / Prescale / 256) (в секундах)
Таймер = Значение_таймера
'--------------- Настройка пониженного энергопотребления МК ------------------
' Не забываем про фьюз (CKOPT (англ.)), подпитка кварца для повышения стабильности и помехозащищённости, потребление МК вышеAssr.3 = 1 : Waitms 100 ' Включить НЧ-генератор AS2 и подождать стабилизации амплитуды генератора
' При включении бита AS2 (3) в регистре ASSR (ASSR.3), становится возможным применение режима
' "Powersave" - разновидность спящего режима. Пробуждение МК от TIMER2
'Const Значение_idle = &B_1000_0000
Const Значение_adcnoise = &B_1001_0000
Const Значение_powersave = &B_1011_0000
Const Значение_powerdown = &B_1010_0000'-------------- Разрешаем работу необходимых прерываний ----------------------
Enable Timer2
'------------ Разрешаем работу всех включенных прерываний --------------------
Enable Interrupts
'===============================================================================' Г Л А В Н Ы Й Ц И К Л
Главный_цикл:
'===============================================================================If Таймер = 0 Then
'Делаете то, что Вам надо
'Gosub ...............Wait 1
Таймер = Значение_таймера
Else
Gosub Тихий_час
End If
'===============================================================================
Goto Главный_цикл
End
'==============================================================================='===============================================================================
_init_micro:
'-------------------------------------------------------------------------------
Ddrb = &B_1111_1111 : Portb = &B_0000_0000
Ddrc = &B_1111_1111 : Portc = &B_0000_0000
Ddrd = &B_1111_1111 : Portd = &B_0000_0000
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
Тихий_час:
'-------------------------------------------------------------------------------
Acsr.acd = 1 'Выключаем компаратор (именно записью "1", смотреть документацию), слишком много потребляет
Ucsrb.rxen = 0 'Выключаем приёмник USART, слишком много потребляет
Ucsrb.txen = 0 'Выключаем передатчик USART, слишком много потребляет
Adcsra.aden = 0 'Выключаем АЦП, слишком много потребляетПитание_перифирии = 0
Тихий_час_1:
'! В Н И М А Н И Е !
'Если есть внешняя подтяжка к "+", вывод МК меняем на 1, иначе будет потребление в зависимости от сопротивления подтяжки!
'! В Н И М А Н И Е !
Ddrb = &B_1111_1111 : Portb = &B_0000_0000
Ddrc = &B_1111_1111 : Portc = &B_0000_0000
Ddrd = &B_1111_1111 : Portd = &B_0000_0000Enable Timer2 'Разрешаем прерывания TIMER2
Enable Interrupts 'Разрешаем прерывания'###########################
Экстренная_остановка:
'Только так, иначе можем не проснуться
If Assr.tcn2ub > 0 And Assr.ocr2ub > 0 And Assr.tcr2ub > 0 Then
nop
Goto Экстренная_остановка
End If!lds R16 , Mcucr
!andi R16 , &B_0000_1111 'Обнуляем биты 4; 5; 6; 7
!ori R16 , Значение_powersave 'Выставляем, как будем спать
!sts mcucr , R16 'Пишем в региср!sleep 'Отправляемся спать
'###########################If Таймер > 0 Then
Goto Экстренная_остановка
End IfWaitms 10 'Ждём пока все проснутся
'Просыпаемся, настраиваем порты и включаем всё, что необходимо
Ddrb = &B_1111_1111 : Portb = &B_0000_0000
Ddrc = &B_1111_1111 : Portc = &B_0011_0011
Ddrd = &B_1111_1111 : Portd = &B_0001_0110' Питание_перифирии = 1 'Подаём питание на периферию
Ucsrb.rxen = 1 'Включаем приёмник USART
Ucsrb.txen = 1 'Включаем передатчик USART
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
' Подпрограмма обработки прерывания TIMER2, для переменной Byte
'===============================================================================
Обработка_прерывания_timer2_byte:
'-------------------------------------------------------------------------------
!Push R16 ' Сохраняем регистры, которые используем в обработке прерывания
!In R16 , Sreg
!Push R16!lds R16 , {Таймер}
!cpi R16 , 0
!breq Выход_прерывание_timer2!dec R16
!sts {Таймер} , R16Выход_прерывание_timer2:
!Pop R16
!Out Sreg , R16
!Pop R16!reti
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
' Подпрограмма обработки прерывания TIMER2, для переменной Word
'===============================================================================
Обработка_прерывания_timer2_word:
'-------------------------------------------------------------------------------
!push R16
!in R16 , sreg
!push R16
!push R30
!push R31!lds R30 , {Таймер}
!lds R31 , {Таймер + 1}!cpi R31 , 0
!ldi R16 , 0
!cpc R30 , R16
!brcs Выход_прерывания_timer2_word
!breq Выход_прерывания_timer2_word
!rjmp Считаем_таймер
!rjmp Выход_прерывания_timer2_wordСчитаем_таймер:
!sbiw R30 , 1!sts {Таймер} , R30
!sts {Таймер + 1} , R31Выход_прерывания_timer2_word:
!pop R31
!pop R30
!pop R16
!out sreg , R16
!pop R16!reti
'-------------------------------------------------------------------------------
Return
'===============================================================================
Поделиться42016-06-07 08:16:44
Atmega328P
частота кварца 32,768 кГц
частота работы МК 8 МГц
Просыпаемся 1 раз в 8 секунд, что-то делаем (в исходнике просто пауза 4 сек) и снова идём спать.
Время сна настраивается в исходнике, переменная "Значение_таймера" и константа "Razmer_timer2"
максимальное время сна, с очень кратковременным просыпанием для подсчёта таймера:
= 524 288 секунд ~ 8738 минут ~ 145 часов
8 сек (Prescale = 1024) * 65535 (Const Razmer_timer2 = 1; Значение_таймера = 65535) = 524 288 секунд ~ 8738 минут ~ 145 часов
U питания = 4 V
Потребление МК в режиме сна ~ 1.2 мкА
После просыпания > 4 mА
'===============================================================================
$initmicro 'Переходит в подпрограмму "_init_micro:" раньше сброса Watchdog, сразу после инициализации SPL; SPH
'===============================================================================
$map ' Получаем карту распределения памяти компилятором Bascom
$regfile = "m328pdef.dat" ' http://www.atmel.com/images/atmel-8159- … asheet.pdf
$crystal = 8000000 ' 8 МГц
$framesize = 64 ' Размер области используемой и необходимой для преобразований
$hwstack = 64 ' Размер аппаратного стека
$swstack = 64 ' Размер программного стека'===============================================================================
' Настройка вывода МК для питания внешней периферии (напрямую или через полевик)
'===============================================================================
Питание_перифирии Alias Portb.0 : Config Питание_перифирии = Output : Питание_перифирии = 1'===============================================================================
' Настройка TIMER2 в асинхронном режиме, работа от внешнего кварца
'===============================================================================' Делитель 32768 / 64 / 256 = 0,5 сек (прерывание TIMER2 = 2 раза в секунду)
' Делитель 32768 / 128 / 256 = 1 сек (прерывание TIMER2 = 1 раз в 1 секунду)
' Делитель 32768 / 256 / 256 = 2 сек (прерывание TIMER2 = 1 раз в 2 секунды)
' Делитель 32768 / 1024 / 256 = 8 сек (прерывание TIMER2 = 1 раз в 8 секунд)Config Timer2 = Timer , Async = On , Prescale = 1024 ' Делитель 32768 / 1024 / 256 = 8 сек (прерывание TIMER2 = 1 раз в 8 секунд)
' Ссылка на подпрограмму обработчика прерывания TIMER2, для работы часов
' Используемая переменная в обработчике прерывания
Const Razmer_timer2 = 0 '0 - Byte; 1 - Word#if Razmer_timer2 = 0
On Timer2 Обработка_прерывания_timer2_byte Nosave ' Ссылка на подпрограмму обработчика прерывания TIMER2
Dim Таймер As Byte
Dim Значение_таймера As Byte
#else
On Timer2 Обработка_прерывания_timer2_word Nosave ' Ссылка на подпрограмму обработчика прерывания TIMER2
Dim Таймер As Word
Dim Значение_таймера As Word
#endifЗначение_таймера = 1 'Необходимое значение * (f кварца / Prescale / 256) (в секундах)
Таймер = Значение_таймера
'--------------- Настройка пониженного энергопотребления МК ------------------
' Не забываем про фьюз (CKOPT (англ.)), подпитка кварца для повышения стабильности и помехозащищённости, потребление МК вышеAssr.3 = 1 : Waitms 100 ' Включить НЧ-генератор AS2 и подождать стабилизации амплитуды генератора
' При включении бита AS2 (3) в регистре ASSR (ASSR.3), становится возможным применение режима
' "Powersave" - разновидность спящего режима. Пробуждение МК от TIMER2
'Const Значение_idle = &B_0000_0001
Const Значение_adcnoise = &B_0000_0011
Const Значение_powersave = &B_0000_0111
Const Значение_powerdown = &B_0000_0101'-------------- Разрешаем работу необходимых прерываний ----------------------
Enable Timer2
'------------ Разрешаем работу всех включенных прерываний --------------------
Enable Interrupts
'===============================================================================' Г Л А В Н Ы Й Ц И К Л
Главный_цикл:
'===============================================================================If Таймер = 0 Then
'Делаете то, что Вам надо
'Gosub ...............Wait 4
Таймер = Значение_таймера
Else
Gosub Тихий_час
End If
'===============================================================================
Goto Главный_цикл
End
'==============================================================================='===============================================================================
_init_micro:
'-------------------------------------------------------------------------------
Ddrb = &B_1111_1111 : Portb = &B_0000_0000
Ddrc = &B_1111_1111 : Portc = &B_0000_0000
Ddrd = &B_1111_1111 : Portd = &B_0000_0000
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
Тихий_час:
'-------------------------------------------------------------------------------
Acsr.acd = 1 'Выключаем компаратор (именно записью "1", смотреть документацию), слишком много потребляет
Ucsr0b.rxen0 = 0 'Выключаем приёмник USART, слишком много потребляет
Ucsr0b.txen0 = 0 'Выключаем передатчик USART, слишком много потребляет
Adcsra.aden = 0 'Выключаем АЦП, слишком много потребляетПитание_перифирии = 0
Тихий_час_1:
'! В Н И М А Н И Е !
'Если есть внешняя подтяжка к "+", вывод МК меняем на 1, иначе будет потребление в зависимости от сопротивления подтяжки!
'! В Н И М А Н И Е !
Ddrb = &B_1111_1111 : Portb = &B_0000_0000
Ddrc = &B_1111_1111 : Portc = &B_0000_0000
Ddrd = &B_1111_1111 : Portd = &B_0000_0000Enable Timer2 'Разрешаем прерывания TIMER2
Enable Interrupts 'Разрешаем прерывания'###########################
Экстренная_остановка:
'Только так, иначе можем не проснуться
If Assr.tcn2ub > 0 And Assr.ocr2aub > 0 And Assr.tcr2aub > 0 And Assr.ocr2bub > 0 And Assr.tcr2bub > 0 Then
nop
Goto Экстренная_остановка
End If!ldi R16 , Значение_powersave 'Выставляем, как будем спать
!sts SMCR , R16 'Пишем в региср!sleep 'Отправляемся спать
'###########################If Таймер > 0 Then
Goto Экстренная_остановка
End IfWaitms 10 'Ждём пока все проснутся
'Просыпаемся, настраиваем порты и включаем всё, что необходимо
Ddrb = &B_1111_1111 : Portb = &B_0000_0000
Ddrc = &B_1111_1111 : Portc = &B_0011_0011
Ddrd = &B_1111_1111 : Portd = &B_0001_0110Питание_перифирии = 1 'Подаём питание на периферию
Ucsr0b.rxen0 = 1 'Включаем приёмник USART
Ucsr0b.txen0 = 1 'Включаем передатчик USART
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
' Подпрограмма обработки прерывания TIMER2, для переменной Byte
'===============================================================================
Обработка_прерывания_timer2_byte:
'-------------------------------------------------------------------------------
!Push R16 ' Сохраняем регистры, которые используем в обработке прерывания
!In R16 , Sreg
!Push R16!lds R16 , {Таймер}
!cpi R16 , 0
!breq Выход_прерывание_timer2!dec R16
!sts {Таймер} , R16Выход_прерывание_timer2:
!Pop R16
!Out Sreg , R16
!Pop R16!reti
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
' Подпрограмма обработки прерывания TIMER2, для переменной Word
'===============================================================================
Обработка_прерывания_timer2_word:
'-------------------------------------------------------------------------------
!push R16
!in R16 , sreg
!push R16
!push R30
!push R31!lds R30 , {Таймер}
!lds R31 , {Таймер + 1}!cpi R31 , 0
!ldi R16 , 0
!cpc R30 , R16
!brcs Выход_прерывания_timer2_word
!breq Выход_прерывания_timer2_word
!rjmp Считаем_таймер
!rjmp Выход_прерывания_timer2_wordСчитаем_таймер:
!sbiw R30 , 1!sts {Таймер} , R30
!sts {Таймер + 1} , R31Выход_прерывания_timer2_word:
!pop R31
!pop R30
!pop R16
!out sreg , R16
!pop R16!reti
'-------------------------------------------------------------------------------
Return
'===============================================================================





