初学者
10 分钟

使用 THB001P、VZ43FC1B5640007L 和 STM32L496AG,实现精准的双轴摇杆控制并具备触觉反馈

带有触觉反馈的摇杆控制方案,为用户界面提供直观操作体验

Thumbstick 2 Click with Discovery kit with STM32L496AG MCU

已发布 10月 20, 2025

点击板

Thumbstick 2 Click

开发板

Discovery kit with STM32L496AG MCU

编译器

NECTO Studio

微控制器单元

STM32L496AG

双轴操纵杆控制,集成按键与触觉反馈,为直观的人机界面提供理想体验

A

A

硬件概览

它是如何工作的?

Thumbstick 2 Click 基于 C&K Components 的高品质双轴摇杆 THB001P,该摇杆集成了按键,并配合额外电路实现了适用于嵌入式应用的高级输入和触觉反馈功能。该摇杆在 X 和 Y 两个轴上提供平滑且精确的运动控制,其角位移和位置数据通过 Microchip 的 MCP3202(12 位模数转换器)转换为数字信号,并通过 SPI 串行接口与主控通信。这种方式能够可靠获取代表摇杆运动的原始模拟值,从而确保在广泛的应

用场景中实现精确控制,包括人机界面、手持控制单元、工业设备、辅助装置和游戏控制器等需要精确定位和触觉确认的领域。除了方向输入之外,内置按键扩展了输入功能,在按下时可执行离散命令,同时该按键还与板载振动电机相连。板载背面的 VZ43FC1B5640007L 振动电机能够提供 0.91G 的强烈触觉反馈,并以额定转速 10,000 rpm 运行,产生即时的触觉信号,从而增强用户的实时交互体验。其

工作由 VB 引脚通过 PWM 控制,从而可以根据应用需求灵活调节振动强度和持续时间。该 Click board™ 可在 3.3V 或 5V 逻辑电压下工作,通过 VCC SEL 跳线进行选择,因此无论是 3.3V 还是 5V 的 MCU 都能正确使用通信接口。此外,该 Click board™ 还配备了一个库文件,其中包含易于使用的函数和示例代码,可作为进一步开发的参考。

Thumbstick 2 Click hardware overview image

功能概述

开发板

32L496GDISCOVERY Discovery 套件是一款功能全面的演示和开发平台,专为搭载 Arm® Cortex®-M4 内核的 STM32L496AG 微控制器设计。该套件适用于需要在高性能、先进图形处理和超低功耗之间取得平衡的应用,支持无缝原型开发,适用于各种嵌入式解决方案。STM32L496AG 采用创新的节能架构,集成

了扩展 RAM 和 Chrom-ART 图形加速器,在提升图形性能的同时保持低功耗,使其特别适用于音频处理、图形用户界面和实时数据采集等对能效要求较高的应用。为了简化开发流程,该开发板配备了板载 ST-LINK/V2-1 调试器/编程器,提供即插即用的调试和编程体验,使用户无需额外硬件即可轻松加载、调

试和测试应用程序。凭借低功耗特性、增强的内存能力以及内置调试工具,32L496GDISCOVERY 套件是开发先进嵌入式系统、实现高效能解决方案的理想选择。

Discovery kit with STM32L496AG MCU double side image

微控制器概述 

MCU卡片 / MCU

STM32L496AG Image

建筑

ARM Cortex-M4

MCU 内存 (KB)

1024

硅供应商

STMicroelectronics

引脚数

169

RAM (字节)

327680

使用的MCU引脚

mikroBUS™映射器

NC
NC
AN
ID SEL
PB2
RST
SPI Select / ID COMM
PG11
CS
SPI Clock
PI1
SCK
SPI Data OUT
PD3
MISO
SPI Data IN
PI3
MOSI
Power Supply
3.3V
3.3V
Ground
GND
GND
Vibro Motor Control
PA0
PWM
Push-Button Status
PH2
INT
NC
NC
TX
NC
NC
RX
NC
NC
SCL
NC
NC
SDA
Power Supply
5V
5V
Ground
GND
GND
1

