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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Спящий режим (Powersave)


Спящий режим (Powersave)

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

1

Доброго дня
Столкнулся с очень интересным фактом.
У меня есть 10 устройств прошитых одинаково. Микроконтроллер в них общается с исполнительным устройством по USART причем общается раз в определенный интервал. В промежутках между интервалами контроллер засыпает. Вот код:

$regfile = "M128def.dat"
$crystal = 8000000
$baud = 4800
$hwstack = 256
$swstack = 256
$framesize = 256

Dim In_bit as bit                                                   'если 0 - входа в основной цикл не было, 1- вход был
In_bit = 0
Dim Pow_ctrl_adc As Integer                                 'здесь хранится значение, измеренное АЦП на аккумуляторе
Dim R_bit As Bit
R_bit = 0
Dim Timer3_schet As Integer
Timer3_schet = 0
Dim Schet As Integer
Schet = 0
Dim Schet_ee As Eram Integer
Schet = Schet_ee
Dim Analog As Integer
Analog = 0

Config Adc = Single , Prescaler = Auto , Reference = Internal
Start Adc

Config Serialin = Buffered , Size = 170 , Bytematch = All   'конфигурация com порта на перехва всех прерываний

Dim Simbol As String * 2                                    'сюда приходит символ
Simbol = ""
Dim Command As String * 170                                 'здесь формируется комманда
Command = ""

Dim Pvr_save_bit As Bit                                     'разрешение на сбережение энергии         0 - запрещено 1-разрешено
Pvr_save_bit = 0

Config Timer0 = Timer , Async = On , Prescale = 1024
Enable Ovf0
On Timer0 Timer_0
Start Timer0

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

'Тело программы////////////////////////////////////////////////////////////////

Enable Interrupts

Do

In_bit = 1                                                          'говорим, что вошли в цикл программы

Pow_ctrl_adc = Getadc(0)                                    'измеряем зарядку аккумулятора

If Pvr_save_bit = 0 And Pow_ctrl_adc <= 1000 Then
Print Schet
End If

If Pow_ctrl_adc > 1000 And R_bit = 1 Then
Pvr_save_bit = 1
End If

If Pvr_save_bit = 1 Then
Stop Adc
Clear Serialin                                              ' чистим буфер
Ucsr0b.3 = 0                                                'выключаем ком порт
Config Porte.1 = Input                                      'ногу TxD как вход, чтоб ток не тек
Powersave
End If

Loop

End

'//////////////////////////////////////////////////////////////////////////////
Timer_0:

Start Adc
Ucsr0b.3 = 1
Incr Timer3_schet

If Timer3_schet >= 800 Then
Pvr_save_bit = 0
Incr Analog
Incr Schet
Schet_ee = Schet
End If

Return
'//////////////////////////////////////////////////////////////////////////////

Serial0bytereceived:                                        'метка обработчика прерываний на нулевом com порту
Simbol = Waitkey()                                          'здесь ждем символ
If Simbol <> Chr(13) Then
Command = Command + Simbol                                  'формируем из символов комманду
   If Len(command) >= 169 Then
   Command = ""
   Clear Serialin
   End If
End If

If Simbol = Chr(13) Then                                    'если это конец посылки, то

   If Command = "R" Then
   R_bit = 1
   End If

   If Command = "N" Then
   R_bit = 0
   End If

Command = ""
End If

Return
'-------------------------------------------------------------------------------
Но после первого пробуждения на всех 10 устройствах происходит рестарт (In_bit становится равным 0, Analog также обнуляется). Долго ломал голову, не понял почему перезагрузка идет... дописал эту строку Stop Watchdog, вот сюда:

If Pvr_save_bit = 1 Then
Stop Adc
Clear Serialin                                              ' чистим буфер
Ucsr0b.3 = 0                                                'выключаем ком порт
Config Porte.1 = Input                                      'ногу TxD как вход, чтоб ток не тек
Stop Watchdog
Powersave
End If

и о чудо перезагрузка прекратилась, все работает, но только на 8 из 10, остальные два не перезагружаются (In_bit равен 1) , но переменная Analog по прежнему равна 0.

У меня два вопроса к знающим людям:
1. Как влияет строка Stop Watchdog на режим сна?
2. Почему все таки сбивается переменная Analog, что не так с кодом?
Спасибо

0

2

"Собака" в конфигурации МК отключена?

0

3

Да, я бы выкинул из обработчиков прерываний все проверки. Только флаг установить да в переменную принятый символ прибавить, иначе могут быть всякие переполнения и уход на перезагрузку из за переполнения стека. То, что помогло именно Stop Watchdog скорее всего случайность.
Лично я поломав голову не раз на тему хрензнает что происходит взял за правило добавлять nosave в обработчик прерывания, код в прерывании писать на ассемблере по максимуму  с ручным сохранением только используемых регистров. Так же стараюсь запрещать прерывания пока не обработаю прерывание. Глюки волшебным образом пропали.

0

4

Пётр написал(а):

"Собака" в конфигурации МК отключена?

собака и не включалась

0

5

Пётр написал(а):

