Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



Исследование PowerSave

Сообщений 1 страница 4 из 4

1

PowerSave - при внешнем тактировании пониженое энергопотребление, в зависимости от МК и U питания, достижимое значение < 1 мкА

0

2

.                                ! Внимание !

Atmega8A, после обновления документации, изменились биты в регистре MCUCR

Документация

Rev.: Atmel-8159F-8-bit AVR Microcontroller_Datasheet_Complete-09/2015             Rev.: 2486AA–AVR–02/2013
http://s6.uploads.ru/t/KOQnZ.jpg                       http://s9.uploads.ru/t/KYNBQ.jpg

.                                ! Внимание !

0

3

Atmega8A

частота кварца 32,768 кГц

фьюз CKOPT установлен

http://s7.uploads.ru/t/3GDEk.jpg

не забываем о выключении контроля питания, включенный потребляет ~ 24 - 9 =  ~ 15 мкА

Видео

http://s9.uploads.ru/t/kya9R.jpg

частота работы МК 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А

Видео


Исходник для Atmega8A

'===============================================================================

  $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_0000

    Enable 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 If

    Waitms 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
'===============================================================================

0

4

Atmega328P

частота кварца 32,768 кГц

в Atmega328P фьюз CKOPT сброшен, выполняет другую функцию

http://se.uploads.ru/t/JNlo3.jpg

не забываем о выключении контроля питания, включенный потребляет ~ 22 мкА

Видео

http://sa.uploads.ru/t/fbexn.jpg

частота работы МК 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А

Видео


Исходник для Atmega328P

'===============================================================================

  $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_0000

    Enable 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 If

    Waitms 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
'===============================================================================

0