Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » atXmega - Quadrature Decoder Channels


atXmega - Quadrature Decoder Channels

Сообщений 31 страница 60 из 75

31

Вот... вот оно!!!  :crazyfun: для глазок:

Отредактировано Ev3658 (2016-12-03 18:37:32)

0

32

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

0

33

Пётр написал(а):

...счетчик будет много раз переполнятся.

Это да, длина линейки как раз впритык счётчика, остаётся 1000 с небольшим.
Заявленная длина линейки 30см. точность линейки 0,005мм. = 60 000 прерываний + там запас хода линейки в 5000.
Очень быстро обрабатывает, если линейку туды-сюды тыркать с большой скоростью, значения не убегают.
Вот бы ещё сигнал нулевой метки как-то инициировать на другой таймер, но как сделать убавление-прибавление согласно движению на аппаратном уровне, пока не знаю.
Так-то я добился того, что надо, мне надо замерять разницу линеек в перемещении, с аппаратной поддержкой вообще халява  :D

0

34

Ev3658 написал(а):

Вот бы ещё сигнал нулевой метки как-то инициировать на другой таймер

Что этот сигнал из себя представляет? Короткий импульс при прохождении линейки в определенной позиции или что-то другое?

0

35

Пётр написал(а):

Что этот сигнал из себя представляет? ....

Этот сигнал везде по разному, на моторах он 1 раз за оборот, в линейках либо по краям, либо как контрольная метка.
В системе событий он тоже существует как QDINX - стр.64

Сигналы QDPH0 и QDPH90 - два квадратурных сигнала. Когда QDPH90 опережает QDPH0, вращение считается в прямом направлении. Если же QDPH0 опережает QDPH90, то вращение считается в обратном (реверсном) направлении. Последовательность состояний двух различающихся по фазе сигналов называется квадратурным состоянием или фазовым состоянием.
Чтобы определить абсолютную величину углового движения можно использовать третий, индексный сигнал (QDINDX), который сигнализирует о выполнении каждого оборота.
6.7.2 Настройка квадратурного декодера
Для полной настройки QDEC необходимо выполнить следующее:
1. Линии портов ввода-вывода - вход квадратурного сигнала
2. Система событий - квадратурная дешифрация
3. Таймер-счетчик - счет вперед, назад и опциональный индексный счет
4. Для настройки QDEC необходимо выполнить следующие процедуры:
5. Выбрать два соседних вывода порта в качестве входов QDEC.
6. Указать, что выводы QDPH0 и QDPH90 являются входами.
7. Настроить выводы QDPH0 и QDPH90 на обнаружение низкого уровня.
8. Выбрать вывод QDPH0 в качестве входа мультиплексора канала событий n.
9. Разрешить квадратурную дешифрацию и цифровую фильтрацию в канале события.
10. Опционально:
11. Настроить индексный вход QDEC (QINDX).
12. Выбрать третий, индексный, вход QINDX.
13. Указать, что QINDX является входом.
14. Настроить вывод QINDX на обнаружение обоих фронтов.
15. Выбрать QINDX в качестве входа мультиплексора канала событий n+1
16. Установить бит разрешения квадратурного индекса в канале событий n+1.
17. Выбрать режим распознавания индекса в канале событий n+1.
18. Указать, что квадратурная дешифрация является действием события для таймера-счетчика.
19. Выбрать таймер-счетчик источником событий для канала событий n.
20. Настроить регистр периода таймера-счетчика равным ('число меток' * 4 - 1), где число меток - параметр квадратурного энкодера.
21. Разрешить работу таймера-счетчика настройкой бит CLKSEL в регистре CLKSEL_DIV1.
В результате, величину углового перемещения квадратурного энкодера, генерирующего сигналы QDPH0, QDPH90 (и QINDX) можно будет считать непосредственно из счетного регистра таймера-счетчика. Если значение в счетном регистре отличается от значения BOTTOM, по которому распознается индекс, устанавливается флаг ошибки таймера-счетчика. Аналогичным образом, установка флага ошибки происходит, если счетчик положения пересекает значение BOTTOM без распознавания индекса.

