реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Подпрограмма обработки энкодера на ассемблере
Игoрь
сообщение Jan 13 2014, 18:38
Сообщение #16


Участник
*

Группа: Участник
Сообщений: 52
Регистрация: 15-05-13
Пользователь №: 76 836



я же не просил тыкать меня носом в поисковик. Тема предельно простая- есть код на ассемблере для обработки энкодера, которым вы готовы поделиться- поделитесь. Нет кода, нечего сказать полезного- проходите мимо, идите в другие темы тыкайте носом в статистику поисковика.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jan 13 2014, 18:45
Сообщение #17


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Вы представляете , а там есть код и не один. Ну ждите, дальше


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Игoрь
сообщение Jan 14 2014, 05:05
Сообщение #18


Участник
*

Группа: Участник
Сообщений: 52
Регистрация: 15-05-13
Пользователь №: 76 836



вы представляете, а я и до вашего совета искал, и встречал некоторые реализации на ассемблере. Но они меня не устроили своей громоздкостью, неочевидностью. Ваши советы были бы гораздо полезнее, если бы они выглядели в виде: "мне попалась хорошая реализация здесь: http:\\...". За такой ответ я бы сказал- СПАСИБО. А так я и без вас знаю, что в интернете флуда на слово энкодер по нескольким миллионам ссылок. Мне бы хотелось из всех миллионов оставить один вариант на фразу "хорошая реализация обработки энкодера для AVR на ассемблере". К сожалению такого мне пока не попалось.
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Jan 14 2014, 09:55
Сообщение #19


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Эта тема неоднократно обсуждалась на форуме. Вам лениво поискать ? А мне вот лениво копипастить...
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jan 14 2014, 10:11
Сообщение #20


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата
Но они меня не устроили своей громоздкостью, неочевидностью
А что Ва мешает , взять одну из , довести до ума и выложить под
Цитата
"хорошая реализация обработки энкодера для AVR на ассемблере".
Лень?


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Игoрь
сообщение Jan 14 2014, 11:09
Сообщение #21


Участник
*

Группа: Участник
Сообщений: 52
Регистрация: 15-05-13
Пользователь №: 76 836



Цитата(ILYAUL @ Jan 14 2014, 14:11) *
А что Ва мешает , взять одну из , довести до ума и выложить под
Лень?

мешает отсутствие времени, поэтому и попросил тех, кто это уже сделал, помочь мне. Ещё раз повторюсь- я не прошу тыкать меня в поиск и кому-то заниматься поиском вместо меня.

Цитата(rx3apf @ Jan 14 2014, 13:55) *
Эта тема неоднократно обсуждалась на форуме. Вам лениво поискать ? А мне вот лениво копипастить...

я никого не просил сообщать мне о том, кому чего лениво делать.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 14 2014, 11:37
Сообщение #22


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Опрашиваю периодически (часто) по таймеру состояние выводов энкодера. Для устранения дребезга проверяю состояние за два периода, и если оно совпадает, считаю состояние устойчивым.
Сравниваю новое состояние с предыдущим устойчивым (разность нахожу). Если разность:
0 - ничего не делаю
1 - добавляю 1 к счетчику энкодера
-1 - вычитаю 1 из счетчика энкодера
2 или -2 - ошибка (слишком быстро вращается), ничего не делаю.
Периодически (редко) пересылаю состояние изменившихся органов управления (в том числе, счетчики энкодеров) по последовательному порту тому, кому надо. :-)
После этого счетчик энкодера обнуляю.
Типа того. На PIC16 cool.gif На C.
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Jan 14 2014, 12:47
Сообщение #23


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Цитата(ViKo @ Jan 14 2014, 06:37) *
Опрашиваю периодически (часто) по таймеру состояние выводов энкодера. Для устранения дребезга проверяю состояние за два периода, и если оно совпадает, считаю состояние устойчивым.
Сравниваю новое состояние с предыдущим устойчивым (разность нахожу). Если разность:
0 - ничего не делаю
1 - добавляю 1 к счетчику энкодера
-1 - вычитаю 1 из счетчика энкодера
2 или -2 - ошибка (слишком быстро вращается), ничего не делаю.
Периодически (редко) пересылаю состояние изменившихся органов управления (в том числе, счетчики энкодеров) по последовательному порту тому, кому надо. :-)
После этого счетчик энкодера обнуляю.
Типа того. На PIC16 cool.gif На C.

Топик стартера алгоритм не интересует. Дайте ему конкретный код на ассемблере.
А то у него времени нет. Даже на поиск.


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
Navovvol
сообщение Jan 30 2014, 10:52
Сообщение #24


Частый гость
**

Группа: Участник
Сообщений: 105
Регистрация: 9-09-11
Пользователь №: 67 080



CODE

.def count_VERY_HIGHT = R22
.def count_HIGHT= R21
.def count_LOW = R20 //Перменная счётчик

.def temp = R16
.def NewState= R17 ///Сюда записываем новое состояние
///пинов на которых висит энкодер
.def OldState= R18 //Тут хранится состояние пинов
//предыдущего опроса
.def count_encoder = R23

