0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【CW32模块使用】双轴按键摇杆模块

CW32生态社区 来源:CW32生态社区 作者:CW32生态社区 2025-03-29 17:23 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

双轴按键游戏摇杆模块,采用 PS2游戏手柄上金属按键摇杆电位器。模块特设二路模拟输出和一路数字输出接口、输出值分别对应(X、Y)双轴偏移量、其类型为模拟量、按键表示用户是否在Z轴上按下、其类型为数字开关量、用其可以轻松控制物体,在二维空间运动、因此可以通控制器编程传感器扩展板插接、完成具有创意性遥控互动作品。

一、模块来源

模块实物展示:

wKgZPGflMoWASaIXAAAZ8BIZGZw925.jpg

二、规格参数

驱动电压:3.3V~5V

控制方式:ADC+GPIO

以上信息见厂家资料文件

三、移植过程

我们的目标是将例程移植至CW32F030C8T6开发板上【能够控制电机旋转速度的功能】。首先要获取资料,查看数据手册应如何实现读取数据,再移植至我们的工程。

3.1查看资料

输出信号:模块特设二路模拟输出(VRX,VRY)和一路数字输出接口(SW),二路模拟输出值分别对应(X,Y)双轴偏移量,其类型为模拟量;按键表示用户是否在Z轴上按下,其类型为数字开关量。

十字摇杆为一个双向的10K电阻器,随着摇杆方向不同,抽头的阻值随着变化。本模块如果使用5V供电,原始状态下X,Y读出电压为2.5V左右,当随箭头方向按下,读出电压值减少,限小为0V。

3.2引脚选择

VRX与VRY使用ADC功能。

想要使用ADC,需要确定使用的引脚是否有ADC外设功能。

当前只有AO引脚需要使用到ADC接口,所以DO引脚可以使用开发板上其他的GPIO。这里选择使用PA1和PA2的附加ADC功能。使用ADC的第1道和2通道。

wKgZO2flMoWASIekAAClLFymW44730.jpg

ADC功能引脚

wKgZPGflMoaAPw8FAADqpBXA0lw421.jpg

模块接线图

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;                     // 帧数据长度为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 收发在前
        SPI_InitStructure.SPI_Speed = SPI_Speed_Low;                          // 低速SPI

        SPI_Init(PORT_SPI, &SPI_InitStructure);   // 初始化
        SPI_Cmd(PORT_SPI, ENABLE);   // 使能SPI1
}

/**
  * @brief :SPI收发一个字节
  * @param :
  * @TxByte: 发送的数据字节
  * @note  :非堵塞式,一旦等待超时,函数会自动退出
  * @retval:接收到的字节
  */
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))//等待发送缓冲区为空
        {
                if( SPI_WAIT_TIMEOUT == ++l_WaitTime )
                {
                        break;                        //如果等待超时则退出
                }
        }
        l_WaitTime = SPI_WAIT_TIMEOUT / 2;                //重新设置接收等待时间(因为SPI的速度很快,正常情况下在发送完成之后会立即收到数据,等待时间不需要过长)
        SPI_SendData(PORT_SPI, TxByte);//发送数据

    while(RESET == SPI_GetFlagStatus(PORT_SPI, SPI_FLAG_RXNE))//等待接收缓冲区非空
        {
                if( SPI_WAIT_TIMEOUT == ++l_WaitTime )
                {
                                break;                        //如果等待超时则退出
                }
        }
    l_Data = SPI_ReceiveData(PORT_SPI);//读取接收数据

        return l_Data;                //返回
}