0

36

Вот не задача! Решил использовать второй таймер для расширения битности счётчика, но он считает только в одну сторону  :'(

Реализация аппаратного подсчёта вот такая:

1. Делаем порты энкодера на вход:
Config Porta.5 = Input                                     
Config Porta.6 = Input     
               

2. Если нужно, включаем подтягивающие регистры, мне не надо было:
Porta_pin5ctrl = &B00000000 
Porta_pin6ctrl = &B00000000

3. Настраиваем мультиплексор с поддержкой квадратурной дешифрации (это №0,2,4) на 1 Pin5 (если на Pin6, то не работает):
Evsys_ch0mux = &B01010101

4. Настраиваем квадратурное событие и фильтр канала (фильтр канала если =0, то ничего не происходит):
Evsys_ch0ctrl = &B00011001

5. Настраиваем счётчик/таймер Tcc0 на подсчёт импульсов по каналу события 0 по принципу квадратурной шифрацией и ставим задержку "Event_delay "  (в хелпе говорят нужно для 32битной реализации):
Config Tcc0 = Normal , Prescale = &B111 , Event_source = &B1000 , Event_action = Qdec , Event_delay = Enabled

Всё, квадратурный подсчёт работает отлично!!!! Правда от 0 до 65535 импульсов, значение получаем в переменная_WORD=TCC0_CNT
===================
Решил расширить разрядность, но вот оказался в тупике, не могу заставить считать при переполнении квадратурного таймера в уменьшение и в прибавление другой таймер.

Для 32 битной реализации делаю так:
1.Беру канасл события №1 и настраиваю на собтие таймера С0 (который квадратуру считает) и на событие "переполнение/незаполнение(x=C,D,E или F)(n=0 или 1)
Evsys_ch1mux = &B11000100

2.Настраиваю счётчик/таймер TcD0 на канал события 1 по принципу события UPDOWN (внешне-управляемый прямой/обратный счёт)
Config Tcd0 = Normal , Prescale = &B111 , Event_source = &B1001 , Event_action = Updown

Начинаю крутить энкодер, переполнять его в обе стороны, вообщем всё время второй таймер прибавляет +1 +1 и никак не могу заставить его убавляться.

Всё это как-бы должно работать на аппаратном уровне, может чего не понимаю, все регистры перелопатил и нет представления, как канал события должен отправить команду таймеру на убавление или прибавление?  %-)

0

37

Видимо возможно только на подсчёт импульсов в одну сторону, как-то странно, такие сложности в Xmega замутили, а лишний бит decr забыли сделать...не, не верю.

Настройка 32-битного ТС с входным захватом

   Задача: Настройте таймеры TCC0 и TCC1 как один 32-битный TC с входным захватом по каналу А и срабатыванием по заднему (падающему) фронту на ножке PC0. Канал событий 0 используется для переноса переполнения, пока входной сигнал захвата от PC0 переходит на канал событий 1.

   1. Настройте PC0 как вход, срабатывающий по заднему фронту.

   2. Настройте PC0 как вход мультиплексора для канала событий 1.

   3. Настройте переполнение по TCC0 как вход мультиплексора для канала событий 0.

   4. Настройте TCC0 и TCC1 как входной захват со срабатыванием по каналу событий 1.

   5. Разрешите задержку события TCC1 (это задержит событие по захвату входа на один цикл, чтобы позволить переполнению от TCC0 перейти к TCC1 прежде, чем произойдет входной захват).

   6. Разрешить входной захват по каналу А на TCC0 и TCC1.

   7. Выберите канал событий 0 как источник тактирования для TCC1 битами CLKSEL в регистре CTRLA.

   8. Запустите TCC0, выбрав системные часы как источник тактирования битами CLKSEL в регистре CTRLA.

   9. Ожидайте установки в регистре INTFLAGS флага прерывания А входного захвата TCC0 или TCC1.

   10. Прочитайте значение младшего слова входного захвата в регистре TCC0.CCA[H:L].

   11. Прочитайте значение старшего слова входного захвата в регистре TCC1.CCA[H:L].

   12. Объедините младшее и старшее слова в 32-битное значение входного захвата.

   13. И так далее с пункта 9.

