Перейти к содержанию
    

Доброго вечера!

Заметил такую особенность: при "небольшом" загрязнении между контактами TX и RX (видимо электрический контакт появился), функция gets() безнадежно зависла. Подумал, что хорошо бы запустить перед началом gets() сторожевой таймер, который сбросит контроллер в случае зависания, мало ли чего. WDT запустил путем записи в его регистр сначала комбинации битов, разрешающих изменение режима WDT, а потом записал нужное значение. Через положеные 8 секунд произошол сброс контроллера. Попробовал остановить WDT путем записи в его регистр 0x00. Но эффекта не последовало, произошел сброс... Что делать?!?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

WDT запустил путем записи в его регистр сначала комбинации битов, разрешающих изменение режима WDT, а потом записал нужное значение. Через положеные 8 секунд произошол сброс контроллера. Попробовал остановить WDT путем записи в его регистр 0x00. Но эффекта не последовало, произошел сброс... Что делать?!?

 

А вы пытались останавить его тоже комбинацией или простой записью?

Может быть так попробовать:

 

WDTCSR |= (1<<WDCE);

WDTCSR = 0;

 

или так:

 

WDTCSR |= (1<<WDCE) | (1<<WDE);

WDTCSR = 0;

 

Только не забудьте прерывания блокировать на время исполнения этих двух строк.

Ну в крайнем случае так:

 

cli();

wdt_reset();

MCUSR &= ~(1<<WDRF);

WDTCSR |= (1<<WDCE) | (1<<WDE);

WDTCSR = 0;

sei();

 

Ну тут уж кажется всё предусмотрено с запасом...

Изменено пользователем Xenia

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Доброго вечера!

Подумал, что хорошо бы запустить перед началом gets() сторожевой таймер, который сбросит контроллер в случае зависания, мало ли чего.

Вы бы лучше подумали - а нужна ли такая "полезная" функция. Которая видимо тупо ждет прихода чего бы то ни было в UDR. Используйте нормальный драйвер работающий по прерываниям.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вы пытались останавить его тоже комбинацией или простой записью?

Может быть так попробовать:

 

WDTCSR |= (1<<WDCE);

WDTCSR = 0;

 

или так:

 

WDTCSR |= (1<<WDCE) | (1<<WDE);

WDTCSR = 0;

 

Так пробовал, непомогло.

 

А вот следующий вариант выглядит убедительно! Что-то я припоменаю про MCUSR при сбросе бита WDE... :) Пойду попробую!

 

 

Вы бы лучше подумали - а нужна ли такая "полезная" функция. Которая видимо тупо ждет прихода чего бы то ни было в UDR. Используйте нормальный драйвер работающий по прерываниям.

 

Ну дак у меня gets() и находится в блоке обработки прерывания, вызываемого при приеме очередного символа по USART!

 

INTERRUPT (SIG_USART_RCV)

{

gets();

}...

 

Или вы имеете ввиду посимвольно считывать строку???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вы пытались останавить его тоже комбинацией или простой записью?

Может быть так попробовать:

 

WDTCSR |= (1<<WDCE);

WDTCSR = 0;

 

или так:

 

WDTCSR |= (1<<WDCE) | (1<<WDE);

WDTCSR = 0;

 

Только не забудьте прерывания блокировать на время исполнения этих двух строк.

Ну в крайнем случае так:

 

cli();

wdt_reset();

MCUSR &= ~(1<<WDRF);

WDTCSR |= (1<<WDCE) | (1<<WDE);

WDTCSR = 0;

sei();

 

Ну тут уж кажется всё предусмотрено с запасом...

Даже не знаю где здесь указывать на "неправильности"... поэтому текст не сокращаю,

ВСЕ показанные варианты не применимы.... тк принципиально зависят от уровня оптимизации компилятора...

Ну нельзя пользовать |= в ситуации наличии 4 тактов для операции и все тут... ну повторим это в 125раз...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну нельзя пользовать |= в ситуации наличии 4 тактов для операции и все тут... ну повторим это в 125раз...

 

Ой! А как же тогда быть? Использовать простое приравнивание REGISTOR=0x05?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ВСЕ показанные варианты не применимы.... тк принципиально зависят от уровня оптимизации компилятора...

Ну нельзя пользовать |= в ситуации наличии 4 тактов для операции и все тут... ну повторим это в 125раз...

 

Вот, пожалуйста, результат компиляции на IAR EWAVR:

 

WDTCR |= (1<<WDCE) | (1<<WDE); 
00000000   B501               IN      R16, 0x21
00000002   6108               ORI     R16, 0x18
00000004   BD01               OUT     0x21, R16

