Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Микропроцессорная курсовой.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
935.94 Кб
Скачать

2.2 Робота з таймерами/лічильниками мк avr

У мікроконтролерах AVR може бути до 4х таймерів/лічильників (МК). Розрядність цих таймерів 8 або 16 біт (тобто вони можуть рахувати до 28=256 або до 216=65536). Зазвичай їх використовують для точного формування часових інтервалів, підрахунку імпульсів на виводах мікроконтролера, формування послідовності імпульсів. Таймери здатні виробляти запити на переривання, при цьому звільняючи процесор від необхідності опитування стану таймерів. Розглянемо роботу таймерів і переривань, які вони можуть виробляти, на прикладі 16-ти бітного таймеру/лічильнику1 (ТС1) мікроконтролера ATmega8. Всього у цього МК три таймера - два 8-ми бітних (ТС0, ТС2) та один 16 бітний (ТС1). Поглянемо на таблицю векторів переривань МК Atmega8 - 7 переривань пов'язані з таймерами мікроконтролера, з них 4 пов'язані з таймером/ лічильником1 (ТС1). Давайте розберемося, що ж може цей таймер, які регістри ним керують і що в них треба записати, щоб налаштувати таймер як нам потрібно. Для початку розглянемо всі регістри ТС1 і за що який біт відповідає, а потім розглянемо простий приклад з налаштування таймера. Почнемо з регістрів управління таймером.

TCCR1A - регістр управління A

Біти 7:6 - COM1A 1:0: контролюють поведінку виходу OC1A (див. Таблицю 4).

Біти 5:4 - COM1B 1:0: контролюють поведінку виходу OC1B (див. Таблицю 4).

Таблиця 4 – Стан виходів OC1A та OC1B за події порівняння по каналу А та В

Біти 3:2 - FOC1A, FOC1B: служать для примусового зміни стану виходів OC1A і OC1B.

Біти 1:0 - WGM11, WGM10: служать для налаштування ТС1 для роботи в якості широтно-імпульсного модулятора (ШІМ). У режимі ШІМ стан виходів OC1A і OC1B буде відрізнятися.

TCCR1B - регістр управління

Біт 7 - ICNC1: придушення брязкоту контактів на вході ICP1. Якщо біт встановлений, то визначення події на вході ICP1 відбувається із затримкою на 4 машинних цикли.

Біт 6 - ICES1: вибір фронту спрацьовування переривання по захопленню. Якщо встановлений - на зростаючому фронті, якщо скинутий - на падаючому фронті.

Біт 5 - не використовується

Біти 4:3 - WGM1 3:2: для налаштування ШІМу.

Біти 2:0 - CS1 2:0: вибір тактування ТС1 (Таблиця 5).

Таблиця 5 – Вибір тактування таймеру 1.

Після налаштування таймеру з частотою, яку ми обрали в регістрі TCCR1B лічильник таймера починає рахувати і записувати значення лічильника в регістри TCNT1H і TCNT1L - старший і молодший байт рахункового регістра. При досягненні TCNT1 значення 65536 лічильник переповнюється і скидається, і починає рахунок заново. В цей регістр ми також можемо записати якесь значення, з якого ми хочемо, щоб наш лічильник стартував. Для 16-бітної операції запису, старший байт повинен бути записаний першим. Молодший - другим. Для операції 16-бітного читання, молодший байт повинен бути прочитаний першим, а вміст старшого байта зчитується другим. Якщо ми налаштували зміну стану входу OC1A або OC1B, тоді значення рахункового регістра порівнюється кожен раз зі значенням регістрів OCR1A і OCR1B - регістри порівняння. Кожен із цих регістрів складається з двох байт (наприклад, OCR1AH та OCR1AL). Ми можемо записати в ці регістри потрібне нам значення і за збігом значення регістра лічильника з регістром порівняння буде відбуватися потрібне нам зміна на виходах OC1A і OC1B. У МК також є регістр захоплення входу - ICR1 (ICR1H і ICR1L). Значення TCNT1 в цей регістр записується при настанні події на вході ICP1.

Крім рахунку і зміни стану ніжок МК цей таймер може при певних подіях генерувати переривання. Як ми вже бачили в таблиці векторів переривань у ТС1 є 4 вектора переривання - переривання по захопленню, переривання за збігом А, переривання за збігом, переривання по переповненню (перелічені в порядку зменшення пріоритету). Розглянемо регістри, налаштовуючи які можна управляти перериваннями ТС1.

TIMSK - регістр маски переривань таймерів/лічильників

Біт 7 - OCIE2: переривання за збігом ТС2

Біт 6 - TOIE2: переривання по переповнюванню ТС2

Біт 5 - TICIE1: переривання по захопленню ТС1

Біт 4 - OCIE1A: переривання за збігом A ТС1

Біт 3 - OCIE1B: переривання за збігом В ТС1

Біт 2 - TOIE1: переривання по переповнюванню ТС1

Біт 1 - не використовується

Біт 0 - TOIE0: переривання по переповнюванню ТС0

Якщо відповідний біт встановлений в "1" і біт I (7-й біт) регістра станів SREG встановлений в "1", тоді відповідне переривання буде спрацьовувати.

TIFR - регістр прапорів переривань таймерів/лічильників

Прапори відповідають переривань у регістрі TIMSK. Встановлюються в "1" при виконанні умов відповідного переривання.

Інші таймери налаштовуються аналогічним чином. Тепер ми можемо узагальнити і записати якими можливостями володіє цей таймер:

  • Лічильник 16-ти бітний (16 бітний ШІМ);

  • Два незалежних виходу, що спрацьовують за збігом;

  • Один вхід по захопленню події (росте або падає фронт) і придушення брязкоту контактів на цьому вході;

  • Тактування від вбудованого тактового генератора або зовнішнього джерела тактування (T1);

  • 4 незалежних переривання.

Розглянемо приклад реалізації таймера/лічильника. На рис. 2 наведена принципова схема пристрою. Таймер/лічильник включає та виключає світлодіод D1 з частотою 1 Гц.

 

Рисунок 2. – Генератор сигналу включення світлодіода.

Розглянемо програму зроблену у середовищі CodeVisionAVR, що реалізує даний пристрій.

1

#include <mega8.h>

2

// Timer1 output compare A interrupt service routine

3

interrupt [TIM1_COMPA] void timer1_compa_isr(void)

4

{

5

// Place your code here

6

TCNT1H=0x00;//

7

TCNT1L=0x00;//

8

}

9

void main(void)

10

{

11

DDRB=0x02; // налаштовуємо біт 1 порту В як вихід

12

PORTB=0x00;

13

TCCR1A=0x40; // рівень сигналу на виході ОС1А змінюється

14

//на протилежний

15

TCCR1B=0x05; // тактову частоту ділимо на 1024

16

TCNT1H=0x00; // у рахункові реєстри спочатку "зі скількох рахуємо" (старший)

17

TCNT1L=0x00; // записуємо 0 "зі скількох рахуємо" (молодший)

18

OCR1AH=0x03; // до скількох рахувати (старший регістр)

19

OCR1AL=0xЕ8; // до скількох рахувати (молодший регістр)

20

// Timer(s)/Counter(s) Interrupt(s) initialization

21

TIMSK=0x10;

22

23

// Global enable interrupts

#asm("sei")// дозволяємо обробку переривань

24

while (1)

25

{

26

27

// Place your code here

}

28

}