ENCODER_RAM: .byte 6
; FLASH ======================================================
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////// ТАБЛИЦА ВЕКТОРОВ ПРЕРЫВАНИЙ /////////////////////////////////////
.CSEG
.org $0000 rjmp RESET ; Переход на обработку сброса
.org $0012 jmp TIM2_COMP ; Переход на обработку при выполнении условия сравнения таймера 2
.ORG INT_VECTORS_SIZE ; Конец таблицы прерываний

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////// иницилизация стека/////////////////////////
RESET: ldi r16,low(RAMend)
out SPL,r16
ldi r16,high(RAMend)
out SPH,r16
//
;ENCODER INIT
CLRB DDRE,3,R16 ;DDRE.3 = 0 датчик зенита на вход
CLRB DDRE,4,R16 ;DDRE.4 = 0 датчик зенита на вход
SETB PORTE,3,R16 ;PORTE.3 = 1 Pull-up
SETB PORTE,4,R16 ;PORTE.4 = 1 Pull-up
//
///////////////Инициализация Прерываний//////////////////////
;.......................................................................
.equ XTAL = 16000000
.equ baudrate =115200 /// в реале скорость 115200. т.к. бит удвоенной скорости=1
.equ bauddivider = XTAL/(8*baudrate)-1
.equ frequncy = 1000
.equ encoder_number = (XTAL/(frequncy))/64

outi TCCR2,0<<WGM00|0<<COM01|0<<COM00|1<<WGM01|0<<CS02|1<<CS01|1<<CS00
outi OCR2, encoder_number

//обработка прерывания таймера 2
TIM2_COMP:
PUSHF
PUSH ZL
PUSH ZH
PUSH R17
PUSH R18
PUSH R19
clr R16
clr R17
clr R18
LDS NewState,ENCODER_RAM
LDS OldState,ENCODER_RAM+1
LDS count_LOW,ENCODER_RAM+2
LDS count_HIGHT,ENCODER_RAM+3
LDS count_VERY_HIGHT,ENCODER_RAM+4
LDS count_encoder,ENCODER_RAM+5
;.............................................................
IN NewState,PINE ;Читаем порт к которому подключен энкодер
CBR NewState,0b11100111

LSR NewState
LSR NewState
LSR NewState

cpi OldState,0;OldState,0
brne Cpi1 //Если нет то проверяем другое условие
cpi NewState,2;NewState,2
brne Cpi11
rcall RightShift
;.............................................................
Cpi11:
cpi NewState,1;NewState,1
brne Cpi12
rcall LeftShift
;.............................................................
Cpi12:
mov OldState,NewState;OldState,NewState //То что было новым состоянием энкодера, стало старым...
rjmp EXIT_ENCODER


;.............................................................
Cpi1:
//2) При прошлом опросе Пин А=1 и Пин В=0 ?
cpi OldState,1;OldState,1
brne Cpi2 //Если нет то проверяем другое условие
cpi NewState,0;NewState,0 //
brne Cpi21
rcall RightShift
;.............................................................
Cpi21:
cpi NewState,3;NewState,3
brne Cpi22
rcall LeftShift
;.............................................................
Cpi22:
mov OldState,NewState;OldState,NewState //То что было новым состоянием энкодера, стало старым...
rjmp EXIT_ENCODER

;.............................................................
Cpi2:
//3 ) При прошлом опросе Пин В=1 и Пин А=0 ?
cpi OldState,2;OldState,2
brne Cpi3 //Если нет то проверяем другое условие
cpi NewState,3;NewState,3
brne Cpi31
rcall RightShift
;.............................................................
Cpi31:
cpi NewState,0;NewState,0
brne Cpi12
rcall LeftShift
;.............................................................
Cpi32:
mov OldState,NewState;OldState,NewState //То что было новым состоянием энкодера, стало старым...
rjmp EXIT_ENCODER

;.............................................................
Cpi3:
///4) При прошлом опросе Оба пина=1 ?
cpi OldState,3;OldState,3
brne Cpi4 //Если нет то выходим из процедуры сканирования
cpi NewState,1;NewState,1
brne Cpi41
rcall RightShift
;.............................................................
Cpi41:
cpi NewState,2;NewState,2
brne Cpi42
rcall LeftShift
;.............................................................
Cpi42:
mov OldState,NewState;OldState,NewState //То что было новым состоянием энкодера, стало старым...
;.............................................................
Cpi4:
rjmp EXIT_ENCODER

;.............................................................
RightShift:

clr count_encoder
STS count_Left,count_encoder
LDS count_encoder,count_Right
cpi count_encoder,4;count,4 //Состояние пинов сменилось 4 раза?
brne exitRS
clr count_encoder;count
STS count_Right,count_encoder
ldi R16,1
ADD count_LOW,R16
clr R16
ADC count_HIGHT,R16
ADC count_VERY_HIGHT,R16
rjmp exitRS2

exitRS:
inc count_encoder;count
STS count_Right,count_encoder
exitRS2:
RET
;.............................................................
LeftShift:

