Таймеры/счётчики в AVR

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

sirha, у Вас в прерывании начальное значение счетчика задается 0, а надо TCNT0=0x63.
sirha писал(а):

Код: Выделить всё

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
x=~x;
TCNT0=0;
}
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 54
Зарегистрирован: Пт окт 03, 2014 14:41:16

Сообщение alexan9er »

Это почему? Он же хочет сбрасывать счётчик в обработчике.
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

Потому, что в прерывание он он попадает при переполнении, в нем и так 0, а чтобы прерывание наступило раньше нужно соответственно счетчик заранее намотать.
Открыл глаза
Аватара пользователя
Сообщения: 54
Зарегистрирован: Пт окт 03, 2014 14:41:16

Сообщение alexan9er »

Точно :)
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 613
Зарегистрирован: Сб окт 17, 2009 18:56:05
Откуда: РФ, Башкортостан г.Сибай

Сообщение yur4ik »

ВСем привет, такой вопрос. atmega8 (такт = 8МГц, таймер 2 на 125000кГц, режим FAST PWM TOP,non-inverted pwm) реально же получить на ножке частоту в 400гц cкважность = 30% ? У меня с помощью ШИМ выходит либо 333гц либо 488гц а 400 никак... Может кто может кодом помочь или направлением хотя бы?!

Все получил

Код: Выделить всё

PORTB.3=1;
      delay_us(875);
      PORTB.3=0;
      delay_us(1625);
Нельзя всё знать, достаточно понимать.
Контактная информация:
Реклама
Опытный кот
Аватара пользователя
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США

Сообщение Pink-Pank »

Если только программную эмуляцию. Таймер1 заюзать. Режим сброс по совпадению. а между сбросами прерывание по совпадению с регистром B
Fucking static initialization order fiasco
Контактная информация:
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 613
Зарегистрирован: Сб окт 17, 2009 18:56:05
Откуда: РФ, Башкортостан г.Сибай

Сообщение yur4ik »

ну я сделал по таймеру0 на переполнение:

Код: Выделить всё

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
 PORTD.0=1;
 delay_us(875);
 PORTD.0=0;
 delay_us(1250+345); /*375*/
}

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
TCCR0=0x01;
TCNT0=0x00;
нормально же должно работать?
Нельзя всё знать, достаточно понимать.
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США

Сообщение Pink-Pank »

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

Код: Выделить всё

interrupt [TIM2_OVF] void timer0_ovf_isr(void)
{
TCNT2 = 100;
}

...

// Timer/Counter 2 initialization
// Clock source: System Clock :128
// Clock value: 8000,000 kHz
DDRB.3 = 1;
PORTB.3 = 1;
TCNT2 = 100;
OCR2 = 147; // 30%
TIMSK=0x40;
TCCR2=0x6D; // Режим Fast PWM, non-invert.  
#asm ("sei;")
while(1);
Снимать сигнал с порта B3 будете
Fucking static initialization order fiasco
Контактная информация:
Нашел транзистор. Понюхал.
Сообщения: 190
Зарегистрирован: Пт сен 21, 2007 17:53:23
Откуда: Зарайск

Сообщение mrFox »

yur4ik писал(а): atmega8 (такт = 8МГц, таймер 2 на 125000кГц, режим FAST PWM TOP,non-inverted pwm)
реально же получить на ножке частоту в 400гц cкважность = 30% ? У меня с помощью ШИМ выходит либо 333гц либо 488гц а 400 никак... Может кто может кодом помочь или направлением хотя бы?!

Все получил

Код: Выделить всё

PORTB.3=1;
      delay_us(875);
      PORTB.3=0;
      delay_us(1625);
длительные вычисления в прерывании нежелательны

можно воспользоваться режимом CTC - считает до OCR2 в прерывании загоняем в OCR2 по очереди длительность длительность 1 и длительность 0 - обновляется OCR2 сразу, так что должно прокатить

Код: Выделить всё

enum {
  len_0 = ??; // вычислить нужно
  len_1 = ??; // вычислить нужно
};
SIGNAL(TIMER2_COMP_vect)
{
    static bool is_0 = true;
    if( is_0 ) {
     PORTB.3=0;
     is_0 = false;
     OCR2 = len_0;
   } else {
     PORTB.3=1;
     is_0 = true;
     OCR2 = len_1;
   }
}
Встал на лапы
Сообщения: 117
Зарегистрирован: Ср ноя 05, 2014 19:04:31

