Съдържание:

AVR микроконтролер. Светодиоди мигат с помощта на таймер. Таймери Прекъсва. Таймер CTC режим: 6 стъпки
AVR микроконтролер. Светодиоди мигат с помощта на таймер. Таймери Прекъсва. Таймер CTC режим: 6 стъпки

Видео: AVR микроконтролер. Светодиоди мигат с помощта на таймер. Таймери Прекъсва. Таймер CTC режим: 6 стъпки

Видео: AVR микроконтролер. Светодиоди мигат с помощта на таймер. Таймери Прекъсва. Таймер CTC режим: 6 стъпки
Видео: Какво и Как да правим с Микроконтролери - Невен Боянов 2024, Ноември
Anonim
Image
Image

Здравейте всички!

Таймерите са важна концепция в областта на електрониката. Всеки електронен компонент работи по време. Тази времева база помага да се поддържа цялата работа синхронизирана. Всички микроконтролери работят на някаква предварително зададена тактова честота, всички те имат възможност за настройка на таймери. AVR може да се похвали с наличието на таймер, който е много точен, прецизен и надежден. Той предлага много функции в него, което го прави обширна тема. Най -хубавото е, че таймерът е напълно независим от процесора. По този начин той работи успоредно на процесора и няма намеса на процесора, което прави таймера доста точен. В този раздел обяснявам основните понятия на AVR таймерите. Пиша проста програма в C код за управление на LED мигач, използвайки таймери.

Стъпка 1: Описание

Постановка на проблем 1: Нека премигнем първия светодиод (зелен) на всеки 50 ms
Постановка на проблем 1: Нека премигнем първия светодиод (зелен) на всеки 50 ms

В ATMega328 има три типа таймери:

Timer/Counter0 (TC0) - е 8 -битов модул Timer/Counter с общо предназначение, с две независими OutputCompare единици и PWM поддръжка;

Таймер/Брояч1 (TC1) - 16 -битовият модул Таймер/Брояч позволява точно време за изпълнение на програмата (управление на събития), генериране на вълни и измерване на сигнала;

Таймер/Брояч2 (TC2) -е общо предназначение, канал, 8 -битов модул Таймер/Брояч с ШИМ и асинхронна работа;

Стъпка 2: Постановка на проблем 1: Нека премигнем първия светодиод (зелен) на всеки 50 ms

Постановка на проблем 1: Нека премигнем първия светодиод (зелен) на всеки 50 ms
Постановка на проблем 1: Нека премигнем първия светодиод (зелен) на всеки 50 ms
Постановка на проблем 1: Нека премигнем първия светодиод (зелен) на всеки 50 ms
Постановка на проблем 1: Нека премигнем първия светодиод (зелен) на всеки 50 ms

Методология:

- използване на предусилвател Timer0 за намаляване на високочестотен електрически сигнал до по -ниска честота чрез цялостно разделяне;

- използване на прекъсване всеки път, когато Timer0 препълва;

Timer0 (8 бита) брои от 0 до 255 след това, те преливат, тази стойност се променя при всеки тактов импулс.

F_CPU = 16MHz: Часовник период = 1000ms / 16000000Hz = 0.0000625ms

Брой таймер = (Необходимо забавяне / Часовник) -1 = (50ms / 0.0000625ms) = 799999

Часовникът вече е тиктакал 799999 пъти, за да даде закъснение от само 50 мс!

Можем да използваме техника за разделяне на честотата, наречена прескалиране, за да намалим броя на таймера. AVR ни предлага следните стойности на предварителния дебитор, от които да избираме: 8, 64, 256 и 1024. Вижте таблицата, обобщаваща резултатите от използването на различни предусилватели.

Стойността на брояча винаги трябва да бъде цяло число. Нека изберем предсказващо устройство 256!

В повечето микроконтролери има нещо, наречено Прекъсване. Това прекъсване може да се задейства, когато са изпълнени определени условия. Сега, когато се задейства прекъсване, AVR спира и запазва изпълнението на основната рутина, посещава повикването за прекъсване (като изпълнява специална рутина, наречена рутина на услугата за прекъсване, ISR) и след като приключи с нея, се връща към main и продължава да го изпълнява.

Тъй като необходимото забавяне (50ms) е по -голямо от максималното възможно забавяне: 4, 096ms = 1000ms / 62500Hz * 256, очевидно таймерът ще препълни. И когато таймерът препълни, се прекъсва.

