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

Обсуждаем контроллеры компании Atmel.
Pnjom-Penb
Мучитель микросхем
Сообщения: 469
Зарегистрирован: Вс авг 30, 2015 03:52:59

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

Сообщение Pnjom-Penb »

B@R5uk писал(а):Корректное или нет, это вопрошающему решать, ...
Врядли он к этому сейчас готов. :)
То есть, Вы не согласны с тем, что нажатия, начавшиеся и закончившиеся внутри интервала таймера, полностью выпадут из подсчета?
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

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

Сообщение B@R5uk »

Это будут не нажатия, а дребезг. Его выпадение суть задумка и суть антидребезга. Впрочем, это не для этой темы разговор. Если есть вопросы по таймерам, то спрашивайте. :)))
Pnjom-Penb
Мучитель микросхем
Сообщения: 469
Зарегистрирован: Вс авг 30, 2015 03:52:59

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

Сообщение Pnjom-Penb »

Дребезг длится десятки миллисекунд, а не сотни, поэтому именно нажатия могут быть пропущены.
А если бы дребезг длился так долго, то предложенный Вами алгоритм подсчета, учитывал бы такой длинный дребезг, как несколько нажатий (по числу срабатываний таймера, попавших внутрь этого дребезга).

Ну да бог с ним, пусть ТС осмысливает и формулирует вопросы.
prw07
Мучитель микросхем
Сообщения: 403
Зарегистрирован: Ср янв 26, 2011 17:00:30

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

Сообщение prw07 »

Имею что спросить по режимам таймеров в Мега16.
Начнем с простого: Normal.
Можно ли изменять длительность импульсов (или частоту) в этом режиме.
Написано в шите что состояние вывода OC0 может быть изменено принудительно, записью лог. 1 в разряд FOC0 регистра TCCR0.
Как это выглядит на практике? Пример есть?
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

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

Сообщение B@R5uk »

prw07 писал(а):Можно ли изменять длительность импульсов (или частоту) в этом режиме.
Да. Но только переподключением таймера к другому выходу предделителя. А ещё можно тактировать таймер от внешнего источника управляемой частоты (он же может быть выход другого таймера МК).

prw07 писал(а):Как это выглядит на практике?
Как запись байта в регистр ввода-вывода. Применять в режиме Normal у меня не возникало необходимости.
Pnjom-Penb
Мучитель микросхем
Сообщения: 469
Зарегистрирован: Вс авг 30, 2015 03:52:59

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

Сообщение Pnjom-Penb »

B@R5uk писал(а):Но только переподключением таймера к другому выходу предделителя.
Не совсем "только". Насколько я помню, в доке атмеля отмечают, что можно это делать программно - повесившись на прерывание по переполнению - и тут же сообщают, что этот способ не рекомендуется, так как он отнимает много процессорного времени. Но если очень хочется, то - можно. :)
prw07
Мучитель микросхем
Сообщения: 403
Зарегистрирован: Ср янв 26, 2011 17:00:30

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

Сообщение prw07 »

Спасибо. С частотой и длительностью разобрался.
Осталось разобраться с битом FOC0. Не устанавливается он в 1. Вернее сбрасывается в 0 как только в TNT0 что-либо записывается. И потом установить его не возможно.
Т.е. когда идет инициализация:

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

TCCR0=(1<<FOC0) | (0<<WGM00) | (1<<COM01) | (0<<COM00) | (0<<WGM01) | (0<<CS02) | (0<<CS01) | (1<<CS00); установился FOC0 в 1
TCNT0=0x00; по выполнению этого FOC0 сбросился в 0

Если в коде дальше устанавливать его, то он не устанавливается.

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

TCCR0|=(1<<FOC0);
TCCR0=A1;
TCCR0=0b10100001;

вот это все не помогает.
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

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

Сообщение B@R5uk »

Бит FOCn расшифровывается Force Output Compare, что означает "Принудительный вызов события Output Compare". То есть установка этого бита в 1 заставляет таймер вести себя так, как будто произошло событие совпадения, за исключением того, что не вызывается прерывание. Это означает, что модуль формирования волны (Waveform Generation Unit) совершит действие, указанное битами настройки соответствующего модуля: COMnx1:0. В режиме Normal или CTC единственной разумной настройкой этого модуля является переключение по совпадению, поскольку установка или сброс по совпадению изменят состояние выхода единожды, а событий, которые переведут вывод в противоположное состояние нет (в отличие от режимов PWM).