clr count_encoder
STS count_Right,count_encoder
LDS count_encoder,count_Left
cpi count_encoder,4;count,4 //Состояние пинов сменилось 4 раза?
brne exitLS
clr count_encoder;count
STS count_Left,count_encoder
LDI R16,1
SUB count_LOW,R16
clr R16
SBC count_HIGHT,R16
SBC count_VERY_HIGHT,R16

rjmp exitLS2
exitLS:
inc count_encoder;count
STS count_Left,count_encoder
exitLS2:

RET

;.............................................................
/// подпрограммы для энкодера
EXIT_ENCODER:
STS ENCODER_RAM,NewState
STS ENCODER_RAM+1,OldState
STS ENCODER_RAM+2,count_LOW
STS ENCODER_RAM+3,count_HIGHT
STS ENCODER_RAM+4,count_VERY_HIGHT
STS ENCODER_RAM+5,count_encoder
POP R19
POP R18
POP R17 ; Корректный выход из прерывания.
POP ZH
POP ZL
POPF
RETI

Идеальная программа для энкодера на АСМе. Разбирайтесь.
P.S. к сожалению, при копировании накрылась медным тазом табуляция.

Сообщение отредактировал Navovvol - Jan 30 2014, 10:57
Go to the top of the page
 
+Quote Post
Игoрь
сообщение Feb 2 2014, 05:28
Сообщение #25


Участник
*

Группа: Участник
Сообщений: 52
Регистрация: 15-05-13
Пользователь №: 76 836



спасибо. Именно такого ответа я и ожидал! sm.gif
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Feb 2 2014, 10:29
Сообщение #26


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(Navovvol @ Jan 30 2014, 14:52) *
CODE

.def temp = R16
.def NewState= R17 ///Сюда записываем новое состояние
///пинов на которых висит энкодер
....
.org $0000 rjmp RESET ; Переход на обработку сброса
.org $0012 jmp TIM2_COMP ; Переход на обработку при выполнении условия сравнения таймера 2
.ORG INT_VECTORS_SIZE ; Конец таблицы прерываний

... PUSH ZL
PUSH ZH
PUSH R17
PUSH R18
PUSH R19
clr R16
clr R17
clr R18
LDS NewState,ENCODER_RAM
LDS OldState,ENCODER_RAM+1
...

Идеальная программа...


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

до идеала Вам есть куда рости...это хорошо...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 3 2014, 09:20
Сообщение #27


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(ViKo @ Jan 14 2014, 14:37) *
Сравниваю новое состояние с предыдущим устойчивым (разность нахожу).

Забыл добавить одно важное действие. Прежде чем сравнивать с предыдущим состоянием, преобразую код Грэя (в котором выдают свое состояние энкодеры) в двоичный код. Заменяю младшие биты исключающим или старшего и младшего битов. Для 4-х энкодеров в одном байте делал так:
Код
  PanFix[0] = (PanFix[0] & 0b10101010) |
          ((PanFix[0] ^ PanFix[0] >> 1) & 0b01010101);
Go to the top of the page
 
+Quote Post
Maik-vs
сообщение Mar 20 2014, 03:55
Сообщение #28


Местный
***

Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101



Код так код.
Вот:
Код
;
;===============================================================================
biphali: ///////////  bi-phase  driver                                        
      /// calls from main in fast cycle                                    
      ///                                                                             
      ///          0      forward 1-0-2                                                 
      ///       1     2    backward 2-0-1                                    
      ///          3      so, incr/decr nodes shifted in space. Can be stored in bits 0,1 of biphase     
      ///               until 2->3 or 3->2 to remove this shift.                        
.equ CT_B1    = $80
.equ CT_B2    = $40

    ldi    tmp1,CT_B1 | CT_B2
    sbis    BIPORT-PIN,BIPHA    cbr    tmp1,CT_B2
    sbis    BIPORT-PIN,BIPHB    cbr    tmp1,CT_B1
    eor    tmp1,biphase        ; <1> = BaBb 0 0  0 0 0 0
    cpi    tmp1,CT_B2        brlo biret;/// return if B1B2 readed same as prev. saved

    eor    tmp1,biphase        ;  restore <1>
    lsr    biphase        lsr    biphase
    or    tmp1,biphase        cbr    tmp1,3
    mov    biphase,tmp1        ;  aabbcc00 phase history

    lds    tmp2,bico
    cpi    tmp1,$48        brne    bidro;  01-00-10 00    102 forward
    lds    tmp1,biforw        add    tmp2,tmp1    rjmp bdsa
bidro:    cpi    tmp1,$84        brne    biret;  10-00-01 00    201 backward
    lds    tmp1,biforw        sub    tmp2,tmp1    

bdsa:    sts    bico,tmp2

biret:    ret


biphali вызывается часто, чаще, чем крутится енкодер. Изменяет bico (байт).
Чаще, чем переполняется bico нужно вызывать подпрограмму которая это bico
прибавляет к счётчику (у меня 4-байтный) и обнуляет bico.

Сообщение отредактировал Maik-vs - Mar 20 2014, 04:00
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 14:25
Рейтинг@Mail.ru


Страница сгенерированна за 0.01483 секунд с 7
ELECTRONIX ©2004-2016