stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)

本程序编写基于秉火霸道STM32F103ZET6运行环境。
stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第1张图片
今天来玩一个PS2游戏摇杆模块,也被称为Joystick,根据模块提供的手册,下面来了解下工作原理以及如何来应用。
stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第2张图片
看到这里我们就明白了,x,y是模拟量,而z是一个二值数据,在这里,可以利用STM32的ADC控制器来读取X,Y的输出,Z轴就很简单了,把它当作普通按键就可以了。

一、打开CubeMX进行基础配置

1.1、配置外部时钟

stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第3张图片
stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第4张图片

1.2、配置调试器stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第5张图片

1.3、配置串口调试,默认即可

stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第6张图片

1.4、配置ADC

关于ADC输入通道在STM32F103ZET6这款MCU里的分配表
stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第7张图片
stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第8张图片
设置数据右对齐、使能扫描和连续转换,间断转换模式关闭,使能通道,这里选择两个通道,分别是通道6和通道7,设置好两个通道的转换周期,默认为最大。

使能DMA,这样可以为CPU减负。
stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第9张图片
设置ADC1的DMA1通道1,外设到内存方向,循环模式,地址自增及数据宽度。

1.5、配置Z轴输入IO

stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第10张图片

1.6、生成基本工程

stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第11张图片

二、增加软件逻辑

//定义printf的重定向函数fputc,满足串口调试打印
int fputc(int ch, FILE* file)
{
    return HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, 100);
}

//通过DMA通道转换得到的值
uint32_t JOY_VALUE[2];
//保存转换计算后的电压值
__IO float ADC_VOL_VALUE[2];

#define UP         0
#define DOWN       1
#define LEFT       2
#define RIGHT      3
#define LEFT_UP    4
#define LEFT_DOWN  5
#define RIGHT_UP   6
#define RIGHT_DONW 7
#define ENTER      8
#define UNKNOW_KEY 99

//获取摇杆键值
uint8_t GET_KEY_VALUE(int x, int y, int z)
{
    if((0 == x) && (y > 100 && y < 255))
        return UP;
    else if((255 == x) && (y > 0 && y < 255))
        return DOWN ;
    else if((x > 0 && x < 255) && (255 == y))
        return LEFT ;
    else if((x > 0 && x < 255) && (0 == y))
        return RIGHT ;
    else if((0 == x) && (255 == y))
        return LEFT_UP ;
    else if((255 == x) && (255 == y))
        return LEFT_DOWN ;
    else if((0 == x) && (0 == y))
        return RIGHT_UP ;
    else if((255 == x) && (0 == y))
        return RIGHT_DONW ;
    else if(x > 0 && y > 0 && 0 == z)
        return ENTER ;

    return UNKNOW_KEY ;
}

以上的GET_KEY_VALUE是经过动手实践得出的6个方向的数值以及确定返回的键值的映射。
主函数实现:

int main(void)
{
    /* USER CODE BEGIN 1 */
    int JOY_X, JOY_Y, JOY_Z ;
    uint8_t key_value ;
    /* USER CODE END 1 */


    /* MCU Configuration--------------------------------------------------------*/

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */

    /* USER CODE END SysInit */

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_ADC1_Init();
    MX_USART2_UART_Init();
    /* USER CODE BEGIN 2 */
    HAL_ADC_Start_DMA(&hadc1, JOY_VALUE, 2);
    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        //3.3V位AD转换的参考电压值,STM32的AD转换为12bit,所以2^12=4096
        //故当输入参考电压为3.3V时,AD转换的结果为4096
        //取12bit数值
        ADC_VOL_VALUE[0] = (float)(JOY_VALUE[0] & 0xFFF) * 3.3 / 4096 ;
        ADC_VOL_VALUE[1] = (float)(JOY_VALUE[1] & 0xFFF) * 3.3 / 4096 ;
        printf("x:%.2fv   y:%.2fv\n", ADC_VOL_VALUE[0], ADC_VOL_VALUE[1]);
        //只取8位有效数据
        JOY_X = JOY_VALUE[0] & 0xFF;
        JOY_Y = JOY_VALUE[1] & 0xFF;
        JOY_Z = HAL_GPIO_ReadPin(JOY_Z_GPIO_Port, JOY_Z_Pin);
        key_value = GET_KEY_VALUE(JOY_X, JOY_Y, JOY_Z);
        printf("x:%d   y:%d  z:%d\n", JOY_X,	JOY_Y,	JOY_Z);

        switch(key_value)
        {
            case UP :
                printf("上\n");
                break ;

            case DOWN :
                printf("下\n");
                break ;

            case LEFT :
                printf("左\n");
                break ;

            case RIGHT  :
                printf("右\n");
                break ;

            case LEFT_UP:
                printf("左上\n");
                break ;

            case LEFT_DOWN:
                printf("左下\n");
                break ;

            case RIGHT_UP:
                printf("右上\n");
                break ;

            case RIGHT_DONW :
                printf("右下\n");
                break ;

            case ENTER :
                printf("确认\n");
                break ;

            default:
                break ;
        }

        HAL_Delay(200);
    }

    /* USER CODE END 3 */
}

三、实验结果

stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第12张图片
当没有拨动摇杆时:
stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第13张图片
当拨动档杆向左时:
stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第14张图片
当按下确认时候,Z轴输出为0
stm32cubeMX学习十四、游戏摇杆模块的使用(基于野火STM32F103ZET6开发板)_第15张图片

你可能感兴趣的:(stm32cubeMX)