Пятница, 26.04.2024, 20:12
Микроконтроллерная техника AVR
Главная Регистрация Вход
Приветствую Вас, Гость · RSS
Меню сайта
Помоги сайту
Поддержи наш сайт
Через WebMoney
U222865683087
R391933670808
Z877043628365
E649133782052

или пополни нашу SMS копилку
SMS.копилка

Ссылки

 Каталог статей
Главная » Статьи » Учимся работать с AVR

Учимся использовать таймер. :)
На этом примере хочу показать Вам как задействовать один из таймеров МК АТМеga8. Давайте сделаем простой счетчик который будет считать от 0 до 99, и чтобы он когда будет 30 сек. на одном из портов выдавал +5 вольт и продолжал выдавать пока таймер не дойдет то 99 и обнулиться.  
Немного теории. Таймер – это регистр, в котором выполняются некоторые действия (инкрементирование, декрементирование ….) с частотой, на которой был выставлен таймер.
Итак, приступим к созданию кода программы. Нам нужно чтобы некоторая переменная инкрементировалась, с частотой в 1 сек., и эта переменная выводилась на дисплее.
Откроем Code Vision AVR, создадим проект с помощью Wizard'a выберем следующие настройки:

Выберем МК и частоту, подключим LCD к PORTD а PORTB делаем все ножки как выход Output value = 0.

В параметрах таймера выберем Timer 1, Clock Value 7,813 kHz, Interrupt on: Compare A Match, Comp. A = 1e85 (это чисто обозначает что он будет тактироваться с частотой в 1 секунду)
clock value - частота счета
Interrupt on Compare A match - прерывание по совпадению с регистром А


Здесь мы немного остановимся. Итак, чтобы правильно посчитать какова частота работы таймера 
нужно открыть инженерный калькулятор. Число 1e85 (оно в 16-чной системе счисления) =7813 в 10ситичной с/ч. С этого следует что 7813(частота прерывания = 1 Гц)*5(сек)=39065 и перевести это в 16чную с/ч тогда мы получим 9899, вот это число вставляем в Comp. A и наш таймер будет работать с частотой 0,2 Гц то есть 1раз в 5секунд.
Генерируем код и сохраняем.
Дальше, мы видим код нашего таймера:
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Place your code here
   
}
Нужно вставить в середину следующий код:
TCNT1H=0;
TCNT1L=0;  
Для корректной роботы таймера эти регистры обязательно присвоить 0. И еще в «тело» таймера добавим переменную которую будем инкрементировать (num++).
Вот каков наш таймер получился в итоге.

interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
  TCNT1H=0;
  TCNT1L=0;
  num++;  
}

Весь код программы:

#include <mega8.h>
#asm
  .equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
 unsigned int num; // наша переменная  
// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Place your code here
  TCNT1H=0;
  TCNT1L=0;
  num++; // инкрементирруем
   
}
// Declare your global variables here
void main(void)
{
PORTB=0x00;
DDRB=0xFF;

PORTC=0x03;
DDRC=0x00;

PORTD=0x00;
DDRD=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x1E;
OCR1AL=0x85;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x10;

lcd_init(16);

// Global enable interrupts
#asm("sei")

while (1)
  { // Place your code here 
  if (num==30) //если 30 сек. "зажигаем" ПОРТ В.0 
  PORTB.0=1;
   
  if (num==100) // если num = 100 сек. зануляем num и тушим ПОРТ В.0
  {
    num=0;
    PORTB.0=0;
  }
  // выводим значение переменной на экран
  lcd_gotoxy(0,0);  
  lcd_putchar(num/10+0x30);
  lcd_putchar(num%10+0x30);

  };
}

 А вот и сама схема:

Частоту выставить 8 МГц. Прошивка, исходник и файл Proteus'a в катологе "Файлы".
Огромная благодарность KDAlex'y в написании этой статьи.

Категория: Учимся работать с AVR | Добавил: my-avr (12.01.2009)
Просмотров: 55354 | Комментарии: 13 | Рейтинг: 3.0/5 |
Всего комментариев: 131 2 »
13 Иван  
-3
"и наш таймер будет работать с частотой 0,2 Гц то есть 1раз в 5секунд"
0,2 Гц ета 1раз в 5секунд? :-)

12 Сулейман  
0
Всем привет.
какое название LCD ?

11 Jman  
0
Объясните пожалуйста чайнику откуда взялось число 1е85? Почему решили взять именно это число?

10 kost_kot  
0
Дмитрий - СПАСИБО ! очень понятно разжевано. сделал все с первого прочтения! по-моему - самое толковое разъяснение работы с прерываниями по совпадению! еще раз - спасибо !