Колко пъти трябва да се задейства прекъсването?

50ms / 4.096ms = 3125 /256 = 12.207 Ако таймерът е прелетял 12 пъти, 12 * 4.096ms = 49.152ms биха преминали. В 13 -тата итерация се нуждаем от закъснение от 50ms - 49.152ms = 0.848ms.

При честота от 62500Hz (предсказващо = 256), всяка отметка отнема 0.016ms. По този начин, за да се постигне забавяне от 0,848ms, ще са необходими 0,848ms / 0,016ms = 53 отметки. По този начин, в 13 -та итерация, ние позволяваме на таймера да брои само до 53 и след това да го нулираме.

Инициализирайте Таймер 0/Брояч (вижте снимката):

TCCR0B | = (1 << CS02) // настройка на таймер с прескалиране = 256 TCNT0 = 0 // инициализиране на брояча TIMSK0 | = (1 << TOIE0) // активиране на прекъсване на преливане sei () // активиране на глобални прекъсвания tot_overflow = 0 // инициализира променлива брояч на препълване

Стъпка 3: Постановка на проблем 2: Нека мигаме втори светодиод (син) на всеки 1 секунди

Изложение на проблема 2: Нека мигаме втори светодиод (син) на всеки 1 секунди
Изложение на проблема 2: Нека мигаме втори светодиод (син) на всеки 1 секунди
Изложение на проблема 2: Нека мигаме втори светодиод (син) на всеки 1 секунди
Изложение на проблема 2: Нека мигаме втори светодиод (син) на всеки 1 секунди
Изложение на проблема 2: Нека мигаме втори светодиод (син) на всеки 1 секунди
Изложение на проблема 2: Нека мигаме втори светодиод (син) на всеки 1 секунди

Методология:

- използване на предусилвател Timer1 за намаляване на високочестотен електрически сигнал до по -ниска честота чрез цялостно разделяне;

- използване на режим Clear Timer on Compare (CTC);

- използване на прекъсвания с режим CTC;

Таймер1 (16 бита) брои от 0 до 65534 след това, те преливат. Тази стойност се променя при всеки тактов импулс.

F_CPU = 16MHz: Период на часовник = 1000ms / 16000000Hz = 0.0000625ms Брой на таймера = (Необходимо забавяне / Период на часовник) -1 = (1000ms / 0.0000625ms) = 15999999

Часовникът вече е тиктакал 15999999 пъти, за да даде закъснение от 1s!

Можем да използваме техника за разделяне на честотата, наречена прескалиране, за да намалим броя на таймера. AVR ни предлага следните стойности на предварителния дебитор, от които да избираме: 8, 64, 256 и 1024. Вижте таблицата, обобщаваща резултатите от използването на различни предусилватели. Стойността на брояча винаги трябва да бъде цяло число. Нека изберем предсказващо устройство 256!

В режим Clear timer on Compare (CTC) регистърът OCR1A или ICR1 се използва за манипулиране на разделителната способност на брояча. В режим CTC броячът се изчиства до нула, когато стойността на брояча (TCNT1) съвпада или с OCR1A, или с ICR1. OCR1A или ICR1 определят горната стойност на брояча, следователно и неговата разделителна способност. Този режим позволява по -голям контрол на изходната честота за сравняване на мачовете. Той също така опростява операцията за преброяване на външни събития. Трябва да кажем на AVR да нулира Timer1/Counter веднага щом стойността му достигне стойност 62500, като по този начин се постигне закъснение от 1s.

Инициализирайте Таймер 1/Брояч (вижте снимката):

TCCR1B | = (1 << WGM12) | (1 << CS12) // настройка на таймер с предсказване = 256 и режим CTC TCNT1 = 0 // инициализиране на брояча TIMSK1 | = (1 << OCIE1A) // разрешаване на прекъсване за сравнение OCR1A = 62500 // инициализира стойността за сравнение

Стъпка 4: Постановка на проблем 3: Нека мигаме третият светодиод (червен) на всеки 16ms

