Microsin - avr як розрахувати час виконання команди

При програмуванні AVR (ATmegaXX, ATtinyXX) необхідно знати, скільки часу буде виконуватися код. Тут описуються прості правила для розрахунку цього часу.

Час виконання ассемблерних інструкцій строго прив'язане до тактовою частотою мікроконтролера AVR, тому перше, що потрібно дізнатися - яка у Вас встановлена ​​частота ядра F. т. Е. На якій частоті працює внутрішній тактовий генератор. Зазвичай частота тактового генератора задається кварцом, тоді вона дорівнює частоті, написаної на кварці. Іноді кварц не використовується, і запускається не надто точний внутрішній RC генератор (ніякі зовнішні компоненти для генератора не потрібні), тоді зазвичай генератор працює на частоті 1 МГц (можна налаштувати і на частоту 8 МГц). Який режим використовується - визначається внутрішніми налаштуваннями fuses (вони ще називаються перемичками). Наприклад, для чіпа ATmega16 за замовчуванням (коли чіп приходить чистий із заводу) перемички налаштовані на роботу без кварцу, від внутрішнього RC генератора на частоті 1 МГц.

Отже, частоту ядра F в Герцах ми знаємо. Тепер можна дізнатися час одного такту TCLK = 1 / F (в секундах). Кожна команда виконується строго певну кількість тактів (скільки - залежить від команди). Наприклад, команди ANDI і ORI (які часто використовуються при управлінні ніжками портів) виконуються за 1 такт. Приклад розрахунку тривалості виконання команди ANDI:

Таблицю відповідності між командами мікроконтролера і кількістю тактів можна знайти в даташіте на мікроконтролер, див. Instructions Set Summary в кінці даташіта. В останньому стовпчику таблиці #Clocks вказано число тактів, за яке виконується команда. Якщо там стоїть одна цифра - наприклад 2, тоді все зрозуміло, команда виконується 2 такту. Але іноді там стоїть 1/2 або 1/2/3. Це означає для прикладу 1/2, що команда може виконається за 1 або 2 такту, що залежить від умови виконання команди. Наприклад, команда BREQ виконається за 1 такт, якщо немає розгалуження за умовою, і за 2 такту, якщо станеться умовний перехід.

[Розрахунок виконання команди на мові Сі]

Є також спосіб прямого виміру тривалості виконання коду за допомогою осцилографа. Для цього вибирають вільне ніжку у мікроконтролера, і на початку вимірюваного коду ставлять установку ніжки в 1, а після закінчення вимірюваного коду встановлюють ніжку в 0. Запускають програму на виконання і осцилографом вимірюють тривалість імпульсу.

[Обчислення константи для таймера / лічильника]

Таймери / лічильники часто використовуються в програмі для відліку затримок часу. Я зазвичай налаштовую лічильник таким чином, щоб його переривання спрацьовувало приблизно раз в 1 мілісекунди. В цьому випадку в програмі зручно відраховувати час зберігає фінансову лічильника (про це далі). Покажу на таймері 1, як це налаштовується і як використовується.

void SetupTIMER1 (void)
// 1< TCCR1B = (1< TCNT1 = TCNT1_1MS;
// Enable timer 1 overflow interrupt.
TIMSK = (1<>

void timePoll (void)
static u16 timecnt = 100;

if (TIMSK (1< return;

TCNT1 = TCNT1_1MS;
TIMSK = (1<

//[timerint.S]
#include
.text
.global TIMER1_OVF_vect
TIMER1_OVF_vect:
; Cbi _SFR_IO_ADDR (PORTB), PB7
push R24
; Ldi R24,

(1< ldi R24, 0
out _SFR_IO_ADDR (TIMSK), R24
; out 0x39, R24
pop R24
; Sbi _SFR_IO_ADDR (PORTB), PB7
reti

[Відлік часу в програмі з точністю 1 мс]

Якщо у Вас є організований таким чином глобальний лічильник мілісекундних відліків timestamp, то відлік часу в програмі стає тривіальним завданням. Ось приклад обчислення затримки в 0.5 секунди:

u32 timecnt = timestamp + 500;
while (timestamp

Схожі статті