• 正文
    • 一模塊來源
    • 二規(guī)格參數(shù)
    • 三移植過程
    • 四移植驗證
  • 相關推薦
申請入駐 產業(yè)圖譜

【CW32模塊使用】雙軸按鍵搖桿模塊:CW32F030C8T6開發(fā)板控制電機旋轉速度

02/20 08:39
1405
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

雙軸按鍵游戲搖桿模塊,采用 PS2游戲手柄上金屬按鍵搖桿電位器。模塊特設二路模擬輸出和一路數(shù)字輸出接口、輸出值分別對應(X、Y)雙軸偏移量、其類型為模擬量、按鍵表示用戶是否在Z軸上按下、其類型為數(shù)字開關量、用其可以輕松控制物體,在二維空間運動、因此可以通控制器編程、傳感器擴展板插接、完成具有創(chuàng)意性遙控互動作品。

模塊來源

模塊實物展示:

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

驅動電壓:3.3V~5V

控制方式:ADC+GPIO

以上信息見廠家資料文件

移植過程

我們的目標是將例程移植至CW32F030C8T6開發(fā)板上【能夠控制電機旋轉速度的功能】。首先要獲取資料,查看數(shù)據手冊應如何實現(xiàn)讀取數(shù)據,再移植至我們的工程。

3.1查看資料

輸出信號:模塊特設二路模擬輸出(VRX,VRY)和一路數(shù)字輸出接口(SW),二路模擬輸出值分別對應(X,Y)雙軸偏移量,其類型為模擬量;按鍵表示用戶是否在Z軸上按下,其類型為數(shù)字開關量。

十字搖桿為一個雙向的10K電阻器,隨著搖桿方向不同,抽頭的阻值隨著變化。本模塊如果使用5V供電,原始狀態(tài)下X,Y讀出電壓為2.5V左右,當隨箭頭方向按下,讀出電壓值減少,限小為0V。

3.2引腳選擇

VRX與VRY使用ADC功能。

想要使用ADC,需要確定使用的引腳是否有ADC外設功能。

當前只有AO引腳需要使用到ADC接口,所以DO引腳可以使用開發(fā)板上其他的GPIO。這里選擇使用PA1和PA2的附加ADC功能。使用ADC的第1道和2通道。

ADC功能引腳

模塊接線圖

3.3移植至工程

移植步驟中的導入.c和.h文件與【CW32模塊使用】DHT11溫濕度傳感器相同,只是將.c和.h文件更改為bsp_joystick.c與bsp_joystick.h。這里不再過多講述,移植完成后面修改相關代碼。

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

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


