|
Неправильная работа Watch Dog Timer'a, WDT не работает |
|
|
|
Jun 19 2013, 11:50
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608

|
Прошу помощи у Клуба!
Проблема в неправильной работе Watch Dog Timer'a на ATmega640-16AU. Суть в следующем: после запуска Watch Dog Timer'a в режиме "System Reset Mode" через запрограммированое (2 сек) время камень не перезапускается (System Reset), а тупо виснет. Проверку осуществляю при помощи вставленных циклов ожидания функции __delay_cycles().
Компилятор IAR EWB v.6.21.1. Прошивка в железо - AVReal. Инициализация в основной программе (main): // Инициализация Watchdog-таймера _WDR(); // Сброс Watchdog WDTCSR |= (1<<WDCE)|(1<<WDE); WDTCSR = (1<<WDE)|(1<<WDP2)|(1<<WDP1)|(1<<WDP0); // Установка времени срабатывания ~2 с _SEI(); // Глобальное разрешение прерывания
Фьюз WDTON=1. Сама программа без WDT или с включённым WDT, но без принудительной сверхзадержки работает без проблем. Аналогичные варианты других программ, но на камнях ATmega64 с идентичными параметрами (инициализация, фьюзы, способы проверки срабатывания WDT) работают тоже без проблем.
|
|
|
|
|
Jun 19 2013, 13:33
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608

|
Убрал. Стало: // Инициализация Watchdog-таймера _WDR(); // Сброс Watchdog WDTCSR = (1<<WDCE)|(1<<WDE); WDTCSR = (1<<WDE)|(1<<WDP2)|(1<<WDP1)|(1<<WDP0); // Установка времени срабатывания ~2 с _SEI(); // Глобальное разрешение прерывания
В работе ничего не поменялось!
|
|
|
|
|
Jun 19 2013, 14:02
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608

|
К регистру MCUSR я вообще не обращаюсь. Листинг функции main: 448 // Инициализация Watchdog-таймера 449 _WDR(); // Сброс Watchdog \ 000002A8 95A8 WDR 450 WDTCSR = (1<<WDCE)|(1<<WDE); \ 000002AA E108 LDI R16, 24 \ 000002AC 9300.... STS _A_WDTCSR, R16 451 // WDTCSR = (1<<WDE)|(1<<WDP3); // Установка времени срабатывания ~4 с 452 WDTCSR = (1<<WDE)|(1<<WDP2)|(1<<WDP1)|(1<<WDP0); // Установка времени срабатывания ~2 с \ 000002B0 E00F LDI R16, 15 \ 000002B2 9300.... STS _A_WDTCSR, R16 453 _SEI(); // Глобальное разрешение прерывания \ 000002B6 9478 SEI Сам файл листинга = 1,2Мб загружаться не хочет. Цитата(Палыч @ Jun 19 2013, 16:48)  А, если убрать глобальное разрешение прерываний ? Тогда ничего работать не будет: В проге задействовано 4 USARTa, SPI, 2T/C. А, вцелом, я вначале описал, что если отключить WDT, то всё прекрасно работает. Ещё одна подозрительная тонкость: после зависа проги по WDT и дальнейшей перепрошивки проги заново - завис не прекращается, нужно обязательно передёрнуть питание. После этого прога начинает работать (до следующего срабатывания WDT).
|
|
|
|
|
Jun 19 2013, 14:12
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608

|
Цитата(_Артём_ @ Jun 19 2013, 17:11)  Возможно это связано с несброшенным битом WDRF в регистре MCUSR. И когда его сбрасывать?
|
|
|
|
|
Jun 19 2013, 14:20
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608

|
Цитата(SerSh @ Jun 19 2013, 17:12)  И когда его сбрасывать? Перед инициализацией WDT сбросил этот бит: clrbit (MCUSR, WDRF);. Не помогло!
|
|
|
|
|
Jun 19 2013, 15:07
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(SerSh @ Jun 19 2013, 18:02)  Тогда ничего работать не будет: В проге задействовано 4 USARTa, SPI, 2T/C. А, вцелом, я вначале описал, что если отключить WDT, то всё прекрасно работает. Давайте "отделим мух от котлет"! Без WDT Ваша программа правильно работает. Вот и чудесно. WDT без Вашей программы работает ? Проверяли ? Если - нет, проверьте... Я думаю, что тоже будет работать... Для проверки работы WDT с программой Вы вставили задержку __delay_cycles(), вероятно, перед сбросом WDT (может, я и не прав, но так понял из Вашего первого сообщения). Как предположение: эта задержка приводит к краху части функционала программы, но та часть, что отвечает за сброс WDT продолжает работать, при этом, поскольку остальная часть не работает, то время на __delay_cycles(), вероятно, уменьшилось и сброс WDT производится с периодом меньшим 2 сек, что приводить к отсутствию сброса МК. Для проверки работы WDT совместно с программой я бы убрал __delay_cycles(), а вместо него либо - "глухой" цикл при запрещенных прерываниях, либо флаг и проверка флага: взведен - то сброс WDT не производить.
|
|
|
|
|
Jun 19 2013, 15:51
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608