“仔细看看!”

Click board™ 原理图

Thumbstick 2 Click Schematic schematic

一步一步来

项目组装

Discovery kit with STM32H750XB MCU front image hardware assembly

从选择您的开发板和Click板™开始。以Discovery kit with STM32L496AG MCU作为您的开发板开始。

Discovery kit with STM32H750XB MCU front image hardware assembly
Thermo 21 Click front image hardware assembly
Prog-cut hardware assembly
Thermo 21 Click complete accessories setup image hardware assembly
Board mapper by product7 hardware assembly
Necto image step 2 hardware assembly
Necto image step 3 hardware assembly
Necto image step 4 hardware assembly
Necto image step 5 hardware assembly
Necto image step 6 hardware assembly
Discovery kit with STM32H750XB MCU NECTO MCU Selection Step hardware assembly
Necto No Display image step 8 hardware assembly
Necto image step 9 hardware assembly
Necto image step 10 hardware assembly
Necto image step 11 hardware assembly

软件支持

库描述

Thumbstick 2 Click 演示应用程序使用 NECTO Studio开发,确保与 mikroSDK 的开源库和工具兼容。该演示设计为即插即用,可与所有具有 mikroBUS™ 插座的 开发板、入门板和 mikromedia 板完全兼容,用于快速实现和测试。

示例描述
本示例演示了 Thumbstick 2 Click 开发板的使用方法,该开发板配备了一个双轴摇杆,带有按键功能和振动反馈。摇杆的角度和位置基于原始 ADC 数值计算得出,而按键状态则通过 PWM 输出控制振动电机。

关键功能:

  • thumbstick2_cfg_setup - 此函数将 Click 配置结构体初始化为初始值。

  • thumbstick2_init - 此函数初始化本 Click 板所需的所有引脚和外设。

  • thumbstick2_read_raw_adc - 此函数通过 SPI 串行接口读取 X 和 Y 轴的原始 ADC 值。

  • thumbstick2_get_angle - 此函数根据 X 和 Y 轴的原始 ADC 值计算并返回摇杆角度(度数)。

  • thumbstick2_get_position - 此函数根据 X 和 Y 轴的原始 ADC 值计算并返回摇杆位置标志。

应用初始化
初始化日志模块和 Click 驱动程序。

应用任务
持续读取摇杆各轴的原始 ADC 值,计算并记录摇杆的角度和位置。同时检测摇杆按键状态,并根据按键动作触发振动反馈。

开源

代码示例

完整的应用程序代码和一个现成的项目可以通过NECTO Studio包管理器直接安装到NECTO Studio 应用程序代码也可以在MIKROE的GitHub账户中找到。

/*!
 * @file main.c
 * @brief Thumbstick 2 Click example
 *
 * # Description
 * This example demonstrates the use of the Thumbstick 2 Click board which 
 * features a 2-axis joystick with push button and vibration feedback. 
 * The joystick's angle and position are calculated based on raw ADC values, 
 * while the push button status controls the vibration motor through PWM output.
 *
 * The demo application is composed of two sections :
 *
 * ## Application Init
 * Initializes the logger and the Click driver.
 *
 * ## Application Task
 * Continuously reads the raw ADC values from the joystick axes, calculates the 
 * joystick's position and angle, and logs the results. It also checks the state 
 * of the joystick push button and activates vibration feedback accordingly.
 *
 * @author Stefan Filipovic
 *
 */

#include "board.h"
#include "log.h"
#include "thumbstick2.h"

static thumbstick2_t thumbstick2;
static log_t logger;