0

38

Всё перепробовал! Если делать составной таймер из двух 16 битных, то можно вести счёт только в одном направлении, в уменьшение по событию второй таймер не пойдёт, только на прибавление.

0

39

Я не понимаю, зачем вообще это делать?
Если что-то и куда-то не влазит или надо большей скорости срабатывания, не проще менять Prescale или тактирование МК.

0

40

RDW написал(а):

Я не понимаю, зачем вообще это делать?....

Для двигателей счётчика хватает, но если надо следить за пространством перемещения, то 16 битного счётчика хватает не более чем на 35см. с шагом 0,005мм.
К примеру у нас есть ЧПУ станок, длина оптической линейки 450мм, точность деления 0,001мм. - это 400000 - шесть с лишним раз переполнения таймера. Если бы удалось подвязать хотя-бы 8 битный таймер, можно было бы без проблем реализовать слежение за тремя осями одновременно на одном контроллере, а тут приходится черед прерывание:

Код:
On Tcc0_ovf Tim1
Enable Interrupts
Enable Tcc0_ovf
...
...
...
...
Tim1:

If Tcc0_ctrlfset.0 = 1 Then
   Incr Lineyka1
   Else
      Decr Lineyka1
End If

0

41

А ты по линейкам что ли позиции ищешь на поверхности? Абсолютная координация?
Вроде все станки максимум контролируют четкость выполнение команд и нулевая точка, всё равно тупо концевиком делается...это я к чему: уменьшаешь частоту таймера, туда начинает лезть вся линейка - всё.
Просто если алгоритм работы станка идет именно отталкиваясь от четкой позиции линейки/станины, то при большой точности, может получить кучу ошибок, т.к. тсанок может: вибрировать, иметь дефекты механики движения (как электронной, так и механической).

На счет сделать большую точность за счет добавления ещё 8 битный счетчика/регистра - а почему бы и нет, происходит переполнение счетчика > срабатывает прерывание > в прерывании увеличиваем байт/регистр (расширения). Дальше просто это учитываем в программе, на скорости МК - это минимально скажется. Или так сделать нельзя? Есть механизм отслеживания в какую сторону произошло переполнение?

0

42

До станка в целом ещё не такой уж и долгий путь  :hobo:
VGA - решается
Слежение за координатами - в завершении.
Аппаратная квадратурная штука у Xmega довольно шустрая, хорошо следит за счётом.
Есть регистр к примеру в таймере ТСС0, вот так пишется Tcc0_ctrlfset.0 = 1 - нулевой бит, этот бит показывает, в какую сторону идёт счёт. Жаль, что он не передаётся по событию.
Задача у меня стоит, сделать ЧПУ токарный станок. Линеек нет, но есть двигателя, которые за 1 оборот выдают 10000 прерываний и делает он 2-3тыс.оборотов в минуту, тут как не крути, без аппаратной поддержки никак.
К примеру он 5мм. перемещения делает за 1 оборот, нужно не только перемещение сделать, учитывая позицию, но и сигнализировать расхождение, задействовать алгоритм удержания, регулировать скорости и синхронизацию аж 3х осей (шпиндель).
1 контроллер на два таких двигателя + шпиндель - это уже реально, хотелось бы декрементировать и инкрементировать значение второго таймера для повышения разрядности.
Обнаружил, что если отлавливать нулевую метку (Z-метка линеек и энкодеров), то значение не стабильное, хотя в документации написано, что есть другой механизм аппаратного сброса.
Ноль коонечнику никогда не выставляется, а если выставляется, то это ущербный не точный станок, в котором такой конечник дороже самого станка  :D .
Для выхода в ноль в нужном направлении ищется конечник, как только находится, в определённой зоне сигналов энкодера ищется нулевая метка (Z-метка), по этом сигналу можно выставить ноль, но ноль выставляется по делению энкодера на каком нибудь сигнале Z метки (обычно он не один, а пучок).

