加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

RVMCU課堂「17」: 手把手教你玩轉(zhuǎn)RVSTAR—正交編碼器接口篇

2021/05/31
255
閱讀需 9 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

上期內(nèi)容我們介紹了定時器PWM輸出功能,本期內(nèi)容來介紹一下定時器的正交譯碼器功能(編碼器接口)。正交譯碼器是和正交編碼器外設(shè)配合使用的,可對編碼器輸入的脈沖進行計數(shù)進而實現(xiàn)速度測量,本期內(nèi)容我們通過一個使用旋轉(zhuǎn)編碼器的計數(shù)小實驗,來初步了解它的應(yīng)用方法。

系統(tǒng)環(huán)境

Windows 10-64bit

軟件平臺

NucleiStudio IDE 202102版

PlatformIO IDE

硬件需求

RV-STAR開發(fā)板

旋轉(zhuǎn)編碼器

正交編碼器

正交編碼器(Quadrature Encoder)是一種用于測量旋轉(zhuǎn)速度和方向的傳感器。常見的正交編碼器有兩個輸出信號:A信道和B信道。每個信道可以對運動進行測量并產(chǎn)生數(shù)字脈沖,這兩個脈沖的相位相差90度(因此稱為“正交”),這使得你可以根據(jù)它們判斷運動的方向,通過積分(累加)運算后,還可以用來測算距離。

上圖中,A和B分別連接到兩個傳感器單元上,黑白相間的圓環(huán)稱之為「柵格」。傳感器單元和柵格的實現(xiàn)方式有很多種,包括「反射式傳感器+反光率不同的柵格」「對射式傳感器+鏤空光柵」「霍爾傳感器+磁極圓環(huán)」「觸點+導(dǎo)軌」等。

本次實驗中,我們使用的是下圖所示的市面上常見的旋轉(zhuǎn)編碼器(數(shù)字電位器):

GD32VF103的正交譯碼器

正交譯碼器功能使用TIMERx_CH0和TIMERx_CH1引腳生成的CI0和CI1正交信號各自相互作用產(chǎn)生計數(shù)值。通過設(shè)置SMC=0x01、0x02或0x03來選擇是僅由CI0、僅由CI1、或者由CI0和CI1來決定定時器的計數(shù)方向。在每個方向選擇源的電平改變期間,DIR位是由硬件自動改變的。計數(shù)器計數(shù)方向改變的機制如下方的圖表所示。

正交譯碼器可以當(dāng)作一個帶有方向選擇的外部時鐘,這意味著計數(shù)器會在0和自動加載值之間連續(xù)地計數(shù)。因此,用戶必須在計數(shù)器開始計數(shù)前配置TIMERx_CAR寄存器。

實驗部分

首先需要參照如下的示意圖,對RV-STAR開發(fā)板和旋轉(zhuǎn)編碼器進行連線:

然后在集成開發(fā)環(huán)境中創(chuàng)建一個新工程,開始編寫代碼。

首先需要對定時器的編碼器接口進行配置,我們使用的是TIMER2的編碼器接口,對應(yīng)的是PA6和PA7引腳,首先要使能它們的外設(shè)時鐘和復(fù)用時鐘,然后配置為浮空輸入模式。

接著需要創(chuàng)建定時器初始化參數(shù)結(jié)構(gòu)體,對定時器的功能進行配置,其中需要注意的是要將結(jié)構(gòu)體參數(shù)的預(yù)分頻系數(shù)設(shè)為0,周期設(shè)為10000(即定時器的自動加載值,也可以設(shè)為其他值),然后需要將定時器的模式設(shè)置為TIMER_ENCODER_MODE2(編碼器模式,使用CI0和CI1計數(shù)),然后將定時器的計數(shù)值配置為5000(這樣讀取定時器計數(shù)的初值就是5000),最后使能TIMER2。

相關(guān)代碼實現(xiàn)如下:


 

void encoder_init()
{
    /* TIMER2_CH0 - PA6, TIMER2_CH1 - PA7 */
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_AF);
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);

    rcu_periph_clock_enable(RCU_TIMER2);
    timer_deinit(TIMER2);

    /* initialize TIMER init parameter struct */
    timer_parameter_struct timer_initpara;
    timer_struct_para_init(&timer_initpara);
    /* TIMER2 configuration */
    timer_initpara.prescaler = 0;
    timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection = TIMER_COUNTER_UP;
    timer_initpara.period = 10000; /* set auto-reload value */
    timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
    timer_init(TIMER2, &timer_initpara);

    /* select the encoder mode */
    timer_slave_mode_select(TIMER2, TIMER_ENCODER_MODE2);
    timer_counter_value_config(TIMER2, 5000); /* config the initial value */

    timer_enable(TIMER2);
}

本次實驗,我們通過串口的打印輸出來查看編碼器的計數(shù)值,因此在主程序中需要對串口進行初始化,然后在循環(huán)體中,每次讀取依次定時器的計數(shù)值,再打印輸出到串口。


 

int main()
{
    encoder_init();
    gd_com_init(GD32_COM0);

    int counter = 0;
    while (1) {
        counter = timer_counter_read(TIMER2);
        printf("Counter: %dn", counter);

        delay_1ms(500);
    }
}

代碼編寫完成后,進行編譯和上傳,然后打開串口終端(波特率115200),可以查看到在串口終端中輸出定時器的初值為5000:

然后順時針旋轉(zhuǎn)編碼器的旋鈕,觀察到計數(shù)值增加,并且每轉(zhuǎn)動一個單位計數(shù)值增加4,符合芯片數(shù)據(jù)手冊中的功能描述:

逆時針旋轉(zhuǎn),計數(shù)值減少:

“RVMCU課堂”專欄已在社區(qū)開通如需獲取實驗源碼或有實驗相關(guān)問題掃碼進入即可

更多實驗例程

盡在RVMCU社區(qū)

www.rvmcu.com

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

中國大陸首家專業(yè)RISC-V處理器內(nèi)核IP和解決方案公司,助力構(gòu)建RISC-V創(chuàng)新生態(tài),公司網(wǎng)址:https://www.nucleisys.com