Страница 1 из 1

Atmega8,работа с прерываниями и таймерами

Добавлено: Вс июл 19, 2009 16:20:20
boobonick
Здравствуйте,подскажите пожалуйста, только учусь, не могу понять алгоритм работы с таймером и прерыванием. Вот мои мысли:

1.Выбираем время переполнения Timer0.

2.Если таймер переполнен,то происходит прерывание функции main() и переход на функцию timer_ovf.

3.Установка нулевого уровня на PORTB.

Как происходит выход из прерывания?А после PORTB=0x00 должен быть переход в главную функцию?


#include<mega8>

interrupt[TIM0_OVF] void timer_ovf(void)
{
PORTB=0x00;

}
main(){
while(1){
DDRB=0xFF;
PORTB=0xFF;
TIMSK = 0b00000001; //Разрешить прерывание при переполнении //TOIEI1
TCCR0 = 0b00000101; //делим на 1024

#asm("sei");
}
}

Добавлено: Вс июл 19, 2009 16:59:10
ARV
прежде всего - что вы хотите получить? ну выставился 0 на порту у вас по прерыванию - и что дальше?

в основном цикле у вас инициализация таймера не нужна, вынесите ее за пределы цикла в начало main, а вот PORTB=0xFF - это вы что хотели этим сделать? в общем, в том виде, как сейчас у вас получится через промежутки переполнения таймера на порту очень-очень коротенькие импульсы нулевого уровня на фоне постоянной единицы...

Добавлено: Вс июл 19, 2009 17:27:16
boobonick
Спасибо за информацию, кажется я не добавил #asm("cli"), чтобы выйти из прерывания и еще delay_ms в главную функцию, чтобы можно было лицезреть это все с задержкой.... и получилось. Мигает)

Добавлено: Вс июл 19, 2009 17:36:29
ARV
boobonick писал(а):Спасибо за информацию, кажется я не добавил #asm("cli"), чтобы выйти из прерывания и еще delay_ms в главную функцию, чтобы можно было лицезреть это все с задержкой.... и получилось. Мигает)
чтобы выйти из прерывания вам ничего добавлять не надо было. а чтобы мигало по-человечески, надо было сделать так:

Код: Выделить всё

#include<mega8> 
interrupt[TIM0_OVF] void timer_ovf(void){ 
   PORTB ^=0xFF; 
}
 
main(){ 
   DDRB=0xFF; 
   TIMSK = 0b00000001; //Разрешить прерывание при переполнении //TOIEI1 
   TCCR0 = 0b00000101; //делим на 1024 
   #asm("sei"); 
   while(1); 
} 
разберетесь, почему так? ;)

Добавлено: Вс июл 19, 2009 18:01:44
boobonick
:) Понятно. А вот если мы хотим реализовать длинный отчет времени (как пример -часы), чем лучше пользоваться таймерами МК(и возможно ли это) или программными средствами (циклы)?

Добавлено: Вс июл 19, 2009 18:25:21
ARV
boobonick писал(а)::) Понятно. А вот если мы хотим реализовать длинный отчет времени (как пример -часы), чем лучше пользоваться таймерами МК(и возможно ли это) или программными средствами (циклы)?
про "часы" как прибор измерения времени - это вы смотрите в сторону либо спецмикросхем, либо таймера 2 с асинхронным режимом... а если речь просто о выдержках интервалов "в часах" - можно и так и эдак, хотя по таймеру будет конечно гораздо точнее получаться, чем программно.
например:

Код: Выделить всё

#include<mega8> 
interrupt[TIM0_OVF] void timer_ovf(void){ 
   static int counter = 1000;
   if(!--counter){
      PORTB ^=0xFF; 
      counter = 1000;
   }
} 
  
main(){ 
   DDRB=0xFF; 
   TIMSK = 0b00000001; //Разрешить прерывание при переполнении //TOIEI1 
   TCCR0 = 0b00000101; //делим на 1024 
   #asm("sei"); 
   while(1); 
}
простой пример "замедления" в 1000 раз вашего "мигания" :)

Добавлено: Вс июл 19, 2009 19:04:44
boobonick
Спасибо! :)))