Re: [問題] 請教關於『旋轉編碼器』的數值讀取問題
小弟我先前在此提出問題後,
得到許多前輩的協助,在此先拜謝!
因為這問題後來解決了,所以我想就來此回報,並且把我的學習心得和解法,
來分享一下!若有相關需求的朋友也能少走點冤枉路...
我當時問題是:旋轉編碼器,輸出的脈衝數量『太多』,
但無法更換元件(不管是編碼器或處理器),也不能動原有程式。
本來我想要『除頻』--把原本的脈衝數量按照比例減少,
結果,速度確實降低,但『旋轉方向』卻錯亂。
旋轉編碼器的原理是--輸出A,B兩條線,旋轉時,會有固定的脈波出現,
根據方向不同,會有不同的相位差。(如下)
正轉時(A線脈波比B線提前半個相位):
A ___---___---___---___
B _____---___---___---___
反轉時(B線比A線提前):
A _____---___---___---___
B ___---___---___---___
我的想法是--脈衝太多,那就兩條線同時除頻,拿TTL IC去做,
不就會同時減少脈波數量?
有問題的原因到底何在呢?
我思考了好久,直到那天看到一群小朋友在玩遊戲,突然之間恍然大悟
『一二三~~~木頭人!!』
對啦,我這樣的電路設計,就是在跟脈波玩木頭人!
我讓MCU當鬼,而編碼器則是扮演木頭人!
然後,我試圖用除頻器遮住鬼的眼睛.....只讓他隔一段時間回頭看一眼...
但我忽略了...木頭人在鬼看不到的時候不管做了什麼動作,都會被忽視!
MCU只能得知最後脈波的『總數量』變化,但其中到底誰先誰後,之間超前落後關係,
它一概不知道......所以,方向就無法正確的得知
(也許先往左半圈,再往右一圈,而MCU最後只知道往右移動了半圈...)
在找資料以及板友協助之下,我重新思考解決方式---
首先要分析這兩線訊號的行為模式,其實很簡單,就是--
『當A訊號邊緣觸發時,判斷B訊號是0或1,就可判定方向』
既然有這麼簡單的邏輯,那我就選擇外加一個單晶片,負責處理。
選用的還是這顆『單晶片之中的皮卡丘』..89C51
(就是...二十年不進化,經驗值暴表,什麼招式都生得出來)
簡單說,就是用A線輸入INT0外部中斷,判斷邊緣觸發,
進入ISR再去判斷B線電位高低。
當進入中斷達到一定次數時,輸出產生一個轉動的相位訊號,給原本的MCU輸入,就完成此功能了。
而要降低的比例,只要決定『進入中斷多少次產生一個輸出』就可以了。
以下為我的程式碼和註解,給需要的朋友參考啦......
版權沒有,歡迎使用。
再次感謝各位協助我的朋友們!
輸入為P3.1和P3.2(接編碼器A/B線),輸出為P2.0和P2.1(接原本MCU的輸入)
--
COUNT EQU 30 ;輸入脈波多少次才輸出一次
;正轉次數計數為為R3,反轉次數為R4
org 0h
JMP LOP ;跳到主程式
ORG 03H ;中斷位址
JMP INT0_HANDLING ;跳到中斷ISR
LOP: ;主程式
clr P2.0 ;輸出接點設定
clr P2.1
SETB EA ;打開中斷總開關
SETB EX0 ;致能 INT0 (Pin12,3.2)
SETB IT0 ; 負緣觸發
setb P3.2 ;輸入中斷接腳設定 (A接點)
setb P3.1 ;輸入非中斷接腳設定 (B接點)
ajmp LOP
INT0_HANDLING: ;中斷ISR
CLR EA ;關掉中斷
JB P3.1,FR ; 如果B接點高電位,判斷為正轉
;以下為反轉時動作
mov R3,#COUNT ;偵測到反轉,把正轉count重置
DJNZ R4,BACK ;如果還沒觸發足夠次數,不動作
mov R4,#COUNT ;觸發次數到達,重置count
setb P2.1 ; 先拉高P2.1
ACALL DLY1 ;等待
setb P2.0 ; 再拉高P2.0
ACALL DLY1 ;等待
CLR P2.1 ;先降低P2.1
ACALL DLY1 ;等待
CLR P2.0;再降低P2.0
RETI
FR: ;正轉時的動作
mov R4,#COUNT ;偵測到正轉,把反轉count重置
DJNZ R3,BACK ;如果還沒觸發足夠次數,不動作
mov R3,#COUNT ;觸發次數到達,重置count
setb P2.0 ; 先拉高P2.0
ACALL DLY1 ;等待
setb P2.1 ; 再拉高P2.1
ACALL DLY1 ;等待
CLR P2.0 ;先降低P2.0
ACALL DLY1 ;等待
CLR P2.1;再降低P2.1
BACK: RETI ;折返回呼叫中斷副程式的地方
DLY1: ;延時40m秒副程式
MOV R6,#100
DL1: MOV R7,#200
DJNZ R7,$
DJNZ R6,DL1
RET
end
--
/ ╲︵ 笑年A,我教你
∕ ╮ ﹨ ﹨﹨ 奶子不是用來看的,是拿來摸的
∕ ノ╮ ╱∕∕ \ \ \ ︵
∕ ∕ \/ / / ╭ / ︵ ∕ /\ (( ) (-w- )
/ ∕﹨ /﹨﹨﹨ \ \ノ\/ / ノ ∕ ︶ ̄ /﹀(掰)>
﹨ ﹨ ﹨﹨ ﹀ ∕ ﹨ `﹀ ∕ / \
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 210.202.48.60
推
05/30 15:33, , 1F
05/30 15:33, 1F
→
05/30 15:35, , 2F
05/30 15:35, 2F
→
05/30 15:36, , 3F
05/30 15:36, 3F
→
05/30 15:48, , 4F
05/30 15:48, 4F
→
05/30 15:48, , 5F
05/30 15:48, 5F
→
05/30 15:58, , 6F
05/30 15:58, 6F
→
05/30 15:59, , 7F
05/30 15:59, 7F
謝謝前輩的指導!
我稍微修改了一下code,已經把正反轉的計算暫存器分開,
這樣才能確實做到『連續輸入相同方向』才有動作
※ 編輯: lcabc 來自: 210.202.48.60 (05/30 16:09)
推
11/28 11:20, , 8F
11/28 11:20, 8F
討論串 (同標題文章)
完整討論串 (本文為第 2 之 2 篇):