|
Подпрограмма обработки энкодера на ассемблере |
|
|
|
Jan 13 2014, 18:38
|
Участник

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

|
я же не просил тыкать меня носом в поисковик. Тема предельно простая- есть код на ассемблере для обработки энкодера, которым вы готовы поделиться- поделитесь. Нет кода, нечего сказать полезного- проходите мимо, идите в другие темы тыкайте носом в статистику поисковика.
|
|
|
|
|
Jan 14 2014, 05:05
|
Участник

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

|
вы представляете, а я и до вашего совета искал, и встречал некоторые реализации на ассемблере. Но они меня не устроили своей громоздкостью, неочевидностью. Ваши советы были бы гораздо полезнее, если бы они выглядели в виде: "мне попалась хорошая реализация здесь: http:\\...". За такой ответ я бы сказал- СПАСИБО. А так я и без вас знаю, что в интернете флуда на слово энкодер по нескольким миллионам ссылок. Мне бы хотелось из всех миллионов оставить один вариант на фразу "хорошая реализация обработки энкодера для AVR на ассемблере". К сожалению такого мне пока не попалось.
|
|
|
|
|
Jan 14 2014, 10:11
|

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

|
Цитата Но они меня не устроили своей громоздкостью, неочевидностью А что Ва мешает , взять одну из , довести до ума и выложить под Цитата "хорошая реализация обработки энкодера для AVR на ассемблере". Лень?
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Jan 14 2014, 11:09
|
Участник

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

|
Цитата(ILYAUL @ Jan 14 2014, 14:11)  А что Ва мешает , взять одну из , довести до ума и выложить под Лень? мешает отсутствие времени, поэтому и попросил тех, кто это уже сделал, помочь мне. Ещё раз повторюсь- я не прошу тыкать меня в поиск и кому-то заниматься поиском вместо меня. Цитата(rx3apf @ Jan 14 2014, 13:55)  Эта тема неоднократно обсуждалась на форуме. Вам лениво поискать ? А мне вот лениво копипастить... я никого не просил сообщать мне о том, кому чего лениво делать.
|
|
|
|
|
Jan 14 2014, 11:37
|

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

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

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

|
Цитата(ViKo @ Jan 14 2014, 06:37)  Опрашиваю периодически (часто) по таймеру состояние выводов энкодера. Для устранения дребезга проверяю состояние за два периода, и если оно совпадает, считаю состояние устойчивым. Сравниваю новое состояние с предыдущим устойчивым (разность нахожу). Если разность: 0 - ничего не делаю 1 - добавляю 1 к счетчику энкодера -1 - вычитаю 1 из счетчика энкодера 2 или -2 - ошибка (слишком быстро вращается), ничего не делаю. Периодически (редко) пересылаю состояние изменившихся органов управления (в том числе, счетчики энкодеров) по последовательному порту тому, кому надо. :-) После этого счетчик энкодера обнуляю. Типа того. На PIC16  На C. Топик стартера алгоритм не интересует. Дайте ему конкретный код на ассемблере. А то у него времени нет. Даже на поиск.
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Jan 30 2014, 10:52
|
Частый гость
 
Группа: Участник
Сообщений: 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
|
|
|
|
|
Feb 2 2014, 10:29
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 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 ...
Идеальная программа... при указании фиксированного смещения орг - лучше использовать константы из деф файла для конкретного мк. сохраняете и очищаете регистры, хотя дали им символические имена и потом эти имена и юзаете... ну и т.д.. до идеала Вам есть куда рости...это хорошо...
|
|
|
|
|
Mar 20 2014, 03:55
|
Местный
  
Группа: Участник
Сообщений: 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
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|