/** 硬件SPI */#define SPI_WAIT_TIMEOUT       ((uint16_t)0xFFFF)
/**  * @brief :SPI初始化(硬件)  * @param :無  * @note  :無  * @retval:無  */void drv_spi_init( void ){        GPIO_InitTypeDef GPIO_InitStruct1;             // GPIO初始化結構體        GPIO_InitTypeDef GPIO_InitStruct2;             // GPIO初始化結構體
        SPI_GPIO_RCC();                                // 使能GPIO時鐘        RCC_SPI_HARDWARE_ENABLE();                     // 使能SPI1時鐘
        // GPIO復用為SPI1        BSP_SPI_AF_SCK();        BSP_SPI_AF_MISO();        BSP_SPI_AF_MOSI();
        GPIO_InitStruct1.Pins = SPI_NSS_GPIO_PIN|                                                        SPI_CLK_GPIO_PIN|                                                        SPI_MOSI_GPIO_PIN;      // GPIO引腳        GPIO_InitStruct1.Mode = GPIO_MODE_OUTPUT_PP;    // 推挽輸出        GPIO_InitStruct1.Speed = GPIO_SPEED_HIGH;       // 輸出速度高        GPIO_Init(SPI_GPIO_PORT, &GPIO_InitStruct1);    // 初始化
        GPIO_InitStruct2.Pins = SPI_MISO_GPIO_PIN;      // GPIO引腳        GPIO_InitStruct2.Mode = GPIO_MODE_INPUT_PULLUP; // 上拉輸入        GPIO_Init(SPI_GPIO_PORT, &GPIO_InitStruct2);    // 初始化
        spi_set_nss_high();  // 片選拉高
        SPI_InitTypeDef  SPI_InitStructure; // SPI 初始化結構體
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;    // 雙線全雙工        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                         // 主機模式        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                     // 幀數(shù)據長度為8bit        SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                            // 時鐘空閑電平為低        SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                          // 第1個邊沿采樣        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                             // 片選信號由SSI寄存器控制        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;    // 波特率為PCLK的8分頻        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                    // 最高有效位 MSB 收發(fā)在前        SPI_InitStructure.SPI_Speed = SPI_Speed_Low;                          // 低速SPI
        SPI_Init(PORT_SPI, &SPI_InitStructure);   // 初始化        SPI_Cmd(PORT_SPI, ENABLE);   // 使能SPI1}
/**  * @brief :SPI收發(fā)一個字節(jié)  * @param :  * @TxByte: 發(fā)送的數(shù)據字節(jié)  * @note  :非堵塞式,一旦等待超時,函數(shù)會自動退出  * @retval:接收到的字節(jié)  */uint16_t drv_spi_read_write_byte( uint8_t TxByte ){        uint16_t l_Data = 0;        uint16_t l_WaitTime = 0;
    while(RESET == SPI_GetFlagStatus(PORT_SPI, SPI_FLAG_TXE))//等待發(fā)送緩沖區(qū)為空        {                if( SPI_WAIT_TIMEOUT == ++l_WaitTime )                {                        break;                        //如果等待超時則退出                }        }        l_WaitTime = SPI_WAIT_TIMEOUT / 2;                //重新設置接收等待時間(因為SPI的速度很快,正常情況下在發(fā)送完成之后會立即收到數(shù)據,等待時間不需要過長)        SPI_SendData(PORT_SPI, TxByte);//發(fā)送數(shù)據
    while(RESET == SPI_GetFlagStatus(PORT_SPI, SPI_FLAG_RXNE))//等待接收緩沖區(qū)非空        {                if( SPI_WAIT_TIMEOUT == ++l_WaitTime )                {                                break;                        //如果等待超時則退出                }        }    l_Data = SPI_ReceiveData(PORT_SPI);//讀取接收數(shù)據
        return l_Data;                //返回}
/**  * @brief :SPI收發(fā)字符串  * @param :  * @ReadBuffer: 接收數(shù)據緩沖區(qū)地址  * @WriteBuffer:發(fā)送字節(jié)緩沖區(qū)地址  * @Length:字節(jié)長度  * @note  :非堵塞式,一旦等待超時,函數(shù)會自動退出  * @retval:無  */void drv_spi_read_write_string( uint8_t* ReadBuffer, uint8_t* WriteBuffer, uint16_t Length ){    spi_set_nss_low( );//拉低片選        while( Length-- )        {                *ReadBuffer = drv_spi_read_write_byte( *WriteBuffer ); //收發(fā)數(shù)據                ReadBuffer++;                WriteBuffer++;                                //讀寫地址加1        }    spi_set_nss_high( );//拉高片選}

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

/* * Change Logs: * Date           Author       Notes * 2024-06-21     LCKFB-LP    first version */
#ifndef __DRV_SPI_H__#define __DRV_SPI_H__
#include "board.h"

//SPI引腳定義#define SPI_GPIO_RCC()           __RCC_GPIOA_CLK_ENABLE() // GPIO時鐘
#define SPI_GPIO_PORT            CW_GPIOA
#define SPI_CLK_GPIO_PIN         GPIO_PIN_5#define SPI_MISO_GPIO_PIN        GPIO_PIN_6#define SPI_MOSI_GPIO_PIN        GPIO_PIN_7#define SPI_NSS_GPIO_PIN         GPIO_PIN_4

#define spi_set_nss_high( )      GPIO_WritePin(SPI_GPIO_PORT, SPI_NSS_GPIO_PIN, GPIO_Pin_SET)   //片選置高#define spi_set_nss_low( )       GPIO_WritePin(SPI_GPIO_PORT, SPI_NSS_GPIO_PIN, GPIO_Pin_RESET) //片選置低


/******** 硬件SPI修改此次 ********/#define RCC_SPI_HARDWARE_ENABLE()         __RCC_SPI1_CLK_ENABLE()#define PORT_SPI                          CW_SPI1
//GPIO AF#define BSP_SPI_AF_SCK()                  PA05_AFx_SPI1SCK()#define BSP_SPI_AF_MISO()                 PA06_AFx_SPI1MISO()#define BSP_SPI_AF_MOSI()                 PA07_AFx_SPI1MOSI()

void drv_spi_init( void );uint16_t drv_spi_read_write_byte( uint8_t TxByte );void drv_spi_read_write_string( uint8_t* ReadBuffer, uint8_t* WriteBuffer, uint16_t Length );
#endif

移植驗證

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

/* * Change Logs: * Date           Author       Notes * 2024-06-25     LCKFB-LP    first version */#include "board.h"#include "stdio.h"#include "bsp_uart.h"#include "bsp_joystick.h"
int32_t main(void){    board_init();
    uart1_init(115200);
    ADC_Joystick_Init();
    printf("Demo Start.....rn");
    while(1)    {        if( Get_SW_state() == 0 )        {            printf("按鈕按下!!rn");        }
        printf("X = [%d]rn",Get_Joystick_Percentage_value(0));        printf("Y = [%d]rn",Get_Joystick_Percentage_value(1));        printf("n");
        delay_ms(200);    }}

移植現(xiàn)象:移動搖桿并且按下,輸出搖桿移動的數(shù)據。

模塊移植成功案例代碼:

鏈接:https://pan.baidu.com/s/1tubySHCtuFABDPQ1RjK40g?pwd=LCKF

提取碼:LCKF

相關推薦

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

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

B站