Твърдение за проблем 3: Нека мигаме третият светодиод (червен) на всеки 16ms
Твърдение за проблем 3: Нека мигаме третият светодиод (червен) на всеки 16ms
Твърдение за проблем 3: Нека мигаме третият светодиод (червен) на всеки 16ms
Твърдение за проблем 3: Нека мигаме третият светодиод (червен) на всеки 16ms
Твърдение за проблем 3: Нека мигаме третият светодиод (червен) на всеки 16ms
Твърдение за проблем 3: Нека мигаме третият светодиод (червен) на всеки 16ms
Твърдение за проблем 3: Нека мигаме третият светодиод (червен) на всеки 16ms
Твърдение за проблем 3: Нека мигаме третият светодиод (червен) на всеки 16ms

Методология:

- използване на предусилвател Timer2 за намаляване на високочестотен електрически сигнал до по -ниска честота чрез цялостно разделяне;

- използване на режим Clear Timer on Compare (CTC);

- използване на хардуерен режим CTC без прекъсвания;

Таймер 2 (8 бита) брои от 0 до 255 след това, те преливат. Тази стойност се променя при всеки тактов импулс.

F_CPU = 16MHz: Часовник период = 1000ms / 16000000Hz = 0.0000625ms

Брой таймер = (Необходимо забавяне / Часовник) -1 = (16ms / 0.0000625ms) = 255999

Часовникът вече е тиктакал 255999 пъти, за да даде закъснение от 16ms!

Вижте таблицата обобщава резултатите от използването на различни предусилватели. Стойността на брояча винаги трябва да бъде цяло число. Нека изберем предсказващо устройство 1024!

В режим CTC броячът се изчиства до нула, когато стойността на брояча (TCNT2) съвпада или с OCR2A, или с ICR2. ПИН PB3 е също извод за сравнение на изхода на TIMER2 - OC2A (вижте диаграмата).

Таймер/Контролен регистър2 Регистър за управление A - TCCR2A Бит 7: 6 - COM2A1: 0 - Сравнете изходния режим за единица за сравнение A. Тъй като трябва да превключваме светодиода, ние избираме опцията: Превключване на OC2A при сравняване на съвпадението Когато възникне съвпадение на сравнение, ПИН OC2A се превключва автоматично. Няма нужда да проверявате нито един флаг, няма нужда да се грижите за прекъсвания.

Инициализирайте Таймер 2/Брояч

TCCR2A | = (1 << COM2A0) | (1 << WGM21) // настройте таймера OC2A щифт в режим на превключване и режим CTC TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20) // настройка на таймер с предсказване = 1024 TCNT2 = 0 // инициализиране на брояча OCR2A = 250 // инициализиране на стойността за сравнение

Стъпка 5: Писане на код за програма на C. Качване на HEX файл във флаш паметта на микроконтролера

Писане на код за програма на C. Качване на HEX файл във флаш паметта на микроконтролера
Писане на код за програма на C. Качване на HEX файл във флаш паметта на микроконтролера
Писане на код за програма на C. Качване на HEX файл във флаш паметта на микроконтролера
Писане на код за програма на C. Качване на HEX файл във флаш паметта на микроконтролера

Писане и изграждане на приложението за микроконтролер AVR в C Code с помощта на интегрираната платформа за развитие - Atmel Studio.

F_CPU определя тактовата честота в Hertz и е често срещано в програми, използващи библиотеката avr-libc. В този случай се използва от процедурите за забавяне, за да се определи как да се изчислят закъсненията.

#ifndef F_CPU

#define F_CPU 16000000UL // казваща кристална честота на кристала (16 MHz AVR ATMega328P) #endif

#include // заглавка за активиране на контрола на потока от данни върху щифтове. Определя щифтове, портове и др.

Първият включващ файл е част от avr-libc и ще се използва в почти всеки AVR проект, върху който работите. io.h ще определи процесора, който използвате (поради което посочвате частта при компилиране) и на свой ред ще включите подходящата IO заглавна дефиниция за чипа, който използваме. Той просто определя константите за всички ваши пинове, портове, специални регистри и т.н.

#include // заглавка за активиране на прекъсване

променлив uint8_t tot_overflow; // глобална променлива за преброяване на броя на преливанията

Методология за формулиране на проблема: Първо мига (зелен) светодиод на всеки 50 ms

- използване на предусилвател Timer0 за намаляване на високочестотен електрически сигнал до по -ниска честота чрез цялостно разделяне;

- използване на прекъсване при всяко препълване на Timer0;

