Обсуждаем контроллеры компании Atmel.
Ответить

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

Ср июн 06, 2018 13:10:22

Код:
#define BUTTON_UP      (1<<PD4)                     //4 ножка
#define BUTTON_DOWN      (1<<PD5)                     //5 ножка
#define BUTTON_START   (1<<PD6)                     //6 ножка
#define BUTTON_STOP      (1<<PD7)                     //7 ножка

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

Ср июн 06, 2018 13:26:51

Смотрю я ваш BUTTON_Handler - что-то больно накручено. Некоторые куски кода вообще никогда не выполнятся.
Например, секция else
Код:
   if (!(PIND & pin_state))                        //если кнопка физически нажата (логический 0 на n ножке порта D)
   {
      if(Button_count<20)   Button_count++;               //подавление дребезга при нажатии (кнопка физически нажата 20 тактов)
      else
      {
         Button_state=1;                           //регистрируем нажатие кнопки
         key_delay++;                           //как долго кнопка нажата
      }

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

Ср июн 06, 2018 13:31:41

Почему? Я этот кусок кода на stm32 использовала, на реальном камне. Все работало. Но там естественно по другому выглядит условие физического нажатия.
Может условие иначе надо прописать?

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

Ср июн 06, 2018 13:34:18

Как почему? У вас при вызове функции 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.

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

Ср июн 06, 2018 14:40:02

Спасибо, буду разбирать

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

Сб июн 09, 2018 19:40:03

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 использовала, на реальном камне. Все работало.
Может быть неудачно скопипастила?

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

Вс июн 10, 2018 09:32:01

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

Можно завести и внутри обработчика, только с использованием модификатора static - так будет правильнее в точки зрения области видимости переменных.

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

Вс июн 10, 2018 13:38:14

Нет, здесь, как раз, нужна довольно широкая видимость. Таблицу надо проинитить, ее надо видеть из программы обслуживания прерывания, по крайней мере, флажки нужно видеть в программе реакции на нажатие клавиш, там же нужен счетчик длительного нажатия, в общем, проще сделать полную видимость этой таблицы везде и не морочить себе голову.

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

Ср июл 04, 2018 07:41:38

Добрый день! Подскажите пожалуйста, как сделать, чтобы в режиме ШИМ - два канала таймера работали попеременно, т.е. допустим на канале А идут импульсы ШИМ, а на канале В - никаких импульсов не должно быть, даже "иголок". А то даже при OCR0B = 0, присутствуют "иголки". Два канала таймера работают на Н-мост и поэтому из-за "иголок" происходит "сквозняк". Можно ли выключить отдельно тот или другой канал?

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

Ср июл 04, 2018 07:52:39

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

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

Ср июл 04, 2018 08:26:30

Сделать кусок программы проверяющий на ноль содержимое регистра сравнения. Если 0,то выключить соответствующий канал.

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

Сб июл 28, 2018 13:02:30

Подскажите, пожалуйста, в каких моделях AVR, кроме ATtiny2313A, есть одновременно 16-битный таймер с захватом и 8-битный с внешними входом и выходом?

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

Сб июл 28, 2018 17:52:43

Детально я, конечно, не вникал, но у Мег 48-88-168-328 блок-схема таймера 0 та же, что и у 2313А. Да и у 16-й (без А) у таймера 0 есть вход и выход. Как мне кажется, только у 8-й Меги такого нет, у остальных Мег должно быть.

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

Сб июл 28, 2018 20:48:26

Понятно, спасибо. Что-то 8-я мега какая-то обделённая получается. У всех другим мег есть такой таймер, а у 8-й нет. А у меня их целых три не при делах лежит.

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

Ср авг 01, 2018 21:58:11

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

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

Ср авг 01, 2018 22:23:34

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

Конструкторы чипа просто предоставили своим коллегам, которые этот чип будут использовать в своих разработках, некоторую гибкость: можно в зависимости от потребностей использовать тот или иной регистр. Хотя, разумеется, наиболее правильно было бы завести для этого дела отдельный регистр. Но AVR — это не STM32 с её четырьмя гигабайтами на всё-про-всё. У AVR область портов ввода-вывода ограничена. Поэтому конструкторы решили сэкономить: использовать регистры с двойным назначением в зависимости от режима.

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

Чт авг 02, 2018 08:58:37

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

Спасибо, вроде как кое-что прояснилось. Но не все :oops: Непонятно, что значит "нестандартной длительностью" ?

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

Чт авг 02, 2018 09:05:35

не равной разрядности счетчика, а с любым числом, например 100 (будет шим ровно в 100 шагов, например для получения шага ровно в 1%)

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

Чт авг 02, 2018 10:11:59

Спасибо за разъяснение.

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

Чт сен 06, 2018 15:38:16

Всем привет!

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

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