STM32-HAL库,双轴xy摇杆按键

2023-11-26 14:10
文章标签 stm32 按键 hal xy 摇杆 双轴

本文主要是介绍STM32-HAL库,双轴xy摇杆按键,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 双轴xy摇杆按键
    • CubeMX配置
  • 使用
    • u_RockerKey.h
    • u_RockerKey.c
    • main.c
    • 方向参考图

双轴xy摇杆按键

在这里插入图片描述
+5V:接电源
VRx:输出x轴的模拟量
VRy:输出x轴的模拟量
SW:z轴的按键,需将R5焊接一个限流电阻才能使用,拉高,低电平触发

CubeMX配置

PB1接VRx,PB0接VRy,PB8接SW
PB8输出模式上拉,PB0为ADC1_IN8,PB1为ADC1_IN9
ADC配置参考:我的文章《ADC多通道采样》的DMA部分:
https://blog.csdn.net/weixin_60301126/article/details/131730675
采样时间按需求配置,这里不过多介绍。
以及串口和定时器的使用也参考我的文章进行使用:
https://blog.csdn.net/weixin_60301126/article/details/131327438

使用

uint16_t g_iAdcx[2];//缓存ADC采样值HAL_ADC_Start_DMA(&hadc1, (uint32_t*)g_iAdcx, sizeof(g_iAdcx) / sizeof(g_iAdcx[0]));//我的连接方式g_iAdcx[0]采集y轴模拟量,g_iAdcx[1]采集x轴模拟量

u_RockerKey.h

#ifndef _U_ROCKERKEY_H_
#define _U_ROCKERKEY_H_#include "main.h"/*************************************/
// 说明 
// PB0用于ADC1_IN8,连接摇杆VRy 
// PB1用于ADC1_IN9,连接摇杆VRx
// PB8连接遥感SW
// 实现18种按键状态
/*************************************/typedef struct
{uint32_t Y;uint32_t X;uint32_t Z;
}xyzVal_struct;  //xyz轴值结构体typedef enum
{KEYSTOP = 0,  //摇杆不动    /* 0 */KEYUP,        //摇杆上推    /* 1 */KEYSUP,       //摇杆慢上推  /* 2 */KEYDOWN,      //摇杆下推    /* 3 */KEYSDOWN,     //摇杆慢下推  /* 4 */KEYLEFT,      //摇杆左推    /* 5 */KEYSLEFT,     //摇杆慢左推  /* 6 */KEYRIGHT,     //摇杆右推    /* 7 */KEYSRIGHT,    //摇杆慢右推  /* 8 */KEYPRESS,     //摇杆按下    /* 9 */KEYUPLF,      //摇杆上左推      /* 10 */KEYSUPLF,     //摇杆慢上左推    /* 11 */KEYUPRI,      //摇杆上右推      /* 12 */KEYSUPRI,     //摇杆慢上左推    /* 13 */KEYDOWNLF,    //摇杆下左推      /* 14 */KEYSDOWNLF,   //摇杆慢下左推    /* 15 */KEYDOWNRI,    //摇杆下右推      /* 16 */KEYSDOWNRI,   //摇杆慢下右推    /* 17 */KEYState_MAX                /* 18 */
}E_RKEYState;typedef enum
{Yup = 0,    //y轴上位    /* y0 */Ysup,       //y轴慢上位  /* y1 */Ysp,        //y轴中位    /* y2 */Ydn,        //y轴下位    /* y4 */Ysdn        //y轴慢下位  /* y3 */
}E_YaxleState;typedef enum
{Xlf = 0,     //x轴左位   /* x0 */Xslf,        //x轴慢左位 /* x1 */ Xsp,         //x轴中位   /* x2 */Xri,         //x轴右位   /* x4 */Xsri         //x轴慢右位 /* x3 */ 
}E_XaxleState;typedef enum
{Zup = 0,    //z轴上位    /* z0 */Zdn         //z轴下位    /* z1 */ 
}E_ZaxleState;void Get_xyzVal(void);           //获取xy轴的值
E_RKEYState Get_KeyState(void); //获取摇杆的状态
void Test(E_RKEYState state);   //测试摇杆功能#endif //_U_ROCKERKEY_H_

u_RockerKey.c

