Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с авр
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
Andrew82
Начал изучать авр и не могу разобраться с таймерами к авр на порт д подключен семисегментный индикатор раз в сек он должен увеличивать цифру т.е. от 0 до девяти и так далее в чем ошибка подскажите? Симулирую на протеусе все файлы в архиве. Помогите и подскажите.
ivstech
Разрешите прерывания
Andrew82
void main()
{
io_init();
timer0_init();
Dig_init();
PORTD = Dig[0];
#asm("sei"); // тут глобально разрешил прерывания
while(1)
{}
}
но в протеусе все равно не вижу то что хочется подскажите чуть развернутее
Aesthete Animus
2Andrew82

Из Вашегоисходника:
Код
void timer0_init()
{
  SREG |= (1 << 7);
  OCR0 = 1;  // Таймер срабатывает каждые 1024 такта. Прерывание каждые
  // 1024*16 тактов.
  TCCR0 |= (1 << WGM01) | (1 << CS00) | (1 << CS02);
  TIMSK |= (1 << OCIE0);
  TIFR |=(1 << 1);
}


По порядку
"SREG |= (1 << 7);" - необходимости в такой конструкции нет, хотя и она вполне законна. Лучше было написать sei() или #asm("sei") или __asm__ __volatile__ ("sei" :: ), в зависимости от компилятора.

"OCR0 = 1; // Таймер срабатывает каждые 1024 такта. Прерывание каждые 1024*16 тактов." - Непонятно... (С)

"TIFR |=(1 << 1);" - Зачем это?

"TIMSK |= (1 << OCIE0);" - а вот тут похоже и зарыта собака. Вы включаете прерывание по сравнению, но обрабатываете похоже прерывание по переполнению. Вот это у вас далее по тексту:
Код
interrupt [TIM0_OVF] void timer0_ovf_isr(void)


Пожалуйста, указывайте явно, какой используете контроллер и компилятор.
Andrew82
[---skipped---]


void timer0_init()
{
#asm("sei");
OCR0 = 16; // Таймер срабатывает каждые 1024 такта. Прерывание каждые 1024*16 тактов.
TCCR0 |= (1 << WGM01) | (1 << CS00) | (1 << CS02); //
TIMSK |= (1 << TOIE0);
} так я понимаю будет правильно да? указываю что прерываение по переполнению TOIE0 это 0 бит
переделанный исходник в архиве, кодевижион компилятор и чип мега 16


Moderator to
Andrew82: избегайте бездумного цитирования постов.
Aesthete Animus
Цитата(Andrew82 @ Jan 7 2008, 18:56) *
void timer0_init()
{
#asm("sei");
OCR0 = 16; // Таймер срабатывает каждые 1024 такта. Прерывание каждые 1024*16 тактов.
TCCR0 |= (1 << WGM01) | (1 << CS00) | (1 << CS02); //
TIMSK |= (1 << TOIE0);
} так я понимаю будет правильно да? указываю что прерываение по переполнению TOIE0 это 0 бит
переделанный исходник в архиве, кодевижион компилятор и чип мега 16


Да нет, же, вы же хотите получить "Прерывание каждые 1024*16 тактов". Для это и устанавливаете OCR = 16. В строчке "TIMSK |= (1 << OCIE0);" ничего неправильного не было. Только нужно при этом обрабатывать прерывание по сравнинию, но у вас был написан обрботчик по переполнению [TIM0_OVF]. Я в CV не работал, но наверное TIM_OVF означает переполнение.
bloodden
//Инициализация таймера
// Timer/Counter 0 initialization
// Clock source: System Clock
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x05;
TCNT0=0x16;
OCR0=0x00;


//Включаем прерывания по ПЕРЕПОЛНЕНИЮ от него
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;




//функция, которая исполняется с частотой (частота_кварца/1024)/16
//кстати, частота эта будет для 4МГц кварца 244 Гц. далеко не 1....
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0x16;
// Place your code here

}


В кодевизионе это же делается элементарно с помощью мастера!
И с помощью него же по сравнению сделать элементарно.
Хотя некоторые и говорят, что его мастер только калечит головы начинающим программистам МК, с НАЧАЛА он очень помогает, а потом сам перестаёш его пользовать по одной простой причине: переходиш на другой компилятор.
Andrew82
Все всем спасибо все во внеминательности я то хотел по сравнению, а не по переполнению, спасибо всем откликнувшимся, пойду дальше изучать.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.