0

43

Ev3658 написал(а):

этот бит показывает, в какую сторону идёт счёт

Уже что-то, прерывание срабатывает, смотрим на этот бит, в зависимости от этого делаем сложение/вычитание переменной.

0

44

Гадкий Youtube, опять видео растянул, всё-же вот работа 2х недель:

Со звуком веселее  :rofl:

0

45

Супер! И камеру проапгрейдил! ))) Теперь в нормальном разрешении.

Так получилось сделать 24 разряда счета (3 байта)?

0

46

RDW написал(а):

Супер! И камеру проапгрейдил! ))) Теперь в нормальном разрешении.

Так получилось сделать 24 разряда счета (3 байта)?

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

0

47

Свершилось!!!!
Две недели разрабатывал устройство и колхозил прошивку, изучая всю эту тему, но спустя два месяца наконец-то прикрепили эти измерительный оптические линейки к листогибу.
Два месяца делать двёх дневную работу - просто жесть, всё-же вот:

Контроллер Xmega32A4.

+4

48

Какая красота.  :music:  :cool:

0

49

:cool:

0

50

А скрепки сама гнуть может?  :flirt:

0

51

Немного переведу на язык bascom AVR:

Код:
Config Pina.0 = Input                                       'A
Config Pina.1 = Input                                       'B
Config Pina.2 = Input                                       'Z
Config Xpin = Pina.0 , Sense = Rising                       'Контроль входа на обнаружение падающего фронта
Config Xpin = Pina.1 , Sense = Rising                       'Контроль входа на обнаружение падающего фронта
Config Xpin = Pina.2 , Sense = Both                         'Для индекса метки, не обязательно, если кто знает как можно сделать по ней обнуление счёта, буду рад услышать

Config Event_system = Dummy , Mux0 = Porta.0 , Qd0 = Enabled , Qdi0 = Enabled , Qdirm0 = 2 , Digflt0 = 2  'Квадратуру поддерживает канал 0,2,4, фильтр Digflt минимум 2, если 1 то не считает, Qdi - не обязательно, не знаю как работает индекс, как-то связано с Z меткой энкодера  

Config Tcc1 = Normal , Prescale = E0 , Event_source = E0 , Event_action = Qdec  'Таймер может быть любым TCF0 TCF1 TCC0 TCC1 TCD0 TCD1 TCE0 TCE1,  E0-E7 - каналы события

TCC1_PER = 10000 'Это ограничение счёта таймера, по умолчанию он 65536, но если надо ограничить, то юзайте этот регистр


Два энкодера можно впихнуть в один порт. Выход энкодера "А" должен быть первым и дальше по порядку, к примеру вот на два энкодера можно сделать так:

Код:
Config Pina.0 = Input                                       'A
Config Pina.1 = Input                                       'B
Config Pina.2 = Input                                       'Z
Config Xpin = Pina.0 , Sense = Rising                       'Контроль входа на обнаружение падающего фронта
Config Xpin = Pina.1 , Sense = Rising                       'Контроль входа на обнаружение падающего фронта
Config Xpin = Pina.2 , Sense = Both                         'Контроль входа на обнаружение падающего фронта

Config Porta.3 = Input                                      'A
Config Porta.4 = Input                                      'B
Config Porta.5 = Input                                      'Z
Config Xpin = Porta.3 , Sense = Rising                      'Контроль входа на обнаружение падающего фронта
Config Xpin = Porta.4 , Sense = Rising                      'Контроль входа на обнаружение падающего фронта
Config Xpin = Porta.5 , Sense = Both    


Config Event_system = Dummy , Mux0 = Porta.0 , Qd0 = Enabled , Qdi0 = Enabled , Qdirm0 = 2 , Digflt0 = 2
Config Event_system = Dummy , Mux2 = Porta.3 , Qd2 = Enabled , Qdi2 = Enabled , Qdirm2 = 0 , Digflt2 = 2