|
Цитата(Палыч @ Jun 19 2013, 18:07)  WDT без Вашей программы работает ? Кажется работает. Я вводил задержку специально чтобы сымитировать ситуацию "зависание - рестарт". Если задержку не вводить, то программа работает, и WDT как-то там себе живёт, не беспокоит. Цитата(Палыч @ Jun 19 2013, 18:07)  Как предположение: эта задержка приводит к краху части функционала программы... Как может цикл портить функционал программы мне не понятно. Цитата(Палыч @ Jun 19 2013, 18:07)  , но та часть, что отвечает за сброс WDT продолжает работать, при этом, поскольку остальная часть не работает, то время на __delay_cycles(), вероятно, уменьшилось и сброс WDT производится с периодом меньшим 2 сек, что приводить к отсутствию сброса МК. Происходит не отсутствие сброса МК, а его полной замерзание, даже перепрограммирование не помогает, а только выключение питания. Цитата(Палыч @ Jun 19 2013, 18:07)  Для проверки работы WDT совместно с программой я бы убрал __delay_cycles(), а вместо него либо - "глухой" цикл при запрещенных прерываниях, либо флаг и проверка флага: взведен - то сброс WDT не производить. Не совсем понятна идея. Если поставить просто глухой цикл типа while(1);, то всё повторяется - зависание. При этом не важно: открыты или закрыты все прерывания (проверял только что).
Сообщение отредактировал SerSh - Jun 19 2013, 15:52
|
|
|
|
|
Jun 19 2013, 16:43
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(SerSh @ Jun 19 2013, 19:51)  Кажется работает. Кажется? Или, всё-таки - работает? Цитата(SerSh @ Jun 19 2013, 19:51)  Как может цикл портить функционал программы мне не понятно. А, нам-то и подавно не понятно, поскольку Вы как партизан молчите о том, куда Вы задержку вставили... Цитата(SerSh @ Jun 19 2013, 19:51)  Если поставить просто глухой цикл типа while(1);, то всё повторяется - зависание. При этом не важно: открыты или закрыты все прерывания (проверял только что). А, если вместо всяких циклов/задержек просто закомментировать стоку сброса WDT - будет ли Ваша программа рестартовать каждые 2 сек ?
|
|
|
|
|
Jun 19 2013, 20:45
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608

|
Цитата(Палыч @ Jun 19 2013, 19:43)  Кажется? Или, всё-таки - работает? Я в предыдущем посте описал работу программы. А слово "кажется" использовал специально для Вас. ))) Цитата(Палыч @ Jun 19 2013, 19:43)  А, нам-то и подавно не понятно, поскольку Вы как партизан молчите о том, куда Вы задержку вставили... Задержку вставил сразу после инициализации WDT. И вовсе я не партизан, просто это не имеет значения. Её куда ни вставь, она и в Африке задержка. Цитата(Палыч @ Jun 19 2013, 19:43)  А, если вместо всяких циклов/задержек просто закомментировать стоку сброса WDT - будет ли Ваша программа рестартовать каждые 2 сек ? А вот это завтра утром на работе попробую. А сейчас - спать. Спокойной ночи, господа, спокойной ночи!...
|
|
|
|
|
Jun 20 2013, 06:15
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 19-12-08
Из: г.Северодонецк, Украина
Пользователь №: 42 608

|
Закомментировал все команды WDR, но всё осталось по-прежнему: через 2 сек. после старта - завис. Такое впечатление, что он уходит в рестарт, но попадает не на начальный адрес старта, а на какой-нибудь бутлоадер, которого на самом деле нет, и, пробегая по пустым местам, возвращается обратно, при этом портя стек.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|