"Собака" в конфигурации МК отключена?

собака и не включалась

IgorL написал(а):

Да, я бы выкинул из обработчиков прерываний все проверки. Только флаг установить да в переменную принятый символ прибавить, иначе могут быть всякие переполнения и уход на перезагрузку из за переполнения стека. То, что помогло именно Stop Watchdog скорее всего случайность.
Лично я поломав голову не раз на тему хрензнает что происходит взял за правило добавлять nosave в обработчик прерывания, код в прерывании писать на ассемблере по максимуму  с ручным сохранением только используемых регистров. Так же стараюсь запрещать прерывания пока не обработаю прерывание. Глюки волшебным образом пропали.

Не похоже на случайность. Перезагрузка действительно, похоже из-за переполнений была....но все таки, почему стек переполняется? и почему он не переполняется если написать  Stop Watchdog ?

0

6

kostr написал(а):

Не похоже на случайность. Перезагрузка действительно, похоже из-за переполнений была....но все таки, почему стек переполняется? и почему он не переполняется если написать  Stop Watchdog ?

Если при переходе на подпрограмму испортить значение счетчика комманд, сохраненного в стеке, возврат произойдет на тот адрес, что будет в этот момент в ОЗУ в ячейеке, на которую указывает указатель стека. Одна из переменных у вас портится, значит что то идет не так. Не уверен, что
$hwstack и $swstack могут иметь значения 256. Попробуйте поставить 250 возможно все починится.

0

7

IgorL написал(а):

Если при переходе на подпрограмму испортить значение счетчика комманд

А как я могу испортить значение этого счетчика? Именно в моем примере? Переменные действительно портятся, причем как текстовые, так и битовые.

И еще, тоже не очень понимаю логику. Я что-то на подобии уже делал, но контроллеру не надо было спать и был внешний кварц 16Мег, программа в остальном была один в один, устройств было штук 30 и не одного глюка. $hwstack и $swstack всегда были 256, как раз делал больше, чтоб переполнений не было. Сейчас кварц внутренний 8Мег

0

8

256 не входит в байт.
http://avrhelp.mcselec.com/index.html?_hwstack.htm

0

9

Что значит 256 не входит в байт?

Я использую во всех проектах 256, и вроде работает все. Некоторые уже два года круглосуточно и без таких косяков.

0

10

kostr написал(а):

Что значит 256 не входит в байт?

Для числа 255 нужен один байт, для числа  256 уже два байта
hFF=255   256=h0100

0

11

$hwstack = 256 здесь мы уже определяем стек в байтах, как я понимаю. И чем в денном случае негативно, то что 256 занимает 2 байта?

0

12

kostr написал(а):

$hwstack = 256 здесь мы уже определяем стек в байтах, как я понимаю. И чем в денном случае негативно, то что 256 занимает 2 байта?

Вы пробовали перекомпилить проект c

Код:
$hwstack = 250
$swstack = 250
$framesize = 250

? Попробуйте, я думаю, что это должно помочь. Если нет, а так же если поможет и объяснить почему я не возьмусь.

0

13

Попробовать смогу только вечером поздно, обязательно отпишусь по результату.

0

14

Попробуйте $HWCHECK, $FRAMECHECK, $SOFTCHECK. Если я правильно понял перевод, то вы получите нужные значения стека.

0

15

IgorL написал(а):

kostr написал(а):

    $hwstack = 256 здесь мы уже определяем стек в байтах, как я понимаю. И чем в денном случае негативно, то что 256 занимает 2 байта?

Вы пробовали перекомпилить проект c
Код:

$hwstack = 250
$swstack = 250
$framesize = 250

? Попробуйте, я думаю, что это должно помочь. Если нет, а так же если поможет и объяснить почему я не возьмусь.

нет не помогло.
Танцы с бубном продолжаются

0

16

Ну не знаю. Размер стеков явно большой, я на этом на грабли наступал. Что то со страничностью памяти.
Лечил как написал выше NOSAVE и выбрасыванием сложного кода из прерывания.

0

17

Вчера пол ночи со стеком экспериментировал, менял от 64 до 255 - симптомы те же. Буду потихоньку фрагменты выкидывать, мож вылезет косяк

0

18

Начал выкидывать со строки "Powersave" вот уже час работает без глюков четыре прибора. По ходу дела у меня переменные рушатся именно при выходе из этого режима. Кто имел опыт работы с Powersave, мож что не так делаю, когда просыпаюсь?, я просто первое устройство делаю с этим режимом.

0

19

kostr написал(а):

Кто имел опыт работы с Powersave, мож что не так делаю, когда просыпаюсь?

Вместо Powersave попробуйте Idle, у меня PowerSave тоже глючит, в процессе поиска причины.

0

20

Idle - 5мА кушает, это не пойдет, автономное питание погибнет через день. Powersave - 25мкА.
Есть еще две недели почти у меня на изучение сего феномена, буду писать результаты.
Заметил еще одну вещь. Устройство работает от аккума, вынимаю аккумулятор (контроллер перезапускается), вставляю аккумулятор и только что глючное устройство работает как часы. Потом опять сбрасываю все аккумулятором и то же самое устройство опять глючит, и так 50 на 50.

