Показаны сообщения с ярлыком прерывания. Показать все сообщения
Показаны сообщения с ярлыком прерывания. Показать все сообщения

пятница, 22 мая 2015 г.

Timer/Counter0 (Таймер/счётчик0) в ATtiny2313. Описание регистров.

Описание регистров

TCNT0

TCNT0 - восьмиразрядный счётный регистр.
Когда таймер работает, в зависимости от режима его работы, содержимое счётного регистра сбрасывается, увеличивается или уменьшается по каждому импульсу тактового сигнала таймера/счётчика clkT0.
В любой момент времени регистр доступен как для чтения так и для записи.

OCR0A/OCR0B

OCR0A/OCR0B - регистры сравнения.
Во время работы таймера/счётчика каждый такт происходит непрерывное сравнение этих регистров с счётным регистром TCNT0. В случае равенства содержимого этих регистров в следующем такте устанавливается флаг OCF0A/OCF0B в соответствующем регистре флагов и, если разрешено, генерируется прерывание. Также в этом случае может изменяться состояние вывода OC0A/OC0B микроконтроллера.
Регистр доступен как для чтения, так и для записи.

TCCR0A/TCCR0B

Регистры TCCR0A и TCCR0B предназначены для управления модулем таймера/счётчика0.

Бит 7 6 5 4 3 2 1 0 TCCR0A
COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00
Чтение(R)/Запись(W) R/W R/W R/W R/W R R R/W R/W
Начальные значения 0 0 0 0 0 0 0 0

Биты 7, 6 - COM0A1, COM0A0 - определяют состоянии вывода OC0A при наступлении события "Совпадение".
Биты 5, 4 - COM0B1, COM0B0 - определяют состоянии вывода OC0B при наступлении события "Совпадение".

В Нормальном и CTC режимах
COM0A1
(COM0B1)
COM0A0
(COM0B0)
Описание
0 0
Нормальная работа вывода. Вывод OC0A (OC0B) отключен от таймера/счётчика T0.
0 1
Инвертировать состояние вывода.
1 0
Сбросить при совпадении в 0.
1 1
Установить 1 при совпадении.

В режимах Fast PWM и Phase Correct PWM
COM0A1
(COM0B1)
COM0A0
(COM0B0)
Описание
0 0 Нормальная работа вывода. Вывод OC0A (OC0B) отключен от таймера/счётчика T0.
0 1 OC0A:
WGM02 = 0 - Вывод OC0A отключен от таймера/счётчика T0.
WGM02 = 1 - Инвертирование состояния вывода.
OC0B: -
1 0 Сбрасывается при совпадении в 0. Устанавливается в 1 при достижении счётчиком максимального значения (неинвертированный ШИМ сигнал).
1 1 Устанавливается 1 при совпадении. Сбрасывается в 0 при достижении счётчиком максимального значения (инвертированный ШИМ сигнал).

Биты 1,0 - WGM01, WGM00 - совместно с WGM02 из регистра TCCR0B определяют режим работы таймера/счётчикаT0.

WGM02 WGM01 WGM00
Описание
0
0
0
 Нормальный режим
0
0
1
 Phase Correct PWM (ШИМ с точной фазой)
0
1
0
 CTC (Сброс при совпадении)
0
1
1
Fast PWM
1
0
0
-
1
0
1
Phase Correct PWM (ШИМ с точной фазой)
1
1
0
-
1
1
1
Fast PWM

Бит 7 6 5 4 3 2 1 0 TCCR0B
FOC0A FOC0B - - WGM02 CS02 CS01 CS00
Чтение(R)/Запись(W) W W R R R/W R/W R/W R/W
Начальные значения 0 0 0 0 0 0 0 0

Бит 7 - FOC0A - принудительное изменение состояния вывода OC0A.

Этот бит активен, только когда биты WGM установлены в Нормальный режим работы таймера. Однако, для обеспечения совместимости (переносимости) с будущими моделями он должен быть сброшен в 0 в PWM (ШИМ) режимах.
При установке 1 состояние вывода OC0A меняется в зависимости от битов COM0A1 и COM0A0. При этом не генерируется прерывание и таймер не сбрасывается в CTC режиме.
При чтении всегда возвращает 0.

Бит 6 - FOC0B - принудительное изменение состояния вывода OC0B.

Этот бит активен, только когда биты WGM установлены в Нормальный режим работы таймера. Однако, для обеспечения совместимости (переносимости) с будущими моделями он должен быть сброшен в 0 в PWM (ШИМ) режимах.
При установке 1 состояние вывода OC0B меняется в зависимости от битов COM0B1 и COM0B0. При этом не генерируется прерывание и таймер не сбрасывается в CTC режиме.
При чтении всегда возвращает 0.

Бит 3 - WGM02 - совместно с WGM01 и WGM00 из регистра TCCR0A определяет режим работы таймера/счётчикаT0.

Биты 2, 1, 0 - CS02, CS01, CS00 - определяют источник тактового сигнала для таймера, счётчика T0

CS02 CS01 CS00
Описание
0
0
0
 Таймер/счётчик остановлен
0
0
1
 Системный тактовый сигнал (clkT0=clkI/O)
0
1
0
clkI/O/8 (с предделителем)
0
1
1
clkI/O/64 (с предделителем)
1
0
0
clkI/O/256 (с предделителем)
1
0
1
clkI/O/1024 (с предделителем)
1
1
0
Внешний сигнал - по ниспадающему фронту импульсов на выводе таймера T0
1
1
1
Внешний сигнал - по нарастающему фронту импульсов на выводе таймера T0

