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

双轴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)          //y0
    xyzVal.Y = Yup;
  else if(g_iAdcx[0]<1800 && g_iAdcx[0]>1000)  //y1
    xyzVal.Y = Ysup;                           
  else if(g_iAdcx[0]<2200 && g_iAdcx[0]>1800)  //y2
    xyzVal.Y = Ysp;                             
  else if(g_iAdcx[0]<3000 && g_iAdcx[0]>2200)  //y3
    xyzVal.Y = Ysdn;                           
  else if(g_iAdcx[0]<4200 && g_iAdcx[0]>3000)  //y4
    xyzVal.Y = Ydn;
  
  
  if(g_iAdcx[1]<1000 && g_iAdcx[1]>0)          //x0
    xyzVal.X = Xlf;                             
  else if(g_iAdcx[1]<1800 && g_iAdcx[1]>1000)  //x1
    xyzVal.X = Xslf;                            
  else if(g_iAdcx[1]<2200 && g_iAdcx[1]>1800)  //x2
    xyzVal.X = Xsp;                             
  else if(g_iAdcx[1]<3000 && g_iAdcx[1]>2200)  //x3
    xyzVal.X = Xsri;                            
  else if(g_iAdcx[1]<4200 && g_iAdcx[1]>3000)  //x4
    xyzVal.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 0
    keystate = KEYSTOP;                                        
  else if((xyzVal.Y == Yup) && (xyzVal.X == Xsp))                 //x2 y0 z0 1
    keystate = KEYUP;                                          
  else if((xyzVal.Y == Ysup) && (xyzVal.X == Xsp))                //x2 y1 z0 2
    keystate = KEYSUP;                                        
  else if((xyzVal.Y == Ydn) && (xyzVal.X == Xsp))                 //x2 y4 z0 3
    keystate = KEYDOWN;                                        
  else if((xyzVal.Y == Ysdn) && (xyzVal.X == Xsp))                //x2 y3 z0 4
    keystate = KEYSDOWN;                                       
  else if((xyzVal.Y == Ysp) && (xyzVal.X == Xlf))                 //x0 y2 z0 5
    keystate = KEYLEFT;                                        
  else if((xyzVal.Y == Ysp) && (xyzVal.X == Xslf))                //x1 y2 z0 6
    keystate = KEYSLEFT;                                       
  else if((xyzVal.Y == Ysp) && (xyzVal.X == Xri))                 //x4 y2 z0 7
    keystate = KEYRIGHT;                                      
  else if((xyzVal.Y == Ysp) && (xyzVal.X == Xsri))                //x3 y2 z0 8
    keystate = KEYSRIGHT;                                    
  else if(xyzVal.Z == Zdn)                                        //x2 y2 z1 9
    keystate = KEYPRESS;
  else if(((xyzVal.Y==Yup)&&(xyzVal.X==Xlf))||((xyzVal.Y==Yup)&&(xyzVal.X==Xslf))||((xyzVal.Y==Ysup)&&(xyzVal.X==Xlf)))                 //x01 y01 z0 10
    keystate = KEYUPLF;
  else if((xyzVal.Y == Ysup) && (xyzVal.X == Xslf))               //x1 y1 z0 11
    keystate = KEYSUPLF;
  else if(((xyzVal.Y==Yup)&&(xyzVal.X==Xri))||((xyzVal.Y==Yup)&&(xyzVal.X==Xsri))||((xyzVal.Y==Ysup)&&(xyzVal.X==Xri)))                 //x34 y01 z0 12
    keystate = KEYUPRI;
  else if((xyzVal.Y == Ysup) && (xyzVal.X == Xsri))               //x3 y1 z0 13
    keystate = KEYSUPRI;
  else if(((xyzVal.Y==Ydn)&&(xyzVal.X==Xlf))||((xyzVal.Y==Ydn)&&(xyzVal.X==Xslf))||((xyzVal.Y==Ysdn)&&(xyzVal.X==Xlf)))                 //x01 y34 z0 14
    keystate = KEYDOWNLF;
  else if((xyzVal.Y == Ysdn) && (xyzVal.X == Xslf))               //x1 y3 z0 15
    keystate = KEYSDOWNLF;
  else if(((xyzVal.Y==Ydn)&&(xyzVal.X==Xri))||((xyzVal.Y==Ydn)&&(xyzVal.X==Xsri))||((xyzVal.Y==Ysdn)&&(xyzVal.X==Xri)))                 //x34 y34 z0 16
    keystate = KEYDOWNRI;
  else if((xyzVal.Y == Ysdn) && (xyzVal.X == Xsri))               //x3 y3 z0 17
    keystate = KEYSDOWNRI;
  else
    keystate = 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();
  }
}

方向参考图

在这里插入图片描述

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值