prw07 писал(а):Осталось разобраться с битом FOC0. Не устанавливается он в 1. Вернее сбрасывается в 0 как только в TNT0 что-либо записывается.
Значение этих битов всегда читается как ноль, поскольку они реализованы не как обычные биты регистра данных, и даже не как регистр в который можно только записать данные для хранения. Они реализованы как стробы модуля формирования волны (Waveform Generation Unit). Это в точности как тактовый С-вход D-триггера микросхемы К155ТМ2. Внимательнее читайте документацию:

The FOC1A/FOC1B bits are only active when the WGM13:0 bits specifies a non-PWM mode.
However, for ensuring compatibility with future devices, these bits must be set to zero when
TCCR1A is written when operating in a PWM mode. When writing a logical one to the
FOC1A/FOC1B bit, an immediate compare match is forced on the Waveform Generation unit.
The OC1A/OC1B output is changed according to its COM1x1:0 bits setting. Note that the
FOC1A/FOC1B bits are implemented as strobes. Therefore it is the value present in the
COM1x1:0 bits that determine the effect of the forced compare.
A FOC1A/FOC1B strobe will not generate any interrupt nor will it clear the timer in Clear Timer
on Compare match (CTC) mode using OCR1A as TOP.
The FOC1A/FOC1B bits are always read as zero.
gavrasio
Нашел транзистор. Понюхал.
Сообщения: 162
Зарегистрирован: Пн июн 01, 2015 15:23:01

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

Сообщение gavrasio »

ARV писал(а):gavrasio, вы метете пургу

когда вы уже прочтете книжку, чтобы пользоваться ПРАВИЛЬНОЙ ТЕРМИНОЛОГИЕЙ, а не выдумывать свою собственную, не соприкасающуюся с истиной?!

Вот нашёл книжку. Автор Бьярн Страустрап.
Вот цитата из него:

9.4 Оператор while

Оператор while имеет вид

while ( выражение ) оператор


Выполнение подоператора повторяется, пока значение выражения остается ненулевым. Проверка выполняется перед каждым выполнением оператора.

Нет здесь никаких пометок окончания оператора( типа ( ; )).
Следующая цитата:

9.13 Пустой оператор

Пустой оператор имеет вид


;


Пустой оператор используется для помещения метки непосредственно перед } составного оператора или того, чтобы снабдить такие операторы, как while, пустым телом.

Нормальную книжку я прочитал?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

gavrasio писал(а):Нормальную книжку я прочитал?
нет
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
gavrasio
Нашел транзистор. Понюхал.
Сообщения: 162
Зарегистрирован: Пн июн 01, 2015 15:23:01

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

Сообщение gavrasio »

ARV писал(а):
gavrasio писал(а):Нормальную книжку я прочитал?
нет

Так, подскажи, какую читать!
Аватара пользователя
c2n
Сверлит текстолит когтями
Сообщения: 1193
Зарегистрирован: Ср июл 25, 2012 21:40:09
Откуда: Самара
Контактная информация:

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

Сообщение c2n »

Страуструппа читать надобно токмо после Керниган Ритчи.
Ссылка
Последний раз редактировалось Аlex Вс ноя 08, 2015 01:08:14, всего редактировалось 1 раз.
Причина: Поправил ссылку
Аватара пользователя
НАПАЛМ
Это не хвост, это антенна
Сообщения: 1314
Зарегистрирован: Пт ноя 27, 2009 19:47:13
Откуда: Казань

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

Сообщение НАПАЛМ »

Доброго времени суток.
Понадобилось таймер в режиме СТС использовать для задания временного интервала. Делаю следующее:

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

ldi r16, 160
   out OCR0A, r16      ;160 тиков при 16МГц для 10мкс

   ldi r16, (1<<TOIE0)
   sts TIMSK0, r16     ;прерывание по переполнению (максимальное значение снижено с 255 до OCR0A)

   ldi r16, (0<<WGM02)|(1<<WGM01)|(0<<WGM00)
   out TCCR0A, r16 ;Clear Timer on Compare Match (CTC) Mode
sei


Потом жду команды с компа. Как только приходит нужная, запускаю счетчик

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

ldi r16, (0<<CS02)|(0<<CS01)|(1<<CS00)  ;запускаем счетчик
   out TCCR0B, r16                         ;тактирование без предделителя


И проблема в чем: в процессе отладки выяснилось, что мк даже не заходит в обработчик прерывания. Подскажите, может что-то упустил из виду.
Обработчик пишу по вектору переполнения таймера.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