void timer0_init () // инициализира timer0, прекъсване и променлива

{TCCR0B | = (1 << CS02); // настройка на таймер с предсказване = 256 TCNT0 = 0; // инициализира брояч TIMSK0 | = (1 << TOIE0); // разрешаване на препълване nterrupt sei (); // разрешаване на глобални прекъсвания tot_overflow = 0; // инициализира променлива на брояча на препълване}

Методология за формулиране на проблема: Светкавица втори светодиод (син) на всеки 1 s

- използване на предусилвател Timer1 за намаляване на високочестотен електрически сигнал до по -ниска честота чрез цялостно разделяне;

- използване на режим Clear Timer on Compare (CTC);

- използване на прекъсвания с режим CTC;

void timer1_init () // инициализираме timer1, прекъсване и променлива {TCCR1B | = (1 << WGM12) | (1 << CS12); // настройка на таймер с предсказване = 256 и режим CTC TCNT1 = 0; // инициализира брояч OCR1A = 62500; // инициализираме стойността за сравнение TIMSK1 | = (1 << OCIE1A); // разрешаване на прекъсване за сравнение}

Методология на формулиране на проблема: Третият светодиод мига (червен) на всеки 16 ms

- използване на предусилвател Timer2 за намаляване на високочестотен електрически сигнал до по -ниска честота чрез цялостно разделяне;

- използване на режим Clear Timer on Compare (CTC);

- използване на хардуерен режим CTC без прекъсвания;

void timer2_init () // инициализира timer2 {TCCR2A | = (1 << COM2A0) | (1 << WGM21); // настройка на таймер OC2A щифт в режим на превключване и режим CTC TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20); // настройка на таймер с предсказване = 1024 TCNT2 = 0; // инициализира брояч OCR2A = 250; // инициализира стойността за сравнение}

TIMER0 рутинна услуга за прекъсване на препълване, извикана всеки път, когато TCNT0 препълни:

ISR (TIMER0_OVF_vect)

{tot_overflow ++; // следете броя на препълненията}

Този ISR се задейства, когато възникне съвпадение, затова превключете водещия тук:

ISR (TIMER1_COMPA_vect) {PORTC ^= (1 << 1); // превключвателят води тук}

int main (void)

{DDRB | = (1 << 0); // свързваме 1 (зелено) с извод PB0 DDRC | = (1 << 1); // свързваме 2 (синьо) към pin PC1 DDRB | = (1 << 3); // свързване на 3 (червено) към пин PB3 (OC2A) timer0_init (); // инициализираме timer0 timer1_init (); // инициализираме timer1 timer2_init (); // инициализираме timer2 while (1) // цикъл завинаги {

Ако Timer0 е прелетял 12 пъти, 12 * 4.096ms = 49.152ms биха преминали. В 13 -тата итерация се нуждаем от закъснение от 50ms - 49.152ms = 0.848ms. По този начин, в 13 -та итерация, ние позволяваме на таймера да брои само до 53 и след това да го нулираме.

if (tot_overflow> = 12) // проверете дали не. на преливания = 12 ЗАБЕЛЕЖКА: '> =' се използва

{if (TCNT0> = 53) // проверете дали таймерът достига 53 {PORTB ^= (1 << 0); // превключва LED TCNT0 = 0; // нулиране на брояча tot_overflow = 0; // нулиране на брояча за препълване}}}}

Качване на HEX файл във флаш паметта на микроконтролера:

въведете в прозореца на DOS подкана командата:

avrdude –c [име на програмист] –p m328p –u –U флаш: w: [име на вашия шестнадесетичен файл] В моя случай е: avrdude –c ISPProgv1 –p m328p –u –U флаш: w: Timers.hex

Тази команда записва шестнадесетичен файл в паметта на микроконтролера. Гледайте видеоклипа с подробно описание на изгарянето на флаш паметта на микроконтролера:

Изгаряне на флаш памет на микроконтролер …

Добре! Сега микроконтролерът работи в съответствие с инструкциите на нашата програма. Нека го проверим!

Стъпка 6: Осъществяване на електрическата верига

Изработка на електрическата верига
Изработка на електрическата верига
Изработка на електрическата верига
Изработка на електрическата верига
Изработка на електрическата верига
Изработка на електрическата верига

Свържете компонентите в съответствие със схематична диаграма.

Препоръчано: