Страница 14 из 72

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

Добавлено: Сб окт 11, 2014 18:55:08
zero648
sirha, у Вас в прерывании начальное значение счетчика задается 0, а надо TCNT0=0x63.
sirha писал(а):

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

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
x=~x;
TCNT0=0;
}

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

Добавлено: Пн окт 20, 2014 14:42:44
alexan9er
Это почему? Он же хочет сбрасывать счётчик в обработчике.

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

Добавлено: Пн окт 20, 2014 22:38:17
zero648
Потому, что в прерывание он он попадает при переполнении, в нем и так 0, а чтобы прерывание наступило раньше нужно соответственно счетчик заранее намотать.

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

Добавлено: Пн окт 20, 2014 22:47:48
alexan9er
Точно :)

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

Добавлено: Пт окт 24, 2014 20:39:15
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);

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

Добавлено: Пт окт 24, 2014 21:42:28
Pink-Pank
Если только программную эмуляцию. Таймер1 заюзать. Режим сброс по совпадению. а между сбросами прерывание по совпадению с регистром B

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

Добавлено: Пт окт 24, 2014 22:17:59
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;
нормально же должно работать?

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

Добавлено: Пт окт 24, 2014 22:33:07
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 будете

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

Добавлено: Ср ноя 19, 2014 23:07:27
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;
   }
}

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

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

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

Добавлено: Ср дек 10, 2014 08:14:26
akl
Посмотрел DS. Вроде все входы ADC подключены к лапам ввода-вывода и имеют возможность работы с PCINTx. Т.е. нет проблем. Запускаете таймер на формирование измерительного интервала и по каждому прерыванию PCINT отсчитываете входные импульсы за измерительный интервал.

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

Добавлено: Вт дек 16, 2014 18:52:26
rxstart1
Сигнал нужно вешать на ногу INT0 или INT1 и в АВР считать прерывания _interput функцией иначе никак

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

Добавлено: Вт дек 16, 2014 22:47:48
amd9800
rxstart1 писал(а): иначе никак
Почему иначе никак.
Смотря какая частота импульсов.

Если частота очень низкая то настроить таймер так чтоб вызывалось прерывание например раз в 100 микросекунд. И проверять состояние ноги. Если состояние изменилось прибавить 1 к счетчику.
Но если частота высокая тогда только прерывание по событию.

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

Добавлено: Ср дек 17, 2014 08:16:06
rxstart1
да но на это уходит время, а если источник садить на ногу int0 int1, прерывание вызывается автоматически, таймер тикает тоже независимо от кода. Так что на мой взгляд это самый оптимальный вариант

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

Добавлено: Ср дек 17, 2014 08:22:46
zero648
А чем прерывание PCINT не устраивает, так же аппаратно будет срабатывать.

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

Добавлено: Ср дек 17, 2014 08:27:10
rxstart1
ну тык я про то и писал, просто в разных мк по разному обозначается, главное, чтобы было в таблице векторов, чтобы можно было вызвать обработчик.

Кстати протез очень плохо эмулирует работу таймеров и прерываний. :(

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

Добавлено: Ср дек 17, 2014 08:58:20
zero648
В ATMEGA324P любой пин любого порта можно на PCINT прерывание посадить и это не совсем одно и то же, что INT0 и INT1, приоритеты разные.

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

Добавлено: Ср дек 17, 2014 11:01:48
rxstart1
Я сейчас вопрос внимательно перечитал :))
Что за ноги таймера :shock:
Таймер он внутри тикает у него ног нету :facepalm:

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

Добавлено: Ср дек 17, 2014 12:57:25
alexan9er
Посмотри "Input Capture Unit", но это есть не у всех таймеров.

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

Добавлено: Ср дек 17, 2014 17:36:40
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, он везде восьми разрядный?
Биты настройки будут отличаться?