Работа с SRAM в atmel studio 7 (Atmega8)

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 6
Зарегистрирован: Чт апр 25, 2019 20:37:26

Сообщение alexadrenalin »

Здравствуйте,
пишу прошивку на Atmega8, при запуске должна быть проверка датчиков, работа серво и т.д.
но если было кратковременное отключение питания не проверять заново все.
По идее в SRAM должно храниться предыдущие значения, для этого специально объявил отдельно переменную

Код: Выделить всё

#define reg (* (char *) 0x007D)

int main(void)
{
	if (reg==0xFF)
	{
		TestBoard();
	}

	Init_Board();
	
    while (1) 
    {
		startEngine();
		_delay_ms(5000);
		stopEngine();
		_delay_ms(200);
		startReversEngine();
		_delay_ms(200);
    }
	
}
А в самом TestBoard присваиваю reg=0xFF
такой вопрос: как проверить данные до обнуления ОЗУ???
Но неважно как стартует приложение всегда в ОЗУ все забито нулями
вроде как для очистки памяти в ассемблере это нужно писать самому, а тут автоматом выходит может что нужно компилятору выставить

Нигде не могу найти, может настройки компилятора какие или флаг какой-то?
Реклама
Самсусамыч

Сообщение Самсусамыч »

При старте МК в ОЗУ чёрти чо и с боку бантик… гарантированные нули появляются только после предварительной её очистки. Со студией как и с Си не знаком… сори. :) Если до перезагрузки МК не сохранить нужную информацию из ОЗУ то с данными можно попрощаться… :wink:
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

если вам нужна переменная, которая не очищается автоматически при старте программы, вы должны описать её в секции .noinit:

Код: Выделить всё

__attribute__((section(".noinit"))) uint8_t test;
после старта main вы должны проверить регистр MCUSR или MCUCR (в зависимости от типа вашего МК) на предмет определения источника сброса: если сброс был по причине подачи питания, вы должны записать в эту переменную какое-то ваше значение, а если сброс был по любой другой причине - можно проверить, что в этой переменной осталось с "досбросного" состояния.


как-то так

но если у вас питание пропадает всякий раз, это вам мало чем поможет... тут придется действовать гораздо хитрее. самый надежный вариант - использовать отдельную RC-цепочку на одном из входов, и после сброса сразу же смотреть, какое на этой емкости напряжение. если питание было, было (емкость зарядилась), а потом пропало ненадолго, то после восстановления питания емкость еще будет заряжена "с прошлого раза", и вы это обнаружите по высокому уровню на соответствующем пине МК. если же питание пропало надолго, емкость успеет разрядиться, и после сброса вы увидите на ней 0, т.к. заряжаться она будет не мгновенно.

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

Мой уютный бложик... заходите!
Контактная информация:
Родился
Сообщения: 6
Зарегистрирован: Чт апр 25, 2019 20:37:26

Сообщение alexadrenalin »

