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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
bezzabotna
Встал на лапы
Сообщения: 134
Зарегистрирован: Пн ноя 07, 2016 12:14:14

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

Сообщение bezzabotna »

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

#define BUTTON_UP      (1<<PD4)                     //4 ножка
#define BUTTON_DOWN      (1<<PD5)                     //5 ножка
#define BUTTON_START   (1<<PD6)                     //6 ножка
#define BUTTON_STOP      (1<<PD7)                     //7 ножка
Я конечно все понимаю, но этого я не понимаю.
Аватара пользователя
prinv
Вымогатель припоя
Сообщения: 677
Зарегистрирован: Чт янв 20, 2011 09:07:08
Откуда: Пермь
Контактная информация:

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

Сообщение prinv »

Смотрю я ваш BUTTON_Handler - что-то больно накручено. Некоторые куски кода вообще никогда не выполнятся.
Например, секция else

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

   if (!(PIND & pin_state))                        //если кнопка физически нажата (логический 0 на n ножке порта D)
   {
      if(Button_count<20)   Button_count++;               //подавление дребезга при нажатии (кнопка физически нажата 20 тактов)
      else
      {
         Button_state=1;                           //регистрируем нажатие кнопки
         key_delay++;                           //как долго кнопка нажата
      }
Никакая контра не уйдёт от нас
Аватара пользователя
bezzabotna
Встал на лапы
Сообщения: 134
Зарегистрирован: Пн ноя 07, 2016 12:14:14

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

Сообщение bezzabotna »

Почему? Я этот кусок кода на stm32 использовала, на реальном камне. Все работало. Но там естественно по другому выглядит условие физического нажатия.
Может условие иначе надо прописать?
Я конечно все понимаю, но этого я не понимаю.
Аватара пользователя
prinv
Вымогатель припоя
Сообщения: 677
Зарегистрирован: Чт янв 20, 2011 09:07:08
Откуда: Пермь
Контактная информация:

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

Сообщение prinv »

Как почему? У вас при вызове функции Button_count = 0.
И потом вы проверяете Button_count<20
У вас никогда Button_count никогда не станет больше 20, следовательно ветка else никогда не выполнится.

Вот здесь наоборот - только ветка else и будет выпоняться, в которой условие key_delay<20000 будет выполняться всегда.

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

      if (Button_count>0)Button_count--;               //подавление дребезга при отжатии
      else
      {
         Button_state=0;                           //регистрируем отжатие кнопки
         if (key_delay<20000)   Flag=1;               //регистрируем короткое нажатие
         else               Flag=2;               //регистрируем длительное нажатие
     


Но это всё уже к таймерам отношения не имеет, imho.
Никакая контра не уйдёт от нас
Аватара пользователя
bezzabotna
Встал на лапы
Сообщения: 134
Зарегистрирован: Пн ноя 07, 2016 12:14:14

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

Сообщение bezzabotna »

Спасибо, буду разбирать
Я конечно все понимаю, но этого я не понимаю.
Аватара пользователя
afz
Опытный кот
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

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

Сообщение afz »

bezzabotna писал(а):int Button_count=0,Button_state=0,key_delay=0,Flag=0; //служебные переменные
Неудивительно, что кнопки не опознаются. Процитированная строка по каждому прерыванию от таймера инитит эти самые служебные переменные, поэтому при сравнении if'ами в Button_count ничего, кроме единицы, быть не может.

Когда-то я решал подобную задачу - принять данные с сильно дребезжащего контакта. Я тогда, по-простому, сделал программные аналоги последовательно включенных интегратора и триггера Шмидта. Аналоги грубые, сильно упрощенные, тем не менее...

Итак, предположим, что таймерные прерывания у нас будут с периодом 1 мс (1 кГц). Заводим в статической памяти, вне (до) всех функций (чтобы не возиться с передачей параметров) табличку, которая для каждой из кнопок содержит следующие данные (навскидку)
1) время замкнутого состояния контактов кнопки.
2) флажок "распознанное состояние кнопки"
3) флажок "предыдущее состояние кнопки"
4) (возможно) флажок "состояние кнопки изменилось" в качестве сигнала главной программе, мол проснись и поработай. :)
5) (если нужно) время распознанного нажатого состояния кнопки, например, для распознавания коротких и длительных нажатий.