0

21

kostr написал(а):

Начал выкидывать со строки "Powersave" вот уже час работает без глюков четыре прибора. По ходу дела у меня переменные рушатся именно при выходе из этого режима. Кто имел опыт работы с Powersave, мож что не так делаю, когда просыпаюсь?, я просто первое устройство делаю с этим режимом.

Я делал, но не этом камне, на Tiny26, посмотрел сейчас, я выставлял Mcucr = &B00110001  и в коде

Код:
$asm
    SLEEP
$end asm

Кстати, обратите внимание, в http://avrhelp.mcselec.com/index.html?powersave.htm написано "The POWERSAVE mode is only available in the 8535, Mega8, Mega163.

Most new chips have many options for Power down/Idle. It is advised to consult the data sheet to see if a better mode is available.

notice You should use the new CONFIG POWERMODE statement."

0

22

То, что Powersave в Mega128 есть - это написано в даташите, но вот действительно, что делает баском строкой Powersave - секрет.

0

23

kostr написал(а):

То, что Powersave в Mega128 есть - это написано в даташите, но вот действительно, что делает баском строкой Powersave - секрет.

Ну не такой уж это секрет:

Код:
 Powersave
020C B775     IN   R23, $35
020E 7C73     ANDI R23, $C3
0210 6378     ORI  R23, $38
0212 BF75     OUT  $35, R23
0214 9588     SLEEP

Проверьте по даташиту что должно быть в Mcucr и что выставляет в в 35h Bascom

0

24

для Powersave в Mega128 необходимо в Mcucr записать 38h, но что делает BasCom я пока не очень понял.
а 35h - это дежурный режим, доступный только при наличии внешнего кварцевого резонатора

Отредактировано kostr (2014-03-19 10:53:01)

0

25

35h это адрес регистра. У меня нет даташита, посмотрите адрес регистра Mcucr.
Баском вначале читает значение регистра по этому адресу, потом делает логическое "И" с  C3h (11000011 - сбрасывает разряды со 2 по 6) и потом логическим "ИЛИ" с 00111000 устанавливает в единицу разряды с 3 по 6

UPD
http://www.gaw.ru/html.cgi/txt/doc/micr … 103_13.htm вроде все правильно выставляется, смотрите в другом месте :(

Отредактировано IgorL (2014-03-19 11:17:14)

0

26

If Timer3_schet >= 8 Then
Pvr_save_bit = 0
Incr Analog
Incr Schet
Schet_ee = Schet
End If
вот на этом куске после того как был контроллер погружен в сон и Timer3_schet становится равным 8 симулятор виснет
если Powersave закоментить, то все считает

0

27

kostr написал(а):

Schet_ee = Schet

Это запись в EEPROM MK?

Если ДА, то попробуйте ждать окончания записи, а потом засыпать. После окончания записи есть прерывание, проверяйте бит окончания записи или ставьте флажок в прерывании.

Отредактировано sasha_1973 (2014-03-19 12:33:05)

0

28

Да, это запись.
Попробую, да только в даташите написано "Если микроконтроллер переводится в режим выключения командой sleep в процессе выполнения операции записи в ЭСППЗУ, то операция записи будет продолжена и завершится по истечении требуемого времени доступа для записи"

Отредактировано kostr (2014-03-19 12:53:01)

0

29

kostr написал(а):

только в даташите написано "Если микроконтроллер переводится в режим выключения командой sleep в процессе выполнения операции записи в ЭСППЗУ, то операция записи будет продолжена и завершится по истечении требуемого времени доступа для записи"

У меня без ожидания ничего не записывалось, стал проверять бит окончания записи, всё заработало.

Если использовать Idle, можно задействовать регистр "PRR"  -  управления питанием аппаратных средств МК.

' PRR – Регистр управления питанием аппаратных средств МК
' Начальное значение регистра PRR = &B00000000       ' Регистр управления питанием аппаратных средств МК
  Prr = &B10111101
'         ||||||||
'         |||||||+- 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) выключен, после включени обязательна повторная инициализация
' Примечание:

Отредактировано sasha_1973 (2014-03-19 12:59:42)

0

30

sasha_1973 написал(а):

kostr написал(а):

    только в даташите написано "Если микроконтроллер переводится в режим выключения командой sleep в процессе выполнения операции записи в ЭСППЗУ, то операция записи будет продолжена и завершится по истечении требуемого времени доступа для записи"

У меня без ожидания ничего не записывалось, стал проверять бит окончания записи, всё заработало.

Если использовать регистр PRR  -  можно настроить минимальное потребление.

' PRR – Регистр управления питанием аппаратных средств МК
' Начальное значение регистра PRR = &B00000000       ' Регистр управления питанием аппаратных средств МК
  Prr = &B10111101
'         ||||||||
'         |||||||+- 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) выключен, после включени обязательна повторная инициализация

Полезно, спасибо. Попробую прям сейчас.

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Спящий режим (Powersave)