• 正文
    • 01模塊來源
    • 02 規(guī)格參數(shù)
    • 03移植過程
    • 04移植驗證
  • 推薦器件
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

【CW32模塊使用】EC11旋轉(zhuǎn)編碼器

2024/08/29
1768
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

旋轉(zhuǎn)編碼器是一種將旋轉(zhuǎn)位移轉(zhuǎn)換為一連串?dāng)?shù)字脈沖信號的旋轉(zhuǎn)式傳感器。這些脈沖用來控制角位移。讀數(shù)系統(tǒng)通常采用差分方式,即將兩個波形一樣但相位差為180°的不同信號進(jìn)行比較,以便提高輸出信號的質(zhì)量和穩(wěn)定性。讀數(shù)是在兩個信號的差別基礎(chǔ)上形成的,從而消除了干擾。

01模塊來源

資料下載鏈接:https://pan.baidu.com/s/18pp1KaT2V_llizWvdIXtKA?pwd=8889

資料提取碼:8889

02 規(guī)格參數(shù)

模塊的廠家資料下載請查看百度網(wǎng)盤鏈接

工作電壓:5V

工作電流:1MA

模塊尺寸:18 x 25 mm

旋轉(zhuǎn)角度: 360度

通信協(xié)議:相位差

管腳數(shù)量:5 Pin(2.54mm間距排針

03移植過程

我們的目標(biāo)是在立創(chuàng)·CW32F030C8T6開發(fā)板上能夠判斷旋轉(zhuǎn)方向、旋轉(zhuǎn)次數(shù)和是否按下的功能。首先要獲取資料,查看數(shù)據(jù)手冊應(yīng)如何實現(xiàn),再移植至我們的工程。

3.1查看資料

旋轉(zhuǎn)編碼器是通過兩個引腳的相位差,實現(xiàn)的旋轉(zhuǎn)方向判斷(以后的CLK引腳統(tǒng)一稱呼為A相,DT引腳為B相)

當(dāng)是順時針旋轉(zhuǎn)時,A相超前B相90度,即A相為下降沿時,B相為低電平;A相為上升沿時,B相為高電平

當(dāng)是逆時針旋轉(zhuǎn)時,B相超前A相90度,即A相為下降沿時,B相為高電平;A相為上升沿時,B相為低電平。

而EC11按旋轉(zhuǎn)的輸出動作可以分為兩種。

一種是轉(zhuǎn)兩格,A、B端輸出一個完整脈沖(轉(zhuǎn)一格就只是由低電平->高電平或由高電平->低電平);

一種就是轉(zhuǎn)一格,A、B對C端輸出一個完整脈沖。


轉(zhuǎn)一格半個脈沖


轉(zhuǎn)一格完整脈沖

因此我們只需檢測A相或者B相有發(fā)生高低電平跳變時,就判斷另一相狀態(tài),來決定旋轉(zhuǎn)方向。根據(jù)以下真值表,可以發(fā)現(xiàn):

當(dāng)兩相同時為上升沿或者同時為下降沿時,則為順時針;

當(dāng)兩相不同時為上升沿或者不同時為下降沿時,則為逆時針;

下B相 右A相 上升沿 下降沿
上升沿 順時針 逆時針
下降沿 逆時針 順時針

旋轉(zhuǎn)編碼器是機(jī)械結(jié)構(gòu)的,是機(jī)械結(jié)構(gòu)就避免不了在旋轉(zhuǎn)或者按下時有抖動,這里采用定時器每隔10ms掃描一次編碼器是否有動作,實現(xiàn)10ms內(nèi)的消抖。

在中斷服務(wù)函數(shù)中,根據(jù)真值表確定旋轉(zhuǎn)的方向。

3.2引腳選擇

該模塊有5個引腳,具體引腳連接見 表 各引腳連接。

3.3移植至工程

打開自己的工程。(這里工程參考見入門手冊工程模板)

移植步驟中的導(dǎo)入.c和.h文件與第二章的第1小節(jié)【DHT11溫濕度傳感器】相同,只是將.c和.h文件更改為ec11.c與ec11.h。這里不再過多講述,移植完成后面修改相關(guān)代碼。

在文件ec11.c中,編寫如下代碼。

/* * Change Logs: * Date           Author       Notes * 2024-06-19     LCKFB-LP    first version */
#include "ec11.h"#include "stdio.h"

/****************************************************************** * 函 數(shù) 名 稱:Encoder_GPIO_Init * 函 數(shù) 說 明:旋轉(zhuǎn)編碼器引腳初始化 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作       者:LC * 備       注:使用定時器每10Ms掃描一次是否有旋轉(zhuǎn),即通過定時器進(jìn)行消抖******************************************************************/void Encoder_GPIO_Init(void){    GPIO_InitTypeDef GPIO_InitStruct;                     // GPIO初始化結(jié)構(gòu)體    BTIM_TimeBaseInitTypeDef BTIM_TimeBaseInitStruct;     // 定時器初始化結(jié)構(gòu)體
    RCC_GPIO_ENABLE();        // 使能GPIO時鐘    BTIM_RCC_ENABLE();        // 使能BTIM時鐘
    // 禁止中斷,以安全地配置NVIC    __disable_irq();
    // 開啟BTIM1中斷,并關(guān)聯(lián)到NVIC    NVIC_EnableIRQ(BSP_TIMER_IRQ);
    // 允許中斷,恢復(fù)中斷狀態(tài)    __enable_irq();
    GPIO_InitStruct.Pins =  GPIO_ENCODER_SW|          // GPIO引腳                            GPIO_ENCODER_LCK|                            GPIO_ENCODER_DT;    GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP;    // 上拉輸入    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;          // 輸出速度高    GPIO_Init(PORT_GPIO, &GPIO_InitStruct);           // 初始化

    // 配置定時器模式、周期和預(yù)分頻器    BTIM_TimeBaseInitStruct.BTIM_Mode = BTIM_Mode_TIMER;       // 設(shè)置為定時器模式    BTIM_TimeBaseInitStruct.BTIM_Period = 625 - 1;             // 設(shè)置周期,使得定時器每10ms產(chǎn)生一次溢出中斷    BTIM_TimeBaseInitStruct.BTIM_Prescaler = BTIM_PRS_DIV1024; // 預(yù)分頻器設(shè)置為1024,以降低時鐘頻
    // 使用上述配置初始化定時器BTIM1    BTIM_TimeBaseInit(BSP_TIMER, &BTIM_TimeBaseInitStruct);
    // 使能BTIM1的溢出中斷    BTIM_ITConfig(BSP_TIMER, BTIM_IT_OV, ENABLE);
    // 啟動定時器BTIM1    BTIM_Cmd(BSP_TIMER, ENABLE);}

/****************************************************************** * 函 數(shù) 名 稱:Encoder_Scanf * 函 數(shù) 說 明:判斷旋轉(zhuǎn)編碼器是否有往哪一個方向旋轉(zhuǎn) * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:1=正轉(zhuǎn) 2=反轉(zhuǎn) * 作       者:LC * 備       注:哪一邊正轉(zhuǎn)哪一邊反轉(zhuǎn)不需要太在意,你說的算******************************************************************/char Encoder_Scanf(void){    static GPIO_PinState EC11_CLK_Last= GPIO_Pin_RESET; //EC11的LCK引腳上一次的狀態(tài)(A相)    static GPIO_PinState EC11_DT_Last = GPIO_Pin_RESET; //EC11的DT引腳上一次的狀態(tài)(B相)    char ScanResult = 0;    //當(dāng)A發(fā)生跳變時采集B當(dāng)前的狀態(tài),并將B與上一次的狀態(tài)進(jìn)行對比。    if(GET_CLK_STATE !=EC11_CLK_Last)    {           //若A 0->1 時,B 1->0 正轉(zhuǎn);若A 1->0 時,B 0->1 正轉(zhuǎn);                //若A 0->1 時,B 0->1 反轉(zhuǎn);若A 1->0 時,B 1->0 反轉(zhuǎn)        if(GET_CLK_STATE == 1)     //EC11_A和上一次狀態(tài)相比,為上升沿        {            //EC11_B和上一次狀態(tài)相比,為下降沿            if((EC11_DT_Last == 1)&&(GET_DT_STATE == 0))                ScanResult = 1;  //正轉(zhuǎn)             //EC11_B和上一次狀態(tài)相比,為上升沿            if((EC11_DT_Last == 0)&&(GET_DT_STATE == 1))                ScanResult = 2; //反轉(zhuǎn)
            //>>>>>>>>>>>>>>>>下面為正轉(zhuǎn)一次再反轉(zhuǎn)或反轉(zhuǎn)一次再正轉(zhuǎn)處理<<<<<<<<<<<<<<<<//            //A上升沿時,采集的B不變且為0            if((EC11_DT_Last == GET_DT_STATE)&&(GET_DT_STATE == 0))                ScanResult = 1;                                 //正轉(zhuǎn)             //A上升沿時,采集的B不變且為1            if((EC11_DT_Last == GET_DT_STATE)&&(GET_DT_STATE == 1))                ScanResult = 2;                                //反轉(zhuǎn)        }        else  //EC11_A和上一次狀態(tài)相比,為下降沿        {            //EC11_B和上一次狀態(tài)相比,為下降沿            if((EC11_DT_Last == 1)&&(GET_DT_STATE == 0))                ScanResult = 2;                        //反轉(zhuǎn)             //EC11_B和上一次狀態(tài)相比,為上升沿            if((EC11_DT_Last == 0)&&(GET_DT_STATE == 1))                ScanResult = 1;                         //正轉(zhuǎn)
            //>>>>>>>>>>>>>>>>下面為正轉(zhuǎn)一次再反轉(zhuǎn)或反轉(zhuǎn)一次再正轉(zhuǎn)處理<<<<<<<<<<<<<<<<//            //A上升沿時,采集的B不變且為0            if((EC11_DT_Last == GET_DT_STATE)&&(GET_DT_STATE == 0))                ScanResult = 2;                                //反轉(zhuǎn)            //A上升沿時,采集的B不變且為1            if((EC11_DT_Last == GET_DT_STATE)&&(GET_DT_STATE == 1))                ScanResult = 1;                                 //正轉(zhuǎn)        }        EC11_CLK_Last = GET_CLK_STATE;   //更新編碼器上一個狀態(tài)暫存變量        EC11_DT_Last = GET_DT_STATE;     //更新編碼器上一個狀態(tài)暫存變量        return ScanResult;               //返回值的取值:   0:無動作; 1:正轉(zhuǎn);  2:反轉(zhuǎn);    }    return 0;}


/****************************************************************** * 函 數(shù) 名 稱:Encoder_Sw_Down * 函 數(shù) 說 明:判斷編碼器是否被按下 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:0=沒有被按下  1=被按下 * 作       者:LC * 備       注:請注意消抖******************************************************************/unsigned char Encoder_Sw_Down(void){    //沒有按下    if( GET_SW_STATE == GPIO_Pin_SET )    {        delay_ms(100);//消抖        return 0;    }    else//按下    {        delay_ms(100);//消抖//        printf("downrn");        return 1;    }}
/****************************************************************** * 函 數(shù) 名 稱:Encoder_Rotation_left * 函 數(shù) 說 明:左旋轉(zhuǎn)服務(wù)函數(shù)。當(dāng)編碼器左轉(zhuǎn)時,需要執(zhí)行的操作 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:向左旋轉(zhuǎn)次數(shù) * 作       者:LC * 備       注:無******************************************************************/int Encoder_Rotation_left(void){    static int left_num = 0;//左轉(zhuǎn)次數(shù)    left_num++;    /*  你的代碼寫在此處  */    printf("left num = %drn",left_num);
    /*  你的代碼寫在此處  */    return left_num;}
/****************************************************************** * 函 數(shù) 名 稱:Encoder_Rotation_left * 函 數(shù) 說 明:右旋轉(zhuǎn)服務(wù)函數(shù)。當(dāng)編碼器右轉(zhuǎn)時,需要執(zhí)行的操作 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:向右旋轉(zhuǎn)次數(shù) * 作       者:LC * 備       注:無******************************************************************/int Encoder_Rotation_right(void){    static int right_num = 0;//右轉(zhuǎn)次數(shù)    right_num++;    /*  你的代碼寫在此處  */
    printf("right num = %drn",right_num);    /*  你的代碼寫在此處  */
    return right_num;}

/************************************************函數(shù)名稱 : BSP_TIMER_IRQHandler功    能 : 基本定時器中斷服務(wù)函數(shù)參    數(shù) : 無返 回 值 : 無作    者 : LC*************************************************/void BSP_TIMER_IRQHANDLER(void){        static char dat = 0;        if(BTIM_GetITStatus(BSP_TIMER, BTIM_IT_OV) == SET)        {                dat = Encoder_Scanf();//掃描編碼器是否扭動                if( dat != 0 )//如果有轉(zhuǎn)動                {                        if( dat == 2 )                        {                                Encoder_Rotation_left();                        }                        else                        {                                Encoder_Rotation_right();                        }
                }        }        BTIM_ClearITPendingBit(BSP_TIMER, BTIM_IT_OV);}

 

在文件ec11.h中,編寫如下代碼。

/* * Change Logs: * Date           Author       Notes * 2024-06-19     LCKFB-LP    first version */#ifndef _BSP_ENCODER_H_#define _BSP_ENCODER_H_
#include "board.h"
#define RCC_GPIO_ENABLE()   __RCC_GPIOA_CLK_ENABLE()
#define PORT_GPIO           CW_GPIOA
//SW引腳#define GPIO_ENCODER_SW     GPIO_PIN_7
//CLK引腳#define GPIO_ENCODER_LCK    GPIO_PIN_6
//DT引腳#define GPIO_ENCODER_DT     GPIO_PIN_4
//獲取CLK引腳的狀態(tài)#define GET_CLK_STATE   GPIO_ReadPin(PORT_GPIO, GPIO_ENCODER_LCK)//獲取DT引腳的狀態(tài)#define GET_DT_STATE    GPIO_ReadPin(PORT_GPIO, GPIO_ENCODER_DT)//獲取SW引腳的狀態(tài)#define GET_SW_STATE    GPIO_ReadPin(PORT_GPIO, GPIO_ENCODER_SW)
//定時器掃描#define BTIM_RCC_ENABLE()            __RCC_BTIM_CLK_ENABLE() // 使能定時器時鐘#define BSP_TIMER                    CW_BTIM1                // 定時器#define BSP_TIMER_IRQ                BTIM1_IRQn              // 定時器中斷#define BSP_TIMER_IRQHANDLER         BTIM1_IRQHandler        // 定時器中斷服務(wù)函數(shù)

void Encoder_GPIO_Init(void);//旋轉(zhuǎn)編碼器初始化unsigned char Encoder_Sw_Down(void);//編碼器是否按下int Encoder_Rotation_left(void);//左轉(zhuǎn)服務(wù)函數(shù)int Encoder_Rotation_right(void);//右轉(zhuǎn)服務(wù)函數(shù)

#endif

04移植驗證

在自己工程中的main主函數(shù)中,編寫如下。

/* * Change Logs: * Date           Author       Notes * 2024-06-19     LCKFB-LP    first version */#include "board.h"#include "stdio.h"#include "bsp_uart.h"#include "ec11.h"
int32_t main(void){    board_init();        // 開發(fā)板初始化
    uart1_init(115200);  // 串口1波特率115200
    Encoder_GPIO_Init();    printf("encoder demo startrn");    while(1)    {        if( Encoder_Sw_Down() == 1 )//旋轉(zhuǎn)編碼器被按下        {            printf("Encoder downrn");        }    }}

移植現(xiàn)象:向右旋轉(zhuǎn)10次,向左旋轉(zhuǎn)10次,按下一次。

模塊移植成功案例代碼:

鏈接:https://pan.baidu.com/s/18_4-IfR_pzyy1QvyQE7XkQ?pwd=LCKF

提取碼:LCKF

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險等級 參考價格 更多信息
TISP4350M3BJR-S 1 Bourns Inc Silicon Surge Protector, 350V V(BO) Max, 32A, DO-214AA, SMBJ, 2 PIN
$0.9 查看
BTB12-600BWRG 1 New Jersey Semiconductor Products, Inc. Snubberless TRIAC
$0.99 查看
BAV99S,135 1 Nexperia BAV99S - High-speed switching diode@en-us TSSOP 6-Pin

ECAD模型

下載ECAD模型
$0.05 查看

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

以開放、共享、互助為理念,致力于構(gòu)建武漢芯源半導(dǎo)體CW32系列MCU生態(tài)社區(qū)。無論是嵌入式MCU小自還是想要攻破技術(shù)難題的工程師,亦或是需求解決方案的產(chǎn)品經(jīng)理都可在CW32生態(tài)社區(qū)汲取營養(yǎng)、共同成長。

B站