При инициализации, обязательно до разрешения таймерных прерываний, все эти поля надо очистить (обнулить).

В программе прерывания по таймеру, для каждой изх кнопок, проверяем, замкнута она, или нет. Если замкнута, инкрементируем поле (1) и, если оно совпадет с порогом срабатывания "триггера Шмидта", взводим флажок (2), если надо, сравниваем этот флажок с (3) и, если они не совпадают взводим флажок (4) и обновляем (3). Далее проверим, не пора ли нашему "интегратору" входить в насыщение. если да, организовываем это насыщение, то есть отменяем инкремент поля (1). Здесь же, обнаружив распознанное состояние кнопки, можно начать инкрементировать (5) и, обнаружив длительное нажатие, послать соответствующий сигнал.

Если же кнопик разомкнут, декрементируем поле (1) и, если оно совпадает с порогом отпускания триггера Шмитта, очищаем флажок (2) и, опять же, сравниваем (2) и (3), действия при несовпадении те же, что и выше. Далее, опять же, проверяем на насыщение (отрицательное), то есть, если (1) станет отрицательным, обнуляем его, и вперед.

Теперь о порогах. Навскидку, порог отпускания триггера Шмитта нужно взять 5-10, порог срабатывания его же - 20-25 и порог насыщения - на 5-10 больше, чем порог срабатывания.

А основная программа должна мониторить поля (2) каждой из кнопок и, обнаружив нажатие, предпринимать соответствующие действия. Или, может быть, флажок (4), если он очищен, можно заснуть (Sleep). Может быть флажок (4) нужен не каждой кнопке, а один на всех, это уже по вкусу.

Да, зачем для этого дела 16-битный таймер 1 ? Там и 8-битного за глаза, только нужен таймер с Clear to Compare (CTC). У 8-й Меги это Т2, 328-ю я наизусть не помню. А так, прескалером делим на 1024, даже из 20 МГц получим порядка 20 кГц, делим таймером на 20 и вот он, желаемый 1 кГц прерываний. Да, 1024 - это не 1000, но точность этой миллисекунды здесь и даром не нужна.

bezzabotna писал(а):Почему? Я этот кусок кода на stm32 использовала, на реальном камне. Все работало.
Может быть неудачно скопипастила?
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Аватара пользователя
prinv
Вымогатель припоя
Сообщения: 677
Зарегистрирован: Чт янв 20, 2011 09:07:08
Откуда: Пермь
Контактная информация:

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

Сообщение prinv »

Заводим в статической памяти, вне (до) всех функций (чтобы не возиться с передачей параметров) табличку, которая для каждой из кнопок содержит следующие данные (навскидку)

Можно завести и внутри обработчика, только с использованием модификатора static - так будет правильнее в точки зрения области видимости переменных.
Никакая контра не уйдёт от нас
Аватара пользователя
afz
Опытный кот
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

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

Сообщение afz »

Нет, здесь, как раз, нужна довольно широкая видимость. Таблицу надо проинитить, ее надо видеть из программы обслуживания прерывания, по крайней мере, флажки нужно видеть в программе реакции на нажатие клавиш, там же нужен счетчик длительного нажатия, в общем, проще сделать полную видимость этой таблицы везде и не морочить себе голову.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Аватара пользователя
artemik32
Встал на лапы
Сообщения: 121
Зарегистрирован: Пт сен 04, 2015 13:10:49
Откуда: г. Ижевск

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

Сообщение artemik32 »

Добрый день! Подскажите пожалуйста, как сделать, чтобы в режиме ШИМ - два канала таймера работали попеременно, т.е. допустим на канале А идут импульсы ШИМ, а на канале В - никаких импульсов не должно быть, даже "иголок". А то даже при OCR0B = 0, присутствуют "иголки". Два канала таймера работают на Н-мост и поэтому из-за "иголок" происходит "сквозняк". Можно ли выключить отдельно тот или другой канал?
Истина где-то рядом...
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