/**
  * @brief :SPI收发字符串
  * @param :
  * @ReadBuffer: 接收数据缓冲区地址
  * @WriteBuffer:发送字节缓冲区地址
  * @Length:字节长度
  * @note  :非堵塞式,一旦等待超时,函数会自动退出
  * @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 ); //收发数据
                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主函数中,编写如下。

/*
 * 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);
    }
}

移植现象:移动摇杆并且按下,输出摇杆移动的数据。

wKgZO2flMoaAB5WCAADi0AsUINE552.jpg

模块移植成功案例代码:

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

提取码:LCKF

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 模块
    +关注

    关注

    7

    文章

    2822

    浏览量

    52798
  • 游戏
    +关注

    关注

    2

    文章

    787

    浏览量

    27246
  • 按键
    +关注

    关注

    4

    文章

    229

    浏览量

    58419
  • CW32
    +关注

    关注

    1

    文章

    281

    浏览量

    1677
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    CW32移植Free-RTOS】CW32开发者扶持计划

    CW32配置Free-RTOS全过程,CW32开发者扶持计划
    的头像 发表于 04-18 09:38 7134次阅读
    【<b class='flag-5'>CW32</b>移植Free-RTOS】<b class='flag-5'>CW32</b>开发者扶持计划

    【应用笔记】CW32 电容式触摸按键设计指南

    前言CW32电容式触摸按键设计指南向客户提供一种利用CW32内部资源结合软件编程实现电容式触摸按键有效触摸检测的方法。本指南的内容重点在于工作原理、软件检测过程以及调试指引。利用芯源半
    的头像 发表于 07-04 11:44 1791次阅读
    【应用笔记】<b class='flag-5'>CW32</b> 电容式触摸<b class='flag-5'>按键</b>设计指南

    【外设移植】按键摇杆模块Ai-M61开发板

    按键摇杆模块采用金属按键摇杆电位器,
    的头像 发表于 03-12 15:24 1912次阅读
    【外设移植】<b class='flag-5'>双</b><b class='flag-5'>轴</b><b class='flag-5'>按键</b><b class='flag-5'>摇杆</b><b class='flag-5'>模块</b>Ai-M61开发板

    【项目展示】基于CW32的遥控循迹小车

    蓝牙模块、OLED屏幕、TB6612和红外循迹模块组成,电源采用可充电锂电池供电,建议不要使用 1.5V 干电池供电。 图1 CW32小车 二、硬件部分 2.1主控板 小车主控板由小蓝板和控制底板组成,小蓝板通过排母与控制底板
    的头像 发表于 05-31 17:33 2228次阅读
    【项目展示】基于<b class='flag-5'>CW32</b>的遥控循迹小车

    NanoPi +重力摇杆

    介绍JoystickMatrix-Joystick是一个按键摇杆模块,由两个滑动变阻器和一个按键
    发表于 11-13 17:25

    PS2游戏操纵杆摇杆模块

    PS2游戏操纵杆摇杆模块按键摇杆)产品简介:
    发表于 07-19 09:40

    STM32摇杆控制空心杯电机摇杆传感器

    STM32摇杆控制空心杯电机摇杆传感器  PS2
    发表于 09-07 08:43

    摇杆模块说明

    37种传感器(十三)之摇杆模块+Stduino Nano&UNO本文转载自:关键词:51、stm32、arduino、stduino单片机、stduino UNO&Nano、摇杆模块
    发表于 12-01 07:09

    CW32饭盒派开发板试用体验】4. ADC采样摇杆模块X和Y输出

    器 前言 本文主要讲解如何使用ADC,板载了一个电位计连接到了PB00上,官方提供了示例工程,本文就不做过多说明了。 本文使用ADC采集摇杆模块的模拟量,摇杆的X与Y
    发表于 06-01 22:13

    CW32 电容式触摸按键设计指南

    CW32 电容式触摸按键设计指南
    的头像 发表于 10-25 16:36 1761次阅读
    <b class='flag-5'>CW32</b> 电容式触摸<b class='flag-5'>按键</b>设计指南

    基于CW32的RC522刷卡模块的应用

    基于CW32的RC522刷卡模块的应用
    的头像 发表于 11-02 14:53 2280次阅读
    基于<b class='flag-5'>CW32</b>的RC522刷卡<b class='flag-5'>模块</b>的应用

    基于CW32的物联网应用

    CW32】基于CW32的物联网应用
    的头像 发表于 11-02 15:55 1694次阅读
    基于<b class='flag-5'>CW32</b>的物联网应用

    基于CW32的遥控循迹小车

    本实验是使用CW32单片机制作一个入门的遥控循迹小车。遥控采用蓝牙配合手机APP进行遥控。循迹使用一个5路的循迹模块。使用OLED模块进行显示当前小车状态。
    的头像 发表于 11-17 17:46 1970次阅读
    基于<b class='flag-5'>CW32</b>的遥控循迹小车

    【GD32F303红枫派开发板使用手册】第十二讲 ADC-按键摇杆多通道循环采样实验

    本实验是通过ADC规则组多通道循环采样方式实现按键摇杆传感器x和y电压值的读取,通过本实验主要学习以下内容: •
    的头像 发表于 06-11 09:40 1517次阅读
    【GD32F303红枫派开发板使用手册】第十二讲   ADC-<b class='flag-5'>双</b><b class='flag-5'>轴</b><b class='flag-5'>按键</b><b class='flag-5'>摇杆</b>多通道循环采样实验

    使用芯源CW32CW32L012开发评估板做了spi屏幕驱动

    CW32生态社区以极高的性价比入手了这块CW32L012开发评估板,开发板以底板、核心板、1.77寸TFT显示屏构成,所有的IO口都引出了排针,这点好评,使用杜邦线可以非常方便的连接其他模块。引脚
    的头像 发表于 11-21 11:34 297次阅读
    使用芯源<b class='flag-5'>CW32</b>的<b class='flag-5'>CW</b>32L012开发评估板做了spi屏幕驱动