9 Artur  
0
Пытаюсь повторить данный проект, только с прерыванием в полсекунды. Высчитал что в Comp. A надо задать 0F42h, но в протеусе и в живую прерывание происходит раз в 8 сек! Изменение значения Comp. A на меньшее ни на что не влияет ): Просто не могу понять в чем дело.

Вот код прошивки :

#include <mega8.h>

int i = 0;

interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
if (i == 1)
{
PORTB.0 = 0;
i = 0;
}
else
{
PORTB.0 = 1;
i = 1;
}
}

void main(void)
{
PORTB=0x00;
DDRB=0xFF;

PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0x00;

TCCR0=0x00;
TCNT0=0x00;

TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x03;
OCR1AL=0x0D;
OCR1BH=0x00;
OCR1BL=0x00;

ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

MCUCR=0x00;

TIMSK=0x10;

ACSR=0x80;
SFIOR=0x00;

#asm("sei")

while (1)
{
}
}

8 Дмитрий  
0
Понятно - это когда так:

Необходимый интервал - 5 мс. Поехали:

Частота 16 МГц.
Использую 16-ти битный таймер. Делитель таймера 8. Следовательно:
16 / 8 = 2 МГц частота таймера.
2000000 / 65536 = 30,517578125 Гц частота "переполнения". Или же 1 / 30,517578125 = 0,032768 сек. время одного "переполнения".
В одном "переполнении" у нас 65536 тиков. Следовательно 0,032768 / 65536 = 0,0000005 сек. время одного тика таймера.
Чтобы получить 0,005 сек необходимо чтобы таймер тикнул 0,005 / 0,0000005 = 10000 раз.
10000 в 16-тиричной системе это 2710.

Его и записываем в прерывание по совпадению.


7 White_leo  
0
ну смотри если часики у нас тактирутся с частотой 7,813 килогерц(за одну секунду сделает 7813 тиков), то чтобы отмерить одну секунду в Comp A вставляем именно 7813 ( мы хотим чтобы он сделал 7813 тиков прежде чем вызовет прерывание). если нужно 0.5с то Comp A = (7813/2) = 3906. если нужно 0,1с то Comp A = (7813/10) = 781. так понятней?

6 Дмитрий  
0
Элементарные моменты все разжевывают на пальцах, а сложные как будто специально опускают. Я понимаю что 7813 результат деления (...256,1024...), причем тут одна секунда? Ну объясните дибилу на яблоках.... в конце то концов

5 Leon  
1
если хочется заставить таимер работать 1 сек, то в comp A вставляем 7813 переведенную в 16ричку т.е. 1e85
теперь обьясняю: Clock Value 7,813 kHz азначает что таимер делит 8 000 000 hz на 1024 что в итоге палучается 7,813. если вместо 7813 вставить 31,250 то таимер поделит 8000000 на 256 что в итоге палучается 31,250. остальные делит на 64, 8 и 1, соответственно получается 125,000, 1 000 000, и 8 000 000. теперь если мы хотим чтоб таимер тикал в 1 секунду, и если у нас в Clock Value стаит 7,813, то в comp A нада вписать
7,813 переведенную в 16-чную систему счисления. что соответствует 1e85. если у нас в Clock Value стаит 31,250 то в comp A нада вписать 31,250 переведенную в 16-чную систему счисления что соответствует 7A12. и тд. и тп. в конце Ячеики рядом с comp A стаит h что и азначает hex т.е. 16-чная системф счисления. ну об остальном сами дадумаитесь

4 devil  
0
Добрый день, уважаемый автор и все! подскажите как заставить в CodeVisionAVR таймер выдавать прерывания каждую секунду. Кварц стоит 4 МГц.

1-10 11-13
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Copyright My-AVR © 2024
Наша кнопка
У нас появилась кнопка, код кнопки:

Лаборатория самоделок на микроконтроллерах AVR

Форма входа
Наш опрос
Как вам материалы на сайте
Всего ответов: 863
Статистика/Друзья
CY-PR.com



Онлайн всего: 1
Гостей: 1
Пользователей: 0

РадиоКОТ - популярно об электронике. Авторские схемы, новые разработки. Обучение по электронике, микроконтроллерам, ПЛИС. Форум Сайт по радиоэлектронике. У нас все просто и интересно… ARV Reserch: Электроника — просто, полезно, увлекательно. Электронные устройства и программные средства для радиолюбителей и профессионалов, только авторские разработки, плагиата нет! Разработки на заказ. AVR projects Создание электронных роботов своими руками Схемы и программы на AVR http://ur5yfv.ucoz.ua/BANNER.gif Блог начинающего эмбеддера. Дай волю паяльнику! Самоделки на all-make.ru Принципиальные схемы Модулі автозапуску бензогенератора та системи АВР, електромонтажні роботи
Хостинг от uCoz