Помогите разобраться с использованием таймеров на AVR

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 6
Зарегистрирован: Вт сен 25, 2012 16:33:30

Сообщение Evgen-82 »

Прошу помощи!!! Хочу научиться использовать таймер в AVR для отсчета заданного времени, в данный момент бъюсь над проблемой, есть МК Attiny13A хочу что при нажатии на кнопку "Пуск" он запустил отсчет допустим 2 мин и 30 сек и при этом на одном из выводов появился лог 1., как только время 2 мин 30 сек истечет, лог 1 сменился бы на лог 0 и нагрузка отключилась, МК перешел бы в ждущий режим, объясните как это организовать, пишу в CodeVision AVR. Много сайтов пересмотрел по работе с таймерами, так нечего и не понял :( :( :(
Реклама
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

Много сайтов пересмотрел по работе с таймерами, так нечего и не понял
.. нужно смотреть не сайты, а документацию можно например так - задаете значение предделителя и используете переполнение таймера. Настройки делаете кратные значению (2 мин 30 сек = 150 сек). Программный счетчик =0 . Например переполнение срабатывает через 0.1 сек. После каждого переполнения увеличивате программный счетчик и так до 1500. ( т.е 150/0.1=1500 )
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 54
Зарегистрирован: Вт янв 05, 2010 14:51:04

Сообщение mark13121971 »

В CodeVision есть две встроенные функции програмных задержек delay_ms и delay_us:
Например:
for(k = 0; k < 150; k++) {delay_ms(1000);} // 150 * 1000ms = 150000ms = 2min 30sec

либо в обработчике прерывания таймера по переполнению вводишь глобальную переменную tick, которая постоянно считает периоды (тики) твоего таймера, а потом в программе обрабатываешь это значение:

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
tick++; //системный тик = 1мс
TCNT0 = твое значение; //перезагрузка таймера
}

unsigned long tick;
void main(void)
{
PORTA = 0b00000001; //включить, например, вывод PA0 = 1
tick = 0;
while(tick<150000) { //например период таймера = 1мс этот цикл выполняется 2мин 30сек
здесь МК может обрабатывать что-то другое
}
PORTA = 0b00000000; //выключить, например, вывод PA0 = 1
и т.д.
P.S. Только перед циклом while обязательно всегда обнулять tick, т.к. там может быть все что угодно)
Для наглядной работы с битами регистров (и портов в том числе) рекомендую макросы:
#define SetBit(x,y) (x|=(1<<y)) //установка бита в 1
#define ClrBit(x,y) (x&=~(1<<y)) //установка бита в 0
#define ToggleBit(x,y) (x^=(1<<y)) //переключение
#define TestBit(x,y) (x&(1<<y)) //проверка
Т.е. SetBit(PORTA, PA0) - установить в 1, ClrBit(PORTA, PA0) - установить в 0. Все просто и понятно...

Если непонятно функционирование таймера, то в общих чертах работает так:
Допустим у тебя тактовая частота МК - f = 1МГц.
тогда длительность машинного цикла МК составляет 1мкс. (T = 1/f). Приращение регистра таймера происходит в каждом маш.цикле.
переполнение (а значит отработка прерывания) 8-ми разрядного таймера 0 без установленных предделителей наступит через 255мкс, с делителем на 2 - через 255 * 2 = 510мкс. и т.д. Допустим тебе нужно выставить период таймера 0 в 1мс, тогда нужно в TCNT0 записать начальное значение 130 ( 255 - 130 = 125мкс * 8(коэфф.деления задается в регистре TCCR0B) = 1000мкс = 1мс.) И каждый раз в обработчике по переполнению таймера 0 перезаписывать TCNT0 = 130. Вот и все, собственно...
Скачай книжку А.В.Евстифеева Микроконтроллеры AVR семейств Tiny и Mega и все станет понятно как божий день.
Успехов.
Ответить

Вернуться в «AVR»