artemik32 писал(а):Можно ли выключить отдельно тот или другой канал?
во-первых, можно выключить. во-вторых, иголки - это, как правило, ЕСТЕСТВЕННОЕ состояние для Fast-PWM при одном из "крайних" значений регистра сравнения.
то есть либо надо выбирать правильный режим PWM, либо отключать канал программно в нужный момент. вы же как-то включали оба канала? значит, и выключить один сумеете.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

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

Сообщение Demiurg »

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

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

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

Подскажите, пожалуйста, в каких моделях AVR, кроме ATtiny2313A, есть одновременно 16-битный таймер с захватом и 8-битный с внешними входом и выходом?
Аватара пользователя
afz
Опытный кот
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

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

Сообщение afz »

Детально я, конечно, не вникал, но у Мег 48-88-168-328 блок-схема таймера 0 та же, что и у 2313А. Да и у 16-й (без А) у таймера 0 есть вход и выход. Как мне кажется, только у 8-й Меги такого нет, у остальных Мег должно быть.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

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

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

Понятно, спасибо. Что-то 8-я мега какая-то обделённая получается. У всех другим мег есть такой таймер, а у 8-й нет. А у меня их целых три не при делах лежит.
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

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

Сообщение Пока_без_кота »

Доброго времени суток. Прошу прощения за нубский вопрос. Смотрю даташит на Мегу8, а именно на режимы работы Timer1, и вижу, что режим 4 фактически идентичен режиму 12, режим 8 - режиму 9, режим 10 - режиму 11, а режим 13 - режиму 14. Все эти пары режимов отличаются только регистром, из которого они берут значение для сравнения. В одном случае это ICR1, во втором - OCR1A. И я не понимаю, зачем было так делать, ведь режим таймера может быть включен все равно только один. Какой тогда смысл в таком дублировании ? Может быть я чего-то не понимаю, тогда приведите пожалуйста пример, когда такая организация может пригодится.
Аватара пользователя
B@R5uk
Собутыльник Кота
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

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

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

У таймера 1 есть два выхода: OC1A и OC1B. При реализации ШИМа каждый из этих выходов управляется, соответственно, регистрами OCR1A и OCR1B. Если нужен ШИМ с какой-нибудь нестандартной длительностью, то нужен ещё один регистр для хранения этого нестандартного потолка таймера. Этим регистром может являться либо OCR1A, либо ICR1. Если использовать первый регистр, то невозможно будет управлять скважностью канала A, то есть сразу лишимся одного ШИМ-канала. Если же использовать второй регистр, то не будет возможности использовать захват по событию.

Конструкторы чипа просто предоставили своим коллегам, которые этот чип будут использовать в своих разработках, некоторую гибкость: можно в зависимости от потребностей использовать тот или иной регистр. Хотя, разумеется, наиболее правильно было бы завести для этого дела отдельный регистр. Но AVR — это не STM32 с её четырьмя гигабайтами на всё-про-всё. У AVR область портов ввода-вывода ограничена. Поэтому конструкторы решили сэкономить: использовать регистры с двойным назначением в зависимости от режима.
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

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

Сообщение Пока_без_кота »

... Если нужен ШИМ с какой-нибудь нестандартной длительностью...

Спасибо, вроде как кое-что прояснилось. Но не все :oops: Непонятно, что значит "нестандартной длительностью" ?
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

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

Сообщение Ivanoff-iv »

не равной разрядности счетчика, а с любым числом, например 100 (будет шим ровно в 100 шагов, например для получения шага ровно в 1%)
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

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

Сообщение Пока_без_кота »

Спасибо за разъяснение.
Dream555
Встал на лапы
Сообщения: 99
Зарегистрирован: Сб апр 28, 2018 20:29:42

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

Сообщение Dream555 »

Всем привет!

Предисловие:
Я делаю себе таймер на ATmeg48 с внутренним тактированием от RC 8MHz. Хочу повесить часовой кварц для точного счета.

А вот теперь вопрос:
Правильно ли я понимаю, что для данной задачи подойдет только Timer/Counter2? По крайней мере в даташите говориться, что для асинхронного тактирования используется этот счетчик.
Ответить

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