#include "u_RockerKey.h"
#include "u_print.h"xyzVal_struct xyzVal;
uint16_t g_iAdcx[2];/*函数名称:获取xyz轴的值*/
/*形参:无              */
/*返回值:无            */
void Get_xyzVal(void)
{ HAL_ADC_Start_DMA(&hadc1, (uint32_t*)g_iAdcx, sizeof(g_iAdcx) / sizeof(g_iAdcx[0]));
//  PrintfDebug("Y = %d\r\nX = %d\r\n", g_iAdcx[0], g_iAdcx[1]);if(g_iAdcx[0]<1000 && g_iAdcx[0]>0)          //y0xyzVal.Y = Yup;else if(g_iAdcx[0]<1800 && g_iAdcx[0]>1000)  //y1xyzVal.Y = Ysup;                           else if(g_iAdcx[0]<2200 && g_iAdcx[0]>1800)  //y2xyzVal.Y = Ysp;                             else if(g_iAdcx[0]<3000 && g_iAdcx[0]>2200)  //y3xyzVal.Y = Ysdn;                           else if(g_iAdcx[0]<4200 && g_iAdcx[0]>3000)  //y4xyzVal.Y = Ydn;if(g_iAdcx[1]<1000 && g_iAdcx[1]>0)          //x0xyzVal.X = Xlf;                             else if(g_iAdcx[1]<1800 && g_iAdcx[1]>1000)  //x1xyzVal.X = Xslf;                            else if(g_iAdcx[1]<2200 && g_iAdcx[1]>1800)  //x2xyzVal.X = Xsp;                             else if(g_iAdcx[1]<3000 && g_iAdcx[1]>2200)  //x3xyzVal.X = Xsri;                            else if(g_iAdcx[1]<4200 && g_iAdcx[1]>3000)  //x4xyzVal.X = Xri; if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_RESET)xyzVal.Z = Zdn;    else if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_SET)xyzVal.Z = Zup;
//  PrintfDebug("xyzVal.X = %d\r\nxyzVal.Y = %d\r\nxyzVal.Z = %d\r\n", xyzVal.X, xyzVal.Y, xyzVal.Z);
}/*函数名称:获取摇杆的状态 */
/*形参:无                */
/*返回值:keystate        */
/*说明:keystate为E_RKEYState的变量,返回按键状态值*/
E_RKEYState Get_KeyState(void)
{E_RKEYState keystate;Get_xyzVal(); 
//  PrintfDebug("%d %d\r\n", xyzVal.X, xyzVal.Y);                 //摇杆状态编码if((xyzVal.Y == Ysp) && (xyzVal.X == Xsp) && (xyzVal.Z == Zup)) //x2 y2 z0 0keystate = KEYSTOP;                                        else if((xyzVal.Y == Yup) && (xyzVal.X == Xsp))                 //x2 y0 z0 1keystate = KEYUP;                                          else if((xyzVal.Y == Ysup) && (xyzVal.X == Xsp))                //x2 y1 z0 2keystate = KEYSUP;                                        else if((xyzVal.Y == Ydn) && (xyzVal.X == Xsp))                 //x2 y4 z0 3keystate = KEYDOWN;                                        else if((xyzVal.Y == Ysdn) && (xyzVal.X == Xsp))                //x2 y3 z0 4keystate = KEYSDOWN;                                       else if((xyzVal.Y == Ysp) && (xyzVal.X == Xlf))                 //x0 y2 z0 5keystate = KEYLEFT;                                        else if((xyzVal.Y == Ysp) && (xyzVal.X == Xslf))                //x1 y2 z0 6keystate = KEYSLEFT;                                       else if((xyzVal.Y == Ysp) && (xyzVal.X == Xri))                 //x4 y2 z0 7keystate = KEYRIGHT;                                      else if((xyzVal.Y == Ysp) && (xyzVal.X == Xsri))                //x3 y2 z0 8keystate = KEYSRIGHT;                                    else if(xyzVal.Z == Zdn)                                        //x2 y2 z1 9keystate = KEYPRESS;else if(((xyzVal.Y==Yup)&&(xyzVal.X==Xlf))||((xyzVal.Y==Yup)&&(xyzVal.X==Xslf))||((xyzVal.Y==Ysup)&&(xyzVal.X==Xlf)))                 //x01 y01 z0 10keystate = KEYUPLF;else if((xyzVal.Y == Ysup) && (xyzVal.X == Xslf))               //x1 y1 z0 11keystate = KEYSUPLF;else if(((xyzVal.Y==Yup)&&(xyzVal.X==Xri))||((xyzVal.Y==Yup)&&(xyzVal.X==Xsri))||((xyzVal.Y==Ysup)&&(xyzVal.X==Xri)))                 //x34 y01 z0 12keystate = KEYUPRI;else if((xyzVal.Y == Ysup) && (xyzVal.X == Xsri))               //x3 y1 z0 13keystate = KEYSUPRI;else if(((xyzVal.Y==Ydn)&&(xyzVal.X==Xlf))||((xyzVal.Y==Ydn)&&(xyzVal.X==Xslf))||((xyzVal.Y==Ysdn)&&(xyzVal.X==Xlf)))                 //x01 y34 z0 14keystate = KEYDOWNLF;else if((xyzVal.Y == Ysdn) && (xyzVal.X == Xslf))               //x1 y3 z0 15keystate = KEYSDOWNLF;else if(((xyzVal.Y==Ydn)&&(xyzVal.X==Xri))||((xyzVal.Y==Ydn)&&(xyzVal.X==Xsri))||((xyzVal.Y==Ysdn)&&(xyzVal.X==Xri)))                 //x34 y34 z0 16keystate = KEYDOWNRI;else if((xyzVal.Y == Ysdn) && (xyzVal.X == Xsri))               //x3 y3 z0 17keystate = KEYSDOWNRI;elsekeystate = KEYState_MAX;
//  PrintfDebug("keystate = %d\r\n", keystate);return keystate;
}/*函数名称:测试摇杆功能   */
/*形参:E_RKEYState state */
/*返回值:无              */
void Test(E_RKEYState state)
{ switch(state){case KEYSTOP:PrintfDebug("No State\r\n");   break;case KEYUP:PrintfDebug("Key Up\r\n"); break;case KEYSUP:PrintfDebug("Key Slowly Up\r\n"); break;case KEYDOWN:PrintfDebug("Key Down\r\n"); break;case KEYSDOWN:PrintfDebug("Key Slowly Down\r\n"); break;case KEYLEFT:PrintfDebug("Key Left\r\n"); break;case KEYSLEFT:PrintfDebug("Key Slowly Left\r\n"); break;case KEYRIGHT:PrintfDebug("Key Right\r\n");break;case KEYSRIGHT:PrintfDebug("Key Slowly Right\r\n");break;case KEYPRESS:PrintfDebug("Press Key\r\n");break;case KEYUPLF:PrintfDebug("Key Up Left\r\n");break;case KEYSUPLF:PrintfDebug("Key Slowly Up Left\r\n");break;case KEYUPRI:PrintfDebug("Key Up Right\r\n");break;case KEYSUPRI:PrintfDebug("Key Slowly Up Right\r\n");break;case KEYDOWNLF:PrintfDebug("Key Down Left\r\n");break;case KEYSDOWNLF:PrintfDebug("Key Slowly Down Left\r\n");break;case KEYDOWNRI:PrintfDebug("Key Down Right\r\n");break;case KEYSDOWNRI:PrintfDebug("Key Slowly Down Right\r\n");break;case KEYState_MAX:PrintfDebug("State\r\n");break;default:break;}
}

