Страница 1 из 1

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

Добавлено: Пт июл 15, 2016 10:24:51
ATMEL86
Привет всем! Скажите пожалуйста как сбросить мк ?

На пример:

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

}

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

Добавлено: Пт июл 15, 2016 10:41:57
ARV
правильный вариант такой:
1. запретить прерывания
2. активировать WDT на самый короткий интервал срабатывания
3. уйти в вечный цикл

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

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

void (*reset)(void) = (void*)0;
if (a==1 ){//если "а" 
   reset();
}

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

Добавлено: Пт июл 15, 2016 10:48:03
smacorp
ATMEL86 писал(а):как сбросить мк ?
http://www.atmel.com/webdoc/AVRLibcRefe ... reset.html

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

Добавлено: Пт июл 15, 2016 20:47:39
ATMEL86
Добрый вечер ARV ! Большое спасибо за код , всё отлично работает :beer: :))

Уважаемый ARV ! расскажите немного про эту функцию: void (*reset)(void) = (void*)0;

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

Добавлено: Пт июл 15, 2016 20:57:37
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 - самый корректный с любой точки зрения вариант программного сброса микроконтроллера. хотя и не такой лаконичный в виде кода.

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

Добавлено: Пт июл 15, 2016 22:37:03
ATMEL86
Ещё раз спасибо разъяснение ARV! :)) Да, я пользуюсь мастером CVAVR пока всё устаревает программки работают отлично ! Но что бы писать без помощи мастера, мне ещё нужно много практиковаться писать код и читать литературы. :oops:

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

Добавлено: Пт июл 15, 2016 22:47:06
COKPOWEHEU
Похожий способ - ассемблерная вставка asm("rjmp 0"), это гораздо более очевидно, но менее переносимо.
Еще вариант - вызов неправильного прерывания (у которого не прописан обработчик). Gcc в этом случае сбрасывает программу (точнее, идет вызов прерывания BADISR_vect, который используется крайне редко). Недостаток тот же - возможные проблемы с переносимостью. Зато работает даже в области самозагрузчика, если, конечно, туда переместили таблицу прерываний.

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

Добавлено: Пт июл 15, 2016 23:10:56
ATMEL86
скажите пожалуйста! если применить сторожевой таймер?

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

}

как правильно написать?

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

Добавлено: Сб июл 16, 2016 07:21:19
smacorp
ATMEL86 писал(а):если применить сторожевой таймер?
как правильно написать?
Мда... :? :facepalm:
Спойлерhttp://radiokot.ru/forum/viewtopic.php?p=2808919#p2808919

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

Добавлено: Вс июл 17, 2016 12:11:09
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!
		};

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

Добавлено: Вс июл 17, 2016 13:15:26
COKPOWEHEU
А зачем косвенный прыжок, если достаточно
asm("rjmp 0"); / asm("jmp 0");

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

Добавлено: Вс июл 17, 2016 16:46:35
BOB51
Ну уж ежли корректно... то...
программным способом без дополнительной внешней схемотехники...
НИКАК...

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

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

Добавлено: Вс июл 17, 2016 18:29:18
AlanDrakes
COKPOWEHEU писал(а):А зачем косвенный прыжок, если достаточно
asm("rjmp 0"); / asm("jmp 0");
Про RJMP - если сброс находится за "Более чем 2к слов", то не дотянется.
JMP почему-то у меня не сработал.
Пришлось шагать в обход. :solder:
Да и универсальность. Можно подсунуть в качестве точки перехода, например, адрес секции собственного загрузчика.

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

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