WDTCR = 0; 
00000006   E000               LDI     R16, 0
00000008   BD01               OUT     0x21, R16

 

- между записями в регистр WDTCR только одна лишняя команда. Итого всего 2 такта между операциями записи.

А про оптимизацию вы не совсем правы, когда речь идет о записи в регистры, то компилятор (IAR) никогда не опускает присваивание, даже если оно повторное. И это при любом типе оптимизации - как по размеру, так и по скорости.

Однако не забывайте название темы - сказано, что WatchDog запустить удалось. А, значит, компиляция велась в условиях, когда требование 4-х тактов соблюдалось. Поэтому это условие я не стала особо оговаривать.

Изменено пользователем Xenia

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

- между записями в регистр WDTCR только одна лишняя команда. Итого всего 2 такта между операциями записи.
Один раз повезло другой нет...

так и рождаются легенды...

 

 

 

Ой! А как же тогда быть? Использовать простое приравнивание REGISTOR=0x05?
Лучше всего заготовьте ВСЕ константы заранее а потом их присваивайте регистрам...

 

 

 

А про оптимизацию вы не совсем правы, когда речь идет о записи в регистры, то компилятор (IAR) никогда не опускает присваивание, даже если оно повторное. И это при любом типе оптимизации - как по размеру, та и по скорости.
я как раз и не забываю, и volatile у Вашего регистра как раз и заставляет делать много(иногда >4) операций

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Один раз повезло другой нет...

так и рождаются легенды...

 

Длиннее просто невозможно скомпилировать, т.к. операции с константами всегда производятся еще при компиляии, а не в runtime.

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

 

Лучше всего заготовьте ВСЕ константы заранее а потом их присваивайте регистрам...

 

Константы невозможно "приготовить заранее". Если вы намереваетесь поместить их в память, то вытаскивание оттуда обойдется дороже - тогда действительно в 4 такта можно не уложиться. А если положить в регистр, то примерно так оно и получится.

 

P.S. Мой предыдущий пост, адресованный вам, был мною отредактирован. Ознакомьтесь с ним пожалуйста еще разик.

Изменено пользователем Xenia

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что меняет выбор варианта оптимизации? В AVR Studio есть варианты: О0 - Оs. Поисковик ничего не выдал.

 

Спасибо! Замечание с константами я учту на будущее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Константы невозможно "приготовить заранее". Если вы намереваетесь поместить их в память, то вытаскивание оттуда обойдется дороже - тогда действительно в 4 такта можно не уложиться. А если положить в регистр, то так оно и получится.
Я Вам и предлагаю положить их(константы) во временные регистры...

P.S. Мой предыдущий пост, адресованный вам, был мною отредактирован. Ознакомьтесь с ним пожалуйста еще разик.
Вы очень настойчивая девушка... , хотя наверное это и не плохо... но очень торопитесь...

не спешите в своих суждениях... :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы очень настойчивая девушка... , хотя наверное это и не плохо... но очень торопитесь...

не спешите в своих суждениях...

 

Докажите обратное! Приведите результат компиляции этих двух сишных строк, чтобы компилятор допустил больше одной промежуточной инструкции между записями в регистр WDTCR. Условия оптимизации можете выбирать любые.

Изменено пользователем Xenia

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что меняет выбор варианта оптимизации? В AVR Studio есть варианты: О0 - Оs. Поисковик ничего не выдал.
Все меняет, если хотите работу на С для таких вариантов(4такта на все) то только -Os или -O2 рулит..

Спасибо! Замечание с константами я учту на будущее.
Ну и подготовленные заранее константы рулят всегда...

 

 

 

Докажите обратное! Приведите результат компиляции этих двух сишных строк, чтобы компилятор допустил больше одной промежуточной инструкции между записями в регистр WDTCR. Условия оптимизации можете выбирать любые.
Ксения, я Вам позволю самой воспользоваться поиском, особенно по теме записи в EEPROM, и там Вы найдете

ВСЕ ответы, в том числе и мои...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо! Замечание с константами я учту на будущее.

 

В данном случае варианты компиляции выражения

WDTCR |= (1<<WDCE) | (1<<WDE);

несущественны, поскольку запись в регистр WDTCR всегда будет ПОСЛЕДНЕЙ инструкцией. А, стало быть, протяжка перед следующей строкой

WDTCR = 0;

зависит исключительно от сложности обнуления регистра. Дольше двух тактов это не затянется при любых способах оптимизации или отсутствия оной.

Изменено пользователем Xenia

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дольше двух тактов это не затянется при любых способах оптимизации или отсутствия оной.
Давайте Вы уже избавитесь от илюзий и попробуете это сделать совсем без оптимизации..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...