TIMSK

TIMSK - регистр масок прерываний таймеров/счётчиков T0 и T1.
Для разрешения прерывания от таймера/счётчика необходимо установить 1 в соответствующий бит регистра TIMSK и бит I регистра SREG.

Бит 7 6 5 4 3 2 1 0 TIMSK
TOIE1 OCIE1A OCIE1B - ICIE1 OCIE0B TOIE0 OCIE0A
Чтение(R)/Запись(W) R/W R/W R/W R R/W R/W R/W R/W
Начальные значения 0 0 0 0 0 0 0 0

Бит 7 - TOIE1 - разрешение прерывания по переполнению таймера/счётчика T1.

Бит 6 - OCIE1A - разрешение прерывания по событию "Совпадение А" таймера/счётчика T1.

Бит 5 - OCIE1B - разрешение прерывания по событию "Совпадение B" таймера/счётчика T1.

Бит 3 - ICIE1 - разрешение прерывания по событию "Захват" таймера/счётчика T1.

Бит 2 - OCIE0B -  разрешение прерывания по событию "Совпадение B" таймера/счётчика T0.

Бит 1 - TOIE0 - разрешение прерывания по переполнению таймера/счётчика T0.

Бит 0 - OCIE0A - разрешение прерывания по событию "Совпадение А" таймера/счётчика T0.

TIFR

TIFR - регистр флагов прерываний таймеров/счётчиков T0 и T1.
При наступлении какого-либо события соответствующий флаг регистра TIFR устанавливается в 1. При запуске подпрограммы обработки прерывания он аппаратно сбрасывается в 0. Любой флаг также может быть сброшен программно записью в него 1.

Бит 7 6 5 4 3 2 1 0 TIFR
TOV1 OCF1A OCF1B - ICF1 OCF0B TOV0 OCF0A
Чтение(R)/Запись(W) R/W R/W R/W R R/W R/W R/W R/W
Начальные значения 0 0 0 0 0 0 0 0

Бит 7 - TOV1 - флаг прерывания по переполнению таймера/счётчика T1.

Бит 6 - OCF1A - флаг прерывания по событию "Совпадение А" таймера/счётчика T1.

Бит 5 - OCF1B - флаг прерывания по событию "Совпадение B" таймера/счётчика T1.

Бит 3 - ICF1 - флаг прерывания по событию "Захват" таймера/счётчика T1.

Бит 2 - OCF0B - флаг прерывания по событию "Совпадение B" таймера/счётчика T0.

Бит 1 - TOV0 - флаг прерывания по переполнению таймера/счётчика T0.

Бит 0 - OCF0A -  флаг прерывания по событию "Совпадение A" таймера/счётчика T0.

GTCCR


Бит 7 6 5 4 3 2 1 0 GTCCR
- - - - - - - PSR10
Чтение(R)/Запись(W) R R R R R R R R/W
Начальные значения 0 0 0 0 0 0 0 0

Бит 0 - PSR10 - сброс предделителей таймеров счётчиков.

При установке 1 в этот бит предделители таймеров T0 и T1 сбрасываются. После сброса в нём аппаратно устанавливается 0.


Избавление от дребезга контактов 1

Вариантов борьбы с дребезгом кнопок много. Я расскажу о программном способе с задержкой, генерируемой таймером и прерыванием.


При нажатии кнопки в цикле проверяется нажата ли кнопка необходимое количество миллисекунд (переменная delay). Если да, то кнопка считается нажатой.

Данный код актуален как минимум для AtmelStudio и микроконтроллера Attiny2313 с частотой 4 МГц с кнопкой на ножке PD6.

#include <avr/io.h>
/*подключим заголовочный файл для использования прерываний*/
#include <avr/interrupt.h>
#include <avr/sfr_defs.h>

#define F_CPU 4000000UL

/*задержка в миллисекундах*/
unsigned int delay = 100;
int t1 = 0;

char push = 0;

/*обработка прерывания по переполнению счётчика T0*/
ISR (TIMER0_OVF_vect)
{
  t1++;
}

int main (void)
{
     /*настраиваем порт D как вход*/
DDRD = 0x00;
PORTD = 0xFF;
     /*настраиваем порт B как выход*/
DDRB = 0xFF;
PORTB = 0x00;

 /*источник тактирования таймера T0 - внутренный генератор без делителя*/
TCCR0B = 0b00000001;
/*сбрасываем счётчик T0*/
TCNT0 = 0x00000000;

int count = (F_CPU/1000) * delay/255;

 /*общее разрешение прерываний*/
sei ();

 /*отключение прерывания по переполнению таймера T0*/
TIMSK |= (0<<TOIE0);

while(1)
{
while (bit_is_set (PIND, 6))     //пока нажата кнопка на PD6
{
TIMSK |= (1<<TOIE0); //разрешение прерывания по переполнению таймера T0

if (t1>count)
{
push = 1;
TIMSK |= (0<<TOIE0);
t1=0;
}
}
 
  t1 = 0;
 
  if (push == 1)
{
               /*инвертирование состояния порта B*/
PORTB = ~PORTB;
push = 0;
}
}
}

Однако у этого способа есть недостаток. Во время нажатия кнопки контроллер не выполняет никакую работу, кроме отсчитывания времени, указанного в переменной delay.