Ясное дело что там как раз и не черти что, я считываю данные и кидаю на UART и это всегда 0х00 (проверял даже на atmega644p), но если питани не "утекло" далеко то переменная сохранилась, типа дернули рубильник через ноль. Иногда даже плата не замечает что было потеряно питание, но если чуть медленнее то все, сразу долгая инициализация. Хочется понимать там просто не было питания доли секунды или пол часа, к сожалению это не вариант, пишу для готовой платы :(
[uquote="ARV",url="/forum/viewtopic.php?p=3623187#p3623187"]но если у вас питание пропадает всякий раз, это вам мало чем поможет... тут придется действовать гораздо хитрее. самый надежный вариант - использовать отдельную RC-цепочку на одном из входов, и после сброса сразу же смотреть, какое на этой емкости напряжение. если питание было, было (емкость зарядилась), а потом пропало ненадолго, то после восстановления питания емкость еще будет заряжена "с прошлого раза", и вы это обнаружите по высокому уровню на соответствующем пине МК. если же питание пропало надолго, емкость успеет разрядиться, и после сброса вы увидите на ней 0, т.к. заряжаться она будет не мгновенно.[/uquote]

можно по подробнее на счет

Код: Выделить всё

__attribute__((section(".noinit"))) uint8_t test;
как этим воспользоваться

Добавлено after 14 minutes 39 seconds:
применительно к моему примеру

Код: Выделить всё

unsigned char reg __attribute__ ((section (".noinit")));

.....

if (reg==0xFF)
	{
		TestBoard();
	}

....

мне нужно задать адресацию или он вседа будет в одно и тоже место писать, и если нужно то
и еще добавить в линкер чтото типа этого:

Код: Выделить всё

avr-gcc ... -Wl,--section-start=.noinit=0x80007D ...
Реклама
Эиком - электронные компоненты и радиодетали
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

ничего добавлять никуда не надо, .noinit - это "стандартная" секция avr-gcc, в ней можно помещать любые глобальные (и static тоже) переменные, которые код инициализации (т.е. тот, который исполняется до входа в main) не должен обнулять.

Добавлено after 45 minutes 28 seconds:
alexadrenalin писал(а):пишу для готовой платы
для готовой платы можно поиграться емкостью входов - там несколько пикофарад есть.
китайские фонарики на attiny13 вполне себе существуют и работают по такому принципу: если кнопкой питания делается "быстрый клик", то переключается режим свечения, а если "медленный", то происходит простое выключение/включение предыдущего режима. при этом программно осуществляется измерение напряжения на "болтающемся" входе АЦП. после подачи питания этот вход "заряжают" от встроенной подтяжки, а после сброса смотрят, какое там напряжение. принцип тот же, что я и описал - емкость некоторое время сохраняет заряд...

но для вещей серьезнее фонарика я бы такой вариант не советовал, ибо влажность, температура, пыль-грязь - все это будет менять зарядно-разрядные параметры болтающегося входа МК, забодаетесь калибровать или бороться с ложными срабатываниями...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

А как на счет детектора питания и eeprom?
Реклама
Родился
Сообщения: 6
Зарегистрирован: Чт апр 25, 2019 20:37:26

Сообщение alexadrenalin »

нашел вариант такой:

volatile uint8_t *semaphore = (volatile uint8_t *)0x0060;

...
if (*sempaphore) {
// semaphore was set
}

и в настройках линковщива в miscellaneous

-Wl,--section-start=.data=0x800061

вроде не чистит, но и переменная не держит такое впечатление

Добавлено after 2 minutes 59 seconds:
[uquote="Dimon456",url="/forum/viewtopic.php?p=3623328#p3623328"]А как на счет детектора питания и eeprom?[/uquote]
eeprom используется для фатальных записей ошибок, но как отследить просто переход через ноль было или выключение.... детектора питания нет на плате=(
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

alexadrenalin писал(а):нашел вариант такой:

volatile uint8_t *semaphore = (volatile uint8_t *)0x0060
:facepalm: нафига я вообще здесь?! :facepalm:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Родился
Сообщения: 6
Зарегистрирован: Чт апр 25, 2019 20:37:26

Сообщение alexadrenalin »

[uquote="ARV",url="/forum/viewtopic.php?p=3623469#p3623469"]
alexadrenalin писал(а):нашел вариант такой:

volatile uint8_t *semaphore = (volatile uint8_t *)0x0060
:facepalm: нафига я вообще здесь?! :facepalm:[/uquote]
опечатка на форуме было так:

Код: Выделить всё

volatile uint8_t *semaphore = (volatile uint8_t *)0x60;
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

:facepalm: :facepalm: :facepalm: :facepalm: :facepalm: :facepalm: :facepalm: :facepalm: :facepalm: :facepalm:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Родился
Сообщения: 6
Зарегистрирован: Чт апр 25, 2019 20:37:26

Сообщение alexadrenalin »

https://www.avrfreaks.net/forum/noinit- ... ttribute__((section(%22.noinit%22)))

Добавлено after 1 minute 41 second:
наверное не так понял
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

alexadrenalin писал(а):но как отследить просто переход через ноль было или выключение
Поясните, что есть переход через ноль? А что есть выключение?
Родился
Сообщения: 6
Зарегистрирован: Чт апр 25, 2019 20:37:26

Сообщение alexadrenalin »

там тумблер, в середине - нет питания на плату, верхнее и нижнее положения рабочие. Если перевести переключатель из одного крайнего в другое, то происходит потеря питания на плате (я назвал через ноль). Иногда это приводит к переинициализации всей платы иногда нет (когда медленно или быстро). Выключение - это перевели тумблер нейтраль и ушли, секунда, минута и больше значит выключили.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Попробуйте так unsigned char reg __attribute__ ((section (".eeprom")));
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3623593#p3623593"]Попробуйте так unsigned char reg __attribute__ ((section (".eeprom")));[/uquote]
фигню советуете
во-первых, для работы с секцией .eeprom есть более удобный макрос EEMEM
во-вторых, простым "отображением" переменной на секцию .eeprom ничего не делается - от слова вообще
в-третьих, если даже предположить, что работа с секцией .eeprom сделана верно, то по содержимому EEPROM нельзя отследить, пропадало питание или нет, ибо эта память и предназначена для того, чтобы хранить данные при отсутствии питания.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

ARV писал(а):то по содержимому EEPROM нельзя отследить, пропадало питание или нет, ибо эта память и предназначена для того, чтобы хранить данные при отсутствии питания.
Но ему же надо сохранить переменную, вот пусть и сохраняет. А бит BORF ему не поможет, это частный случай, один на миллион, ладно бы от батареи еще питал, хотя этот случай может иметь место.
alexadrenalin писал(а):Иногда это приводит к переинициализации всей платы иногда нет (когда медленно или быстро).
А так конденсатор по питанию побольше поставить и проблема будет решена.
Ответить

Вернуться в «AVR»