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

пятница, 5 июня 2015 г.

Управление электропитанием и режимы пониженного электропотребления ATtiny2313

Режимы пониженного энергопотребления

Режимы пониженного энергопотребления позволяют отключать неипользуемые модули микроконтроллера, уменьшая потребляемый ток. В AVR имеется несколько таких режимов, позволяющих подстроить потребление тока под требования к устройству.
Для разрешения "спящих" режимов необходимо установить 1 в бите SE регистра MCUCR. Биты SM1 и SM0 того же регистра определяют какой именно "спящий" режим будет использоваться.
Переход в режим понижеенного энергопотребления осуществляется командой SLEEP.
Если в "спящем" режиме сработает прерывание, контроллер будет переведён в нормальный режим работы, остановится на 4 такта, обработает прерывание и продолжит выполнение программы с команды, следующей за командой SLEEP.
Если во время "сна" произойдёт сброс контроллера, он перейдёт к обработке прерывания по сбросу.

Регистр MCUCR

Бит 7 6 5 4 3 2 1 0 MCUCR
PUD SM1 SE SM0 ISC11 ISC10 ISC01 ISC00
Чтение(R)/Запись(W) R/W R/W R/W R/W R/W R/W R/W R/W
Начальные значения 0 0 0 0 0 0 0 0

Биты 6, 4 - SM1, SM0 - определяют "спящий" режим.

SM1
SM0
Режим
0 0
Idle
0
1
Power-Down
1
0
Standby
1
1
Power-down

Примечание: режим Stendby рекомендуется только при использовании внешнего кварца.

Бит 5 - SE - разрешение перехода в режим пониженного энергопотребления.
Во избежание непреднамеренного перехода в "спящий" режим рекомендуется устанавливать данный бит непосредственно перед командой SLEEP и сбрасывать сразу после перехода в обычный режим работы.

Режим Idle (режим холостого хода)

В этом режиме прекращается формирование сигналов clkCPU и clkFLASH. При этом остаются работать UART, аналоговый компаратор, АЦП, USI, таймеры/счётчики, сторожевой таймер и прерывания. Выход из режима Idle возможен как по внешнему, так и по внутреннему прерыванию (переполнение таймера/счётчика, окончание передачи по UART и т.п.).
Если не используются прерывания от аналогового компаратора, то он может быть выключен установкой бита ACD регистра ACSR. Это снизит потребление тока контроллером в режиме Idle.
Преимущество этого режима - быстрая реакция на события, "пробуждающие" микроконтроллер. Другими словами выполнение программы начнётся сразу же после выхода на нормальный режим работы.

Режим Power Down (режим микропотребления)

В этом режиме отключается тактирование контроллера. Остаются работать только обработка внешних прерываний, обнаружение состояния Старт модуля USI и сторожевой таймер (если он включен). Разбудить микроконтроллер в этом режиме могут только внешний сброс, сброс от сторожевого таймера, сброс от Brown-out Reset, прерывание по состоянию Старт модуля USI и внешнее прерывание.
В режиме Power Down пробуждение происходит не мгновенно, поэтому длительность сигнала, его вызывающего, должна быть не меньше времени запуска контроллера. Это время определяется теми же конфигурационными ячейками (фьюзами), которые задают задержку сброса микроконтроллера.

Режим Standby

Этот режим рекомендуется задействовать при использовании внешнего резонатора - кварца.
Режим Standby идентичен режиму Power Down с тем исключением, что остаётся работать тактовый генератор, поэтому выход в рабочий режим происходит быстрее - за 6 тактов.

Снижение энергопотребления




четверг, 28 мая 2015 г.

Прерывания. Таблица векторов прерываний ATtiny2313

ATtiny2313

Расположение векторв прерываний в таблице определяет приоритет их обработки. Чем младше адрес прерывания, тем выше приоритет.

№ Адрес Источник Описание
1 0x00 RESET Внешний пин, сброс при включении, сброс при падении напряжения, сброс сторожевого таймера
2 0x01 INT0 Внешнее прерывание 0
3 0x02 INT1 Внешнее прерывание 1
4 0x03 TIMER1 CAPT Захват таймера/счётчика T1 
5 0x04 TIMER1 COMPA Совпадение A таймера/счётчика T1
6 0x05 TIMER1 OVF Переполнение таймера/счётчика T1
7 0x06 TIMER0 OVF Переполнение таймера/счётчика T0
8 0x07 USART0, RX USART0, приём завершён
9 0x08 USART0, UDRE Регистр данных USART0 пуст
10 0x09 USART0, TX USART0, передача завершена
11 0x0A ANALOG COMP Аналоговый компаратор
12 0x0B PCINT Прерывание по изменению состояния выводов
13 0x0C TIMER1 COMPB Совпадение B таймера/счётчика T1
14 0x0D TIMER0 COMPA Совпадение A таймера/счётчика T0
15 0x0E TIMER0 COMPB Совпадение B таймера/счётчика T0
16 0x0F USI START Состояние START USI
17 0x10 USI OVERFLOW Переполнение USI
18 0x11 EE READY EEPROM готово
19 0x12 WDT OVERFLOW Переполнение сторожевого таймера

пятница, 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.