НАПАЛМ писал(а):Обработчик пишу по вектору переполнения таймера.
Да и не должен контроллер заходить в этот обработчик. Для ATtiny13, примерно, будет выглядеть так.
Спойлер

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

        .org 6
T0_COMPA:
   NOP
        reti
;************************
 ldi r16, 160-1      ;ldi r16, 160
   out OCR0A, r16      ;160 тиков при 16МГц для 10мкс

   ldi r16, (1<<OCIE0)     ;   ldi r16, (1<<TOIE0)
   OUT TIMSK0, r16     ;прерывание по совпадению  OCR0A
   OUT TIFR0,R16

   ldi r16, (0<<WGM02)|(1<<WGM01)|(0<<WGM00)
   out TCCR0A, r16 ;Clear Timer on Compare Match (CTC) Mode

ldi r16, (0<<CS02)|(0<<CS01)|(1<<CS00)  ;запускаем счетчик
   out TCCR0B, r16                         ;тактирование без предделителя

   sei
   RJMP  PC+0
Аватара пользователя
НАПАЛМ
Это не хвост, это антенна
Сообщения: 1314
Зарегистрирован: Пт ноя 27, 2009 19:47:13
Откуда: Казань

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

Сообщение НАПАЛМ »

Ага, понял. Не по переполнению, а по совпадению работаем. Спасибо.
xcoma
Родился
Сообщения: 11
Зарегистрирован: Ср янв 22, 2014 20:26:04

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

Сообщение xcoma »

Всех категорически приветствую.
Начал разбираться с прерываниями и таймерами, создаю проект в CodeVisionAVR (простейшая программа мигания светодиода на ножке PORTB.0, внешний часовой кварц на TOSC1 TOSC2,
коэф. деления 128 - возникновение прерывания по переполнению)
Не работает! Комрады посмотрите пожалуйста где ошибка
СпойлерChip type : ATmega168PA
Program type : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*******************************************************/

#include <io.h>

// Declare your global variables here
typedef struct{
unsigned char second;
unsigned char minute;
unsigned int hour;
}time;

time t;
bit bitt=1;
// Timer2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
PORTB.0=bitt;
bitt=~bitt;
if (++t.second==60)
{
t.second=0;


if (++t.minute==60)
{
t.minute=0;
t.hour++;

}
}
}

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=(1<<CLKPCE);
CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=Out
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (1<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=0
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRC=(0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=In Bit5=Out Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (0<<DDD6) | (1<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=0 Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: Crystal on TOSC1 pin
// Clock value: PCK2/128
// Mode: Normal top=0xFF
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=(0<<EXCLK) | (1<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (0<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (1<<CS22) | (0<<CS21) | (1<<CS20);
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (0<<TOIE0);

// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1);

// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=(0<<OCIE2B) | (0<<OCIE2A) | (1<<TOIE2);

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIMSK=(0<<INT1) | (0<<INT0);
PCICR=(0<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);

// USART initialization
// USART disabled
UCSR0B=(0<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (0<<RXEN0) | (0<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
ADCSRB=(0<<ACME);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR1=(0<<AIN0D) | (0<<AIN1D);

// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);

// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);

// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);

// Globally enable interrupts
#asm("sei")

while (1)
{
if (t.hour>1) PORTD.5=1; // Сигнализируем, что прошел 1 час

}
}


Спасибо
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

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

Сообщение Z_h_e »

xcoma, попробуйте затактировать таймер от внутреннего источника. Вдруг какая проблема с кварцем.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

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

Сообщение B@R5uk »

xcoma писал(а):TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
Что ж вы хотите, когда у вас таймер остановлен? Перепроверьте все настройки ещё раз, сверив их с даташитом. Какой МК, кстати, используете, про это, пожалуй, в первую очередь надо было написать.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

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

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

ASSR=(0<<EXCLK) | (1<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (0<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (1<<CS22) | (0<<CS21) | (1<<CS20);

Желательно выполнить требования раздела Asynchronous Operation of Timer/Counter2 DS.
Аватара пользователя
Jeka_M
Встал на лапы
Сообщения: 101
Зарегистрирован: Пт окт 03, 2014 14:50:06

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

Сообщение Jeka_M »

xcoma выкинь CodeVision нафиг. Автоматическая генерация настроек регистров к хорошему не приводит, настраивай всё сам с помощью даташита.
Ответить

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