Config Tcc1 = Normal , Prescale = E0 , Event_source = E0 , Event_action = Qdec
Config Tcc0 = Normal , Prescale = E2 , Event_source = E2 , Event_action = Qdec


Данные счёта можно получить с регистра TCxx_CNT, к примеру W=Tcc1_CNT.

Скорость обработки просто жесть, у меня мотор выдаёт 3000 оборотов, за 1 оборот 10000 положений квадратуры и контроллер не ошибается в счёте в обоих направлениях.

+1

52

Спасибо за изложение. Только мне кажется было бы супер, если добавить картинку/схему для конкретного примера под изложение "энкодера можно впихнуть в один порт. Выход энкодера "А" должен быть первым и дальше по порядку".

0

53

Вот ты красавец, зачем ты начал им на немецкий переводить? :D

0

54

RDW написал(а):

Вот ты красавец, зачем ты начал им на немецкий переводить?

Да они и по английски не понимают ))))
Я бы написал подробнее про квадратуру, но не знаю её полностью её принцип работы.
Надо очень узнать как сбрасывать счётчик по Z метке и квадратурному индексу, а так-же как сделать двунаправленный счёт во втором таймере, чтоб обеспечить 32 битное слежение значения квадратурной дешифрации.

0

55

Опиши проще идею, на подобии: как организовать квадратурный энкодер на 32 разряда, используя только аппаратные возможности.
Ну и добавь, что у тебя получилось. Можно вначале рассказать, что конкретно не получается. Английский язык примитивный, нельзя пихать всё в кучу, такое фиг переведёшь, разложи на простые составляющие.

0

56

Пока проще программно, есть регистр CTRLFCLR или CTRLFSET, в нём бит №0 (DIR) указывает направление счёта, если равен нулю, то счёт в прямом направлении.
По переполнению таймера можно запустить прерывание и исполнить вычислительные действия.

Код:
On Tcc1_ovf Enc1:
Enable Tcc1_ovf

....
....
....

Enc1:
If Tcc1_ctrlfset.0 = 1 Then
   Incr En1
   Else
   If En1 > 0 Then Decr En1
End If
Return

0

57

В XMega нет возможности составлять цепочки таймеров тем самым наращивая разрядность? Или нет свободных таймеров?

0

58

Пётр написал(а):

В XMega нет возможности составлять цепочки таймеров тем самым наращивая разрядность? Или нет свободных таймеров?

Всё есть, но если надо передать не прибавление, а уменьшение - то я не знаю как.
Так-то всё без проблем:
Квадратурное событие - таймер1 - событие по переполнению таймера - таймер 2.
Но таймер 2 не будет уменьшаться и это всё портит, то-есть аппаратно смогу досчитать до 32 бит, а убавляется ко квадратуре будет только первый таймер, второму не передаётся информация, что то первый таймер уменьшился.

Отредактировано Ev3658 (2017-11-28 17:38:11)

0

59

Тогда это недоработка XMega. Не до конца их продумали. В таком случае нужно использовать прерывания.

0

60

Блин, метод по прерыванию переполнения таймера и определения направления счёта работает стабильно, но глючно, прерывания всё-же в нуле может быть очень много, может завалить МК и разрушить связь.
Вот, зацените работу кода, когда на контроллер приходит байт "100", он отсылает данные из которых последний байт это контрольная сумма:

Код:
Printbin #1 , En1
                Bitch = En1
                B = Low(tcc1_cnt)
                Bitch = Bitch + B
                Printbin #1 , B
                B = High(tcc1_cnt)
                Bitch = Bitch + B
                Printbin #1 , B
                Bitch = Bitch + En2
                Printbin #1 , En2
                B = Low(tcc0_cnt)
                Bitch = Bitch + B
                Printbin #1 , B
                B = High(tcc0_cnt)
                Bitch = Bitch + B
                Printbin #1 , B
                Printbin #1 , Bitch


На Purebasic принимаю данные и проверяю сразу, вот в работе на 115200:

0

Похожие темы


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » atXmega - Quadrature Decoder Channels