main.c

static void Proc1sTask(void); int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_DMA_Init();MX_ADC1_Init();MX_USART1_UART_Init();MX_TIM6_Init();PrintfDebug("OK\r\n");while (1){Proc100msTask();}
}static void Proc100msTask(void)    //1s任务
{if(Get100msFlag()){Test(Get_KeyState());Clr100msFlag();}
}

方向参考图

在这里插入图片描述

这篇关于STM32-HAL库,双轴xy摇杆按键的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/425835

相关文章

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介  1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置,启动方式也不方便需要配置BOOT引脚触发启动  4 IAP(自己写的Bootloader,实现程序升级) 1 比如蓝牙转串口,

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

STM32 ADC+DMA导致写FLASH失败

最近用STM32G070系列的ADC+DMA采样时,遇到了一些小坑记录一下; 一、ADC+DMA采样时进入死循环; 解决方法:ADC-dma死循环问题_stm32 adc dma死机-CSDN博客 将ADC的DMA中断调整为最高,且增大ADCHAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_Buffer_Size); 的ADC_Bu

STM32CubeMX和HAL库-新建项目

目录 新建项目 选择开发板  MCU图形化配置界面总览 MCU配置 新建项目 新建项目包含选择MCU创建项目、选择开发板新建项目和交叉选择MCU新建项目三部分。 1. 选择MCU创建项目 单击主菜单项File→New Project,或Home视图上的ACCESS TO MCU SELECTOR 按钮,都可以打开的New Project from a MCU/MPU对话框。

独立按键单击检测(延时消抖+定时器扫描)

目录 独立按键简介 按键抖动 模块接线 延时消抖 Key.h Key.c 定时器扫描按键代码 Key.h Key.c main.c 思考  MultiButton按键驱动 独立按键简介 ​ 轻触按键相当于一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通与断开。  ​ 按键抖动 由于按键内部使用的是机

基于stm32的河流检测系统-单片机毕业设计

文章目录 前言资料获取设计介绍功能介绍具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机设计精品

STM32的使用方法一

注:我采用的是STM32F103RC芯片、相应的电路图和STM32CubeIDE软件这是在STM32CubeIDE软件定义芯片后,所给的必要的代码逻辑,加上了注释 #include "main.h"/* Private variables ---------------------------------------------------------*//* Private function