Свежие обсуждения
Микроконтроллеры

Вопросы по ATmega8

1 3

Добрый день, подскажите правильно так работать с Watchdog Timer в CodeVision

Инициализируем:
// Инициализация Watchdog Timer и его запуск
// Делитель таймера Watchdog: OSC/1024k
#pragma optsize-
WDTCR=0x1E;
WDTCR=0x0E;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

И работаем:

void WDT_off(void) // Остановить WDT
{
#asm("wdr"); // Сбросить WDT
WDTCR |= (14) | (13); // Записать "1" в 4й бит (WDCE) и 3й бит (WDE) регистра WDTCR
WDTCR |= (03); // Записать "0" в 3й бит (WDE) регистра WDTCR
}

вот здесь (14); INSERT INTO `message` VALUES (13); INSERT INTO `message` VALUES (03) между цифрами 2 знака меньше - "сдвиг" их просто не видно

void WDT_on(void) // Запустить WDT
{
#asm("wdr"); // Сбросить WDT
WDTCR=0x1E;
WDTCR=0x0E; // Запустить WDT
}

это правильно?

 

Lerik:

WDTCR |= (0<<3); // Записать "0" в 3й бит (WDE) регистра WDTCR


Ноль надо записывать не так

WDTCR &=~(1<<3);

 

Спасибо, а все остальное правильно, в смысле алгоритма ?
И как у тебя получилось знак меньше нарисовать?

 

Lerik: Спасибо, а все остальное правильно, в смысле алгоритма ?

Значит так...

Отключение (заметь, из даташита ):


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

Лучше так. Какой смысл беречь остальные биты? И есть шанс не успеть за 4 такта...

Запуск:


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

 

Lerik: И как у тебя получилось знак меньше нарисовать?

Надо вместо знака меньше писать знак амперсанда (на клавише с цифрой 7), буквы lt и точку с запятой. Извини, но написать это я не смог, проглатывается Вот: & lt; (только без пробела) &lt;

 

АНТОХА: Какой смысл беречь остальные биты? И есть шанс не успеть за 4 такта...
Вот это - WDTCR = 0; меня и смутило, типа зачем обнулять все, правильнее было бы один битик поменять... но с другой стороны в данном случае и беречь вроде не обязательно
В даташите еще есть такая команда перед изменением битов #asm("wdr"); // Сбросить WDT
ты ее не написал, она же нужна нужна?

Спасибо за консультацию !!!

Попутно еще один вопрос, нигде не смог прочитать от чего срабатывает прерывание по АЦП ?
interrupt [ADC_INT] void adc_isr(void) {
adc_data=ADCW;
}

То ли после конца преобразования (ведь мы ее инициализируем частоту преобразования), то ли по изменению самого кода АЦП после преобразования. Из sleep он отчего просыпается непонятно....

unsigned int read_adc(void) { // Read the AD conversion result with noise canceling
ADMUX=0xC0;
#asm
in r30,MCUCR
cbr r30,__sm_mask
sbr r30,__se_bit | __sm_adc_noise_red
out MCUCR,r30
sleep
cbr r30,__se_bit
out MCUCR,r30
#endasm
return adc_data;

 

Оттого и просыпается, что включен noise reduction. Когда выполняется sleep, в это же момент автоматически запускается АЦП. Прерывание от него появляется обычным порядком, когда в регистре данных готова оцифрованная выборка, никаких изменений в его работе в связи с шумопонижением нет.

 

т.е. после цикла преобразования да ? Не взирая на то, что сигнал на входе АЦП не менялся? Если скажем подать на вход стабилизированные 3В, то после каждого цикла преобразования будем получать код соответствующий 3м вольтам, я правильно понимаю?
и начинается цикл преобразования по команде sleep ?

 

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

 

Это понятно, спасибо.
А по ходу выполнения программы:
процессор останавливается после команды sleep ? на ней самой и ждет прерывание, так?
а когда же выполняются 2 оператора после sleep ? Или после обработки прерывания он возвращается на них и дальше идет по ходу программы?