void application_init ( void )
{
    log_cfg_t log_cfg;  /**< Logger config object. */
    thumbstick2_cfg_t thumbstick2_cfg;  /**< Click config object. */

    /** 
     * Logger initialization.
     * Default baud rate: 115200
     * Default log level: LOG_LEVEL_DEBUG
     * @note If USB_UART_RX and USB_UART_TX 
     * are defined as HAL_PIN_NC, you will 
     * need to define them manually for log to work. 
     * See @b LOG_MAP_USB_UART macro definition for detailed explanation.
     */
    LOG_MAP_USB_UART( log_cfg );
    log_init( &logger, &log_cfg );
    log_info( &logger, " Application Init " );

    // Click initialization.
    thumbstick2_cfg_setup( &thumbstick2_cfg );
    THUMBSTICK2_MAP_MIKROBUS( thumbstick2_cfg, MIKROBUS_1 );
    if ( THUMBSTICK2_OK != thumbstick2_init( &thumbstick2, &thumbstick2_cfg ) )
    {
        log_error( &logger, " Communication init." );
        for ( ; ; );
    }
    
    log_info( &logger, " Application Task " );
}

void application_task ( void )
{
    float angle = 0;
    uint16_t raw_x = 0;
    uint16_t raw_y = 0;
    uint8_t position = 0;
    if ( THUMBSTICK2_OK == thumbstick2_read_raw_adc ( &thumbstick2, &raw_x, &raw_y ) )
    {
        angle = thumbstick2_get_angle ( raw_x, raw_y );
        position = thumbstick2_get_position ( raw_x, raw_y );
        log_printf ( &logger, " RAW X: %u\r\n RAW Y: %u\r\n", raw_x, raw_y );
        log_printf ( &logger, " Joystick angle: %.1f degrees\r\n", angle );
        log_printf ( &logger, " Joystick position: " );
        switch ( position )
        {
            case THUMBSTICK2_POSITION_NEUTRAL:
            {
                log_printf ( &logger, "NEUTRAL" );
                break;
            }
            case THUMBSTICK2_POSITION_UP:
            {
                log_printf ( &logger, "UP" );
                break;
            }
            case THUMBSTICK2_POSITION_UPPER_LEFT:
            {
                log_printf ( &logger, "UPPER-LEFT" );
                break;
            }
            case THUMBSTICK2_POSITION_LEFT:
            {
                log_printf ( &logger, "LEFT" );
                break;
            }
            case THUMBSTICK2_POSITION_LOWER_LEFT:
            {
                log_printf ( &logger, "LOWER-LEFT" );
                break;
            }
            case THUMBSTICK2_POSITION_DOWN:
            {
                log_printf ( &logger, "DOWN" );
                break;
            }
            case THUMBSTICK2_POSITION_LOWER_RIGHT:
            {
                log_printf ( &logger, "LOWER-RIGHT" );
                break;
            }
            case THUMBSTICK2_POSITION_RIGHT:
            {
                log_printf ( &logger, "RIGHT" );
                break;
            }
            case THUMBSTICK2_POSITION_UPPER_RIGHT:
            {
                log_printf ( &logger, "UPPER-RIGHT" );
                break;
            }
            default:
            {
                log_printf ( &logger, "UNKNOWN" );
                break;
            }
        }
        log_printf ( &logger, "\r\n" );
        if ( thumbstick2_get_sw_pin ( &thumbstick2 ) )
        {
            log_printf ( &logger, " Button: Idle\r\n" );
            log_printf ( &logger, " Vibro: Idle\r\n\n" );
            thumbstick2_set_duty_cycle ( &thumbstick2, THUMBSTICK2_PWM_MIN_DUTY );
        }
        else
        {
            log_printf ( &logger, " Button: Active\r\n" );
            log_printf ( &logger, " Vibro: Active\r\n\n" );
            thumbstick2_set_duty_cycle ( &thumbstick2, THUMBSTICK2_PWM_MAX_DUTY );
        }
        Delay_ms ( 100 );
    }
}

int main ( void ) 
{
    /* Do not remove this line or clock might not be set correctly. */
    #ifdef PREINIT_SUPPORTED
    preinit();
    #endif
    
    application_init( );
    
    for ( ; ; ) 
    {
        application_task( );
    }

    return 0;
}

// ------------------------------------------------------------------------ END

额外支持

资源

喜欢这个项目吗?

'购买此套件' 按钮会直接带您进入购物车,您可以在购物车中轻松添加或移除产品。