AVR单片机教程——旋转编码器
本文隸屬于AVR單片機(jī)教程系列。
?
好久沒寫這個(gè)系列了。今天講講旋轉(zhuǎn)編碼器。
旋轉(zhuǎn)編碼器好像不是單片機(jī)玩家很常用的器件,但是我們的開發(fā)板上有,原因如下:
旋轉(zhuǎn)編碼器挺好用的。電位器能旋轉(zhuǎn)的角度有限,旋轉(zhuǎn)編碼器可以無限圈旋轉(zhuǎn);旋轉(zhuǎn)時(shí)不連續(xù),有卡點(diǎn),適合對(duì)應(yīng)離散數(shù)據(jù)。
開發(fā)板上選用的旋轉(zhuǎn)編碼器,使用起來簡單、方便。
本來旁邊的電位器(旋鈕,以后會(huì)講)一枝獨(dú)秀,挺孤單的,我就配一個(gè)高度大致相同的旋轉(zhuǎn)編碼器陪伴它。
今天我想寫旋轉(zhuǎn)編碼器,于是在網(wǎng)絡(luò)上搜索了一下,相關(guān)資料很少。最基本地,旋轉(zhuǎn)編碼器的作用是將角位移、角速度等機(jī)械量轉(zhuǎn)換為電信號(hào)。本文不求成為旋轉(zhuǎn)編碼器的百科全書,但會(huì)把 觸點(diǎn)電刷式 增量式 旋轉(zhuǎn)編碼器的原理講清楚。這里出現(xiàn)了兩個(gè)定語,是對(duì)類別的限定;關(guān)于旋轉(zhuǎn)編碼器的分類,請(qǐng)自行百度。
開發(fā)板上的旋轉(zhuǎn)編碼器是從淘寶買的,淘寶商家提供了資料,這是本講的主題。為避免廣告嫌疑,我不能放鏈接上來,所以我就把它轉(zhuǎn)換成圖片放在文章里(請(qǐng)?jiān)谛马撁嬷胁榭矗?/p>
我們從旋轉(zhuǎn)編碼器的原理開始。旋轉(zhuǎn)編碼器的內(nèi)部是觸點(diǎn)與電刷,可以看作按鍵:當(dāng)兩者接觸時(shí),開關(guān)閉合;反之?dāng)嚅_。實(shí)際上它們的本質(zhì)是一樣的。在旋轉(zhuǎn)時(shí),按鍵會(huì)周期性地閉合、斷開;如果一端接地,另一端接上拉電阻,就會(huì)有周期性高、低電平的脈沖信號(hào)產(chǎn)生。我們使用的旋轉(zhuǎn)編碼器每轉(zhuǎn)過一圈會(huì)輸出24個(gè)脈沖。
通過對(duì)脈沖進(jìn)行計(jì)數(shù),可以知道編碼器轉(zhuǎn)過的角度。如果不管方向,測(cè)量角度或角加速度等,用一個(gè)輸出就夠了。但是如果考慮方向,無論是順時(shí)針還是逆時(shí)針轉(zhuǎn)動(dòng),電平都是“高低高低高……”。為了獲得方向的信息,需要使用兩個(gè)輸出,它們的相位相差90°,如圖所示:
A和B是兩個(gè)輸出端,C端接地。當(dāng)程序檢測(cè)到A端由高電平變?yōu)榈碗娖綍r(shí)(方法在按鍵那里講過了),如果檢測(cè)到B端是高電平(這就更簡單了),那就是順時(shí)針旋轉(zhuǎn);如果是低電平,那就是逆時(shí)針旋轉(zhuǎn)。實(shí)際上不一定要檢測(cè)A端的下降沿,只要按照這張圖來,怎么都對(duì)。
庫函數(shù)使用的檢測(cè)方法是:A、B端由低低變?yōu)楦叩蜁r(shí),判為順時(shí)針轉(zhuǎn)過一格;由低低變?yōu)榈透邥r(shí),判為逆時(shí)針轉(zhuǎn)過一格。這不是最好的方法(你可以想一下怎樣改進(jìn),但是不要低估它的難度),但從實(shí)際使用上來看,只要用戶不故意在兩個(gè)卡點(diǎn)之間扭來扭去,這種方法是可以勝任的。
我們寫一個(gè)用旋轉(zhuǎn)編碼器控制數(shù)碼管顯示數(shù)字的程序,也可以理解為對(duì)旋轉(zhuǎn)編碼器進(jìn)行計(jì)數(shù)并用數(shù)碼管顯示。旋轉(zhuǎn)編碼器A和B端分別連接端口4和5,數(shù)碼管連接6和7。程序的思路是:每隔一毫秒調(diào)用rotary_rotated(它和button_pressed函數(shù)類似——如果你還記得的話)檢測(cè)編碼器是否被轉(zhuǎn)動(dòng)以及轉(zhuǎn)動(dòng)的方向,并根據(jù)方向?qū)τ?jì)數(shù)器變量num進(jìn)行增減。(為什么讓num為uint8_t類型?)為了凸顯旋轉(zhuǎn)編碼器的主題,數(shù)碼管就用segment_auto來解決了。
#include <ee1/delay.h>
#include <ee1/rotary.h>
#include <ee1/segment.h>
int main()
{
rotary_init(PIN_4, PIN_5);
segment_init(PIN_6, PIN_7);
segment_auto();
uint8_t num = 0;
while (1)
{
switch (rotary_rotated())
{
case ROTARY_CW:
++num;
break;
case ROTARY_ACW:
--num;
break;
default:
break;
}
segment_hex(num);
delay(1);
}
}
注意相鄰卡點(diǎn)之間擠了4個(gè)AB端口的狀態(tài),因此延時(shí)不能過長。你可以試試更長的間隔。
作業(yè):對(duì)于旋轉(zhuǎn)編碼器,直接檢測(cè)IO口電平;對(duì)于數(shù)碼管,使用“原始”的動(dòng)態(tài)掃描,即不要用segment_auto();重寫樣例。(提示:你可以分別完成兩個(gè)要求,然后合并。)
總結(jié)
以上是生活随笔為你收集整理的AVR单片机教程——旋转编码器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android模拟器,ADB命令
- 下一篇: 相宜本草适合什么年龄(相宜本草护肤品怎么