Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ATtiny26 + 2 таймера
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
all-nic
Добрый день господа!
Помогите найти ошибку в исходном коде.
Два таймера вместе не хотят работать - только 1 из двух. Причем тот - который последний инициируешь. по отдельности работают. ATtiny26

// иниацилизируем счетчик Timer/Counter1

TIMSK = (1<<TOIE1); // разрешаем прерыв от 8-разр счётчика
TCCR1B = (1 << CS10)|(0 << CS11)|(0 << CS12)|(1 << CS13); //коэф деления 1/1024
TCNT1 = 0x00; // начало отсчета )

// иниацилизируем счетчик Timer/Counter0

TIMSK = (1<<TOIE0); // разрешаем прерыв от 8-разр счётчика
TCCR0 = (1 << CS00)|(0 << CS01)|(1 << CS02); //коэф деления 1/1024
TCNT0 = 0x00;

sei (); // разрешаем прерыв


// ( Прерывание ) счетчик 0го таймера
//------------------------------------------------------------------------------

ISR(SIG_OVERFLOW0) {

perv++;
TCNT0 = 0; // обновить число начал счета
TIFR = (1<<TOV0);
}


// ( Прерывание ) счетчик 1го таймера
//------------------------------------------------------------------------------

ISR(SIG_OVERFLOW1) {

vtor++;
TCNT1 = 0; // обновить число начал счета
TIFR = (1<<TOV1);

}



И далее в общем наброски программы:

unsigned char walk(void) {

if (perv==30) {

perv=0; //сбрасываем в нач счета 0й таймер
Led_inv_R;

}

if (vtor==300) {

vtor=0; //сбрасываем в нач счета 1й таймер
Led_inv_G;

}
return (0);
}

Контролирую это двумя светодиодами. Можно было и все сделать на одном таймере, но хотелось бы разобраться с двумя таймерами.
Спасибо!
haker_fox
QUOTE (all-nic @ Jun 13 2011, 21:20) *
// иниацилизируем счетчик Timer/Counter1

TIMSK = (1<<TOIE1); // разрешаем прерыв от 8-разр счётчика
TCCR1B = (1 << CS10)|(0 << CS11)|(0 << CS12)|(1 << CS13); //коэф деления 1/1024
TCNT1 = 0x00; // начало отсчета )

// иниацилизируем счетчик Timer/Counter0

Вот тут Вы запрещаете прерывания от первого таймера, т.к. перезаписываете регистр TIMSK новым значением
TIMSK = (1<<TOIE0); // разрешаем прерыв от 8-разр счётчика
TCCR0 = (1 << CS00)|(0 << CS01)|(1 << CS02); //коэф деления 1/1024
TCNT0 = 0x00;

sei (); // разрешаем прерыв


Сделайте так. Обратите внимание на "трубу" | - логическое или. Таким образом в регистре TIMSK установлено два разряда, разрешающих прерывания от соответствующих таймеров.
CODE
// иниацилизируем счетчик Timer/Counter1

    TIMSK = (1<<TOIE1);    // разрешаем прерыв от 8-разр счётчика
    TCCR1B = (1 << CS10)|(0 << CS11)|(0 << CS12)|(1 << CS13);    //коэф деления 1/1024
    TCNT1 = 0x00;    // начало отсчета )
    
// иниацилизируем счетчик Timer/Counter0

         [b]Вот тут Вы запрещаете прерывания от первого таймера, т.к. перезаписываете регистр TIMSK новым значением[/b]
    TIMSK |= (1<<TOIE0);    // разрешаем прерыв от 8-разр счётчика
    TCCR0 = (1 << CS00)|(0 << CS01)|(1 << CS02);    //коэф деления 1/1024
    TCNT0 = 0x00;
    
    sei (); // разрешаем прерыв

Xenia
1) Уберите
TIFR = (1<<TOV0);
TIFR = (1<<TOV1);
из процедур обработки прерывания, этого не нужно, т.к если прерывание произошло, то этот флаг сбрасывается сам.
А вот присваивать TIFR'у значение вредно, т.к. вредит другому таймеру. И если уж так хочется сбрасывать TIFR сручную, то делайте это с одним битом, а не со всем его содержимым.

2) Командой
TIMSK = (1<<TOIE0);
в 4-ой строке вы убиваете ранее занесенное туда значение
TIMSK = (1<<TOIE1);
в 1-ой строке кода.
Вы хоть понимате, что TIMSK один на оба таймера и после второго присваивания эффект прошлого присваивания пропадает?
Это и есть ваша ошибка, из-за которой первый из программируемых таймеров перестает работать, как только вы программируете второй.
Надо писать
TIMSK = (1<<TOIE1) | (1<<TOIE0);
сразу для двух таймеров
или для второго таймера ДОБАВЛЯТЬ бит:
TIMSK |= (1<<TOIE0);
all-nic
Спасибо огромное! Много времени убил вычисляя этот глюк.
TIMSK |= (1<<TOIE0); // разрешаем прерыв от 8-разр счётчика
Это правильное решение.
all-nic
Большое спасибо за подсказку.
Свою ошибку понял.
TIFR = (1<<TOV0);
TIFR = (1<<TOV1); вставил от безисходности, пробовал все.
Убрал - работает.
TIMSK |= (1<<TOIE0); Вот так правильно.
ae_
Цитата(Xenia @ Jun 13 2011, 22:12) *
И если уж так хочется сбрасывать TIFR сручную, то делайте это с одним битом, а не со всем его содержимым. И тогда уж стирайте его, а не устанавливайте.

Не вводите в заблуждение!
TOV0; TOV1 регистра TIFR СБРАСЫВАЮТСЯ В НОЛЬ записью в них ЕДИНИЦЫ.
Xenia
Цитата(ae_ @ Jun 13 2011, 19:33) *
Не вводите в заблуждение!
TOV0; TOV1 регистра TIFR СБРАСЫВАЮТСЯ В НОЛЬ записью в них ЕДИНИЦЫ.

Согласна.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.