Сообщение DarkWolf »

Добрый день уважаемые! Подскажите следующий вопрос: стоит задача подсчитать количество импульсов за определенное время. Читал что нужно использовать таймеры, но проблема (для меня) состоит в том, что источник импульсов подключен не на ноги таймера, а на ногу ADC. Можно как то все это сосчитать с использованием таймера? Контроллер ATMEGA324P. Или направте где можно почитать. Спасибо!
akl
Друг Кота
Сообщения: 4450
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Посмотрел DS. Вроде все входы ADC подключены к лапам ввода-вывода и имеют возможность работы с PCINTx. Т.е. нет проблем. Запускаете таймер на формирование измерительного интервала и по каждому прерыванию PCINT отсчитываете входные импульсы за измерительный интервал.
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

Сигнал нужно вешать на ногу INT0 или INT1 и в АВР считать прерывания _interput функцией иначе никак
Опытный кот
Сообщения: 822
Зарегистрирован: Вс июн 02, 2013 12:23:03

Сообщение amd9800 »

rxstart1 писал(а): иначе никак
Почему иначе никак.
Смотря какая частота импульсов.

Если частота очень низкая то настроить таймер так чтоб вызывалось прерывание например раз в 100 микросекунд. И проверять состояние ноги. Если состояние изменилось прибавить 1 к счетчику.
Но если частота высокая тогда только прерывание по событию.
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

да но на это уходит время, а если источник садить на ногу int0 int1, прерывание вызывается автоматически, таймер тикает тоже независимо от кода. Так что на мой взгляд это самый оптимальный вариант
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

А чем прерывание PCINT не устраивает, так же аппаратно будет срабатывать.
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

ну тык я про то и писал, просто в разных мк по разному обозначается, главное, чтобы было в таблице векторов, чтобы можно было вызвать обработчик.

Кстати протез очень плохо эмулирует работу таймеров и прерываний. :(
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

В ATMEGA324P любой пин любого порта можно на PCINT прерывание посадить и это не совсем одно и то же, что INT0 и INT1, приоритеты разные.
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

Я сейчас вопрос внимательно перечитал :))
Что за ноги таймера :shock:
Таймер он внутри тикает у него ног нету :facepalm:
Открыл глаза
Аватара пользователя
Сообщения: 54
Зарегистрирован: Пт окт 03, 2014 14:41:16

Сообщение alexan9er »

Посмотри "Input Capture Unit", но это есть не у всех таймеров.
Встал на лапы
Сообщения: 83
Зарегистрирован: Вс май 20, 2012 16:21:11

Сообщение Lihouzov »

Вопрос знатокам. Есть ассемблерный код:

Код: Выделить всё

iOVF0addr:  ;Прерывание по таймеру
 LDS iB, TimerCounter0_DATA_RAM+5             ;Задаем значение таймера
 out TCNT0, iB                                ;Задаем значение таймера
 in  iB, SREG                                 ;Сохраняем регистр флагов                                   
 LDS iA, TimerCounter0_DATA_RAM               ;мс в текущем цикле
 add iA, One                                  ;мс в текущем цикле
 STS TimerCounter0_DATA_RAM, iA               ;мс в текущем цикле
 out SREG, iB                                 ;Востанавливаем регистр флагов  
 reti

FBD41_init:
 rcall Read_cfg                                ;Период прерывания
 STS   TimerCounter0_DATA_RAM+5, Addr_Data     ;Период прерывания
 rcall Read_cfg                                ;Делитель                       
 out TCCR0, Addr_Data                          ;Делитель
 in    A,      TIMSK                           ;Разрешаем прерывание по переполнению
 ori   A,      0b00000001                      ;Разрешаем прерывание по переполнению
 out   TIMSK,  A                               ;Разрешаем прерывание по переполнению
 ret;
Данный код работает на atmega8.
Будет ли работать данный код на других AVR контроллерах?
У всех контроллеров есть Timer0, он везде восьми разрядный?
Биты настройки будут отличаться?
Ответить

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