программный сброс мк ATtiny2313

Обсуждаем контроллеры компании Atmel.
Ответить
Встал на лапы
Аватара пользователя
Сообщения: 120
Зарегистрирован: Сб апр 20, 2013 16:38:32
Откуда: Страна Чудес

Сообщение ATMEL86 »

Привет всем! Скажите пожалуйста как сбросить мк ?

На пример:

if (a==1 ){//если "а"
код сброса

}
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18711
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

правильный вариант такой:
1. запретить прерывания
2. активировать WDT на самый короткий интервал срабатывания
3. уйти в вечный цикл

рекомендуемый многими (не мной) вариант - перейти на адрес 0х0000:

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

void (*reset)(void) = (void*)0;
if (a==1 ){//если "а" 
   reset();
}
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3490
Зарегистрирован: Вт окт 22, 2013 04:37:23
Откуда: Казань

Сообщение smacorp »

ATMEL86 писал(а):как сбросить мк ?
http://www.atmel.com/webdoc/AVRLibcRefe ... reset.html
Платы для HLDI - установки лазерной засветки фоторезиста.
Фоторезист Ordyl Alpha 350
Жидкое олово для лужения плат (видео) - самое лучшее и только у меня.
Паяльные маски XV501T-4 и KSM-S6189 (5 цветов).
Заказ печатных плат - pcbsmac@gmail.com
Встал на лапы
Аватара пользователя
Сообщения: 120
Зарегистрирован: Сб апр 20, 2013 16:38:32
Откуда: Страна Чудес

Сообщение ATMEL86 »

Добрый вечер ARV ! Большое спасибо за код , всё отлично работает :beer: :))

Уважаемый ARV ! расскажите немного про эту функцию: void (*reset)(void) = (void*)0;
Реклама
Эиком - электронные компоненты и радиодетали
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18711
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

ATMEL86 писал(а):расскажите немного про эту функцию: void (*reset)(void) = (void*)0;
это не функция.
это определение переменной типа указатель на функцию

разбор строки (слева направо):
1. void - тип
2. (*reset) - если в скобках и первый символ * - это означает указатель на функцию, имя этой переменной-указателя reset
3. (void) - это параметры функции, на которую будет этот указатель указывать. т.е. функция без параметров
4. после знака равенства - начальное значение переменной reset
5. (void*) - это явное приведение типа последующей константы 0, т.е. в переменную reset мы записываем число 0, которое приводим к типу указатель

итак, мы имеем переменную-указатель, проинициализированную значением 0, и имеющую тип функция

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

обращаю ваше внимание, что я не рекомендовал этот способ, хотя и рад, что у вас все получилось. этот способ не меняет аппаратное состояние встроенной периферии микроконтроллера - таймеры продолжают работать, АЦП, компаратор и т.п. тоже, состояние портов остается прежним... только при аппаратном сбросе вся периферия устанавливается в определенное начальное состояние. в крайнем случае, если вы любитель CVAVR, вы можете понадеяться на код, генерируемый "мастером", но это дурной тон в программировании.

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

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 120
Зарегистрирован: Сб апр 20, 2013 16:38:32
Откуда: Страна Чудес

Сообщение ATMEL86 »

Ещё раз спасибо разъяснение ARV! :)) Да, я пользуюсь мастером CVAVR пока всё устаревает программки работают отлично ! Но что бы писать без помощи мастера, мне ещё нужно много практиковаться писать код и читать литературы. :oops:
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Похожий способ - ассемблерная вставка asm("rjmp 0"), это гораздо более очевидно, но менее переносимо.
Еще вариант - вызов неправильного прерывания (у которого не прописан обработчик). Gcc в этом случае сбрасывает программу (точнее, идет вызов прерывания BADISR_vect, который используется крайне редко). Недостаток тот же - возможные проблемы с переносимостью. Зато работает даже в области самозагрузчика, если, конечно, туда переместили таблицу прерываний.
Встал на лапы
Аватара пользователя
Сообщения: 120
Зарегистрирован: Сб апр 20, 2013 16:38:32
Откуда: Страна Чудес

Сообщение ATMEL86 »

скажите пожалуйста! если применить сторожевой таймер?

if (a==1 ){//сравниваем "а" на единицу
#asm("cli") // запрет глоб. прерывания
сторожевой таймер

}

как правильно написать?
Друг Кота
Аватара пользователя
Сообщения: 3490
Зарегистрирован: Вт окт 22, 2013 04:37:23
Откуда: Казань

Сообщение smacorp »

ATMEL86 писал(а):если применить сторожевой таймер?
как правильно написать?
Мда... :? :facepalm:
Спойлерhttp://radiokot.ru/forum/viewtopic.php?p=2808919#p2808919
Платы для HLDI - установки лазерной засветки фоторезиста.
Фоторезист Ordyl Alpha 350
Жидкое олово для лужения плат (видео) - самое лучшее и только у меня.
Паяльные маски XV501T-4 и KSM-S6189 (5 цветов).
Заказ печатных плат - pcbsmac@gmail.com
Прорезались зубы
Аватара пользователя
Сообщения: 240
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

Сообщение AlanDrakes »

Эм.. Мой костыль где-то в недрах проекта:

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

		case Packet_RESET_SYS:
		{
			// Перезапуск железки.
			console_print_timestamp();
			console_put_fromPGM(TXT_REBOOT_SYS);
			_delay_ms(150); // А пауза нужна для того, чтобы в консоль успело вывалиться соответствующее сообщение.
			asm("ijmp" :: "z" (0x0000));	// RESET vector
			// (╯°益°)╯彡┻━┻
			break;	// L0L!
		};
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

А зачем косвенный прыжок, если достаточно
asm("rjmp 0"); / asm("jmp 0");
Друг Кота
Аватара пользователя
Сообщения: 15631
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Ну уж ежли корректно... то...
программным способом без дополнительной внешней схемотехники...
НИКАК...

Ибо автоматическая предустановка регистров спецфункций у АВРок иначе чем внешним сигналом на лапке сброса не будет соответствовать данному состоянию (аппаратный сброс при подаче питания).
Несколько корректнее воспользоваться WDT - но ... там ведь тоже уже состояние регистров будет соответствовать "сбросу по WDT".
Так что или действительно сброс переходом на 0х0000 (неважно jmp, rjmp или ijmp) НО... потребуется обязательный участок аналитики типа сброса и модиффикации текущего состояния регистров в зависимости от того, чем вызван старт с адреса 0х0000.
Или внешней схемотехникой, управляемой или с вывода МК или с внешнего устройства, управляется при помощи того МК.
:roll:
Прорезались зубы
Аватара пользователя
Сообщения: 240
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

Сообщение AlanDrakes »

COKPOWEHEU писал(а):А зачем косвенный прыжок, если достаточно
asm("rjmp 0"); / asm("jmp 0");
Про RJMP - если сброс находится за "Более чем 2к слов", то не дотянется.
JMP почему-то у меня не сработал.
Пришлось шагать в обход. :solder:
Да и универсальность. Можно подсунуть в качестве точки перехода, например, адрес секции собственного загрузчика.
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

В *jmp тоже можно подставить любой адрес. Что jmp не сработал - довольно странно, впрочем лично не проверял.
Разве что rjmp / jmp выполняются на пару тактов быстрее.
Ответить

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