摇杆开关的简单应用


一、应用场景?

摇杆开关通常用于需要进行方向控制或位置选择的应用中。以下是一些可能会使用到摇杆开关的情况:

1.游戏控制器:带有摇杆的模拟开关可以作为游戏控制器的一部分,用于控制角色的移动方向或相机的视角。

2.摄像机控制:在摄影和摄像领域中,摇杆可以用来控制摄像机的云台、倾斜和缩放等功能,实现平滑的运动和精确的定位。

3.机器人操作:对于一些机器人应用,带有摇杆的模拟开关可以用来控制机器人的移动方向和速度,同时还可以实现其他功能,如臂部的抬升和旋转等。

4.航空模型控制:在遥控飞机、直升机、无人机等航空模型中,摇杆可以用来控制飞行器的姿态、方向和速度,提供精确的操控能力。

5.工业控制系统:在工业自动化领域中,带有摇杆的模拟开关可以用于控制机器、设备或生产线的运动和位置选择,实现精确的操作和调整。

二、摇杆开关是什么?

微型指拨摇杆开关:THB001P
带有多功能, 高质量的双轴杠杆和集成的中心选择开关 适用于航模玩具遥控器电位器、3D摇杆PS4手柄游戏机、无人机摇杆电位器、工业控制器。

工作原理如下:
1.摇杆位置传感器:THB001P内部集成了一个摇杆位置传感器,通常是一个可变电阻或霍尔效应传感器。
2.模数转换器(ADC):微控制器或其他电子设备上的ADC模块用于将模拟信号转换为数字信号。THB001P的摇杆位置传感器输出的模拟信号会经过ADC转换为数字信号。
3.数字信号处理:转换后的数字信号可以通过软件算法进行处理,以确定摇杆的具体位置和状态。
4.控制反馈:处理后的数字信号可以用于控制相关设备或提供反馈信息,例如调整音量、移动机械部件等。
所以,如果THB001P是一个带有摇杆的模拟开关,它的工作原理涉及到摇杆位置传感器、模数转换器(ADC)和数字信号处理。这种设计能够实现更精确的位置检测和控制。
实物图

三、使用步骤

1.硬件

ADC_X和ADC_Y接的是单片机的ADC通道引脚,VADC是ADC的电压,这里没用到那个按键所以不接。

2.软件

2.1 初始化配置代码如下(示例):

/*******************************************************************************
 * 函数名:User_Rocker_Init
 * 描述  :摇杆开关初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
 *******************************************************************************/
void User_Rocker_Init(void)
{
  Rocker_ADC_Init();
  Rocker_DATA_Init();	
}

/*******************************************************************************
 * 函数名:Rocker_ADC_Init
 * 描述  :摇杆开关ADC配置初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
 *******************************************************************************/
void Rocker_ADC_Init(void)
{
	ADC_InitTypeDef ADC_InitS;
	
	Rocker_GPIO_Init();//ADC引脚配置
	
	RCC_APB2PeriphClockCmd(Rocker_AFIO_RCC | Rocker_ADC_RCC,ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	ADC_InitS.ADC_Mode = ADC_Mode_Independent; 
	ADC_InitS.ADC_ScanConvMode = ENABLE; //多通道(ENABLE)/单通道(DISABLE)
	ADC_InitS.ADC_ContinuousConvMode = ENABLE; //连续(ENABLE)/单次(DISABLE)
	ADC_InitS.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADC_InitS.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐
	ADC_InitS.ADC_NbrOfChannel = 2; //通道数
	ADC_Init(ADC_TYPE, &ADC_InitS);
	ADC_Cmd(ADC_TYPE,ENABLE);
	ADC_ResetCalibration(ADC_TYPE);
	while(ADC_GetResetCalibrationStatus(ADC_TYPE));
	ADC_StartCalibration(ADC_TYPE);//开始指定ADC的校准状态
	while(ADC_GetCalibrationStatus(ADC_TYPE));//获取指定ADC的校准程序
	ADC_SoftwareStartConvCmd(ADC_TYPE, ENABLE);//使能或者失能指定的ADC的软件转换启动功能
}

/*******************************************************************************
 * 函数名:Rocker_GPIO_Init
 * 描述  :摇杆开关引脚初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
 *******************************************************************************/
void Rocker_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(Rocker_GPIO_RCC, ENABLE);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;   
	GPIO_InitStructure.GPIO_Pin = ADCX_Pin | ADCY_Pin;//PA4,PA5	
	GPIO_Init(Rocker_GPIO, &GPIO_InitStructure);//GPIOA	
}

/*******************************************************************************
 * 函数名:Rocker_DATA_Init
 * 描述  :摇杆开关数据初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
 *******************************************************************************/
void Rocker_DATA_Init(void)
{
	Rocker_State.bits.Up = 0;
	Rocker_State.bits.Down = 0;
	Rocker_State.bits.Right = 0;
	Rocker_State.bits.Left = 0;
    Rocker_State.Up_Shift = 0;	
    Rocker_State.Down_Shift = 0;	
    Rocker_State.Right_Shift = 0;	
    Rocker_State.Left_Shift = 0;	
    Rocker_State.bits.Swing_mark = 0;	
}

2.2 读取ADC的值代码如下(示例):

/*******************************************************************************
 * 函数名:Read_AdC_Value
 * 描述  :读取ADC的值
 * 输入  :uint8_t
 * 输出  :uint16_t
 * 调用  :
 * 备注  :ADC采样
 *******************************************************************************/
uint16_t Read_AdC_Value(uint8_t cmd)
{
	while(!ADC_GetFlagStatus(ADC_TYPE,ADC_FLAG_EOC));//转换结束标志位	
	ADC_RegularChannelConfig(ADC_TYPE,cmd,1,ADC_SampleTime_28Cycles5);
	ADC_SoftwareStartConvCmd(ADC_TYPE, ENABLE);	
	return ADC_GetConversionValue(ADC_TYPE);//返回最近一次ADCx规则组的转换结果
}

cmd表示ADC的通道。

2.3 摇杆开关动作扫描代码如下(示例):

/*******************************************************************************
 * 函数名:Rocker_Scan
 * 描述  :摇杆开关动作扫描
 * 输入  :void
 * 输出  :void
 * 调用  :1ms
 * 备注  :
 *******************************************************************************/
void Rocker_Scan(void)
{
    X_Value = Read_AdC_Value(ADC_Channel_4);
    delay_syms(10); // 不可注释掉,确保X转换完毕能正常开始Y转换,确保ADC的准确性
//  printf("X_Value = %d\r\n",X_Value);

    if (X_Value > 1900) // 往下
    {
        Rocker_State.bits.Swing_mark = 1;
        Rocker_State.bits.Up = 0;
        Rocker_State.bits.Down = 1;
//      printf("Rocker_State.bits.Down = %d\r\n",Rocker_State.bits.Down);
    }
    else if (X_Value < 1700) // 往上
    {
        Rocker_State.bits.Swing_mark = 1;
        Rocker_State.bits.Up = 1;
        Rocker_State.bits.Down = 0;
//      printf("Rocker_State.bits.Up = %d\r\n",Rocker_State.bits.Up);
    }
    else if ((X_Value > 1750) && (X_Value < 1850))
    {
        Rocker_State.Up_Shift = 0;
        Rocker_State.Down_Shift = 0;
        Rocker_State.bits.Up = 0;
        Rocker_State.bits.Down = 0;
    }

    Y_Value = Read_AdC_Value(ADC_Channel_5);
//  printf("Y_Value = %d\r\n",Y_Value);

    if (Y_Value > 1750) // 往右
    {
        Rocker_State.bits.Swing_mark = 1;
        Rocker_State.bits.Right = 1;
        Rocker_State.bits.Left = 0;
//      printf("Rocker_State.bits.Right = %d\r\n",Rocker_State.bits.Right);
    }
    else if (Y_Value < 1550) // 往左
    {
        Rocker_State.bits.Swing_mark = 1;
        Rocker_State.bits.Right = 0;
        Rocker_State.bits.Left = 1;
//      printf("Rocker_State.bits.Left = %d\r\n",Rocker_State.bits.Left);
    }
    else if ((Y_Value > 1600) && (Y_Value < 1700))
    {
        Rocker_State.Right_Shift = 0;
        Rocker_State.Left_Shift = 0;
        Rocker_State.bits.Right = 0;
        Rocker_State.bits.Left = 0;
    }

    if ((!Rocker_State.bits.Down) && (!Rocker_State.bits.Up) && (!Rocker_State.bits.Right) && (!Rocker_State.bits.Left))
    {
        if (Rocker_State.bits.Swing_mark)
        {
            Rocker_State.bits.Swing_mark = 0;
            Uart1Prints("\r\n*STOP$");
        }
        LED20_Off();
    }
    else
    {
        LED20_On();
        if ((Rocker_State.bits.Up) && (!Rocker_State.bits.Down)) // 上
        {
            if (Rocker_State.bits.Right) // 右
            {
                Uart1Prints("\r\n*UP Right");
            }
            else if (Rocker_State.bits.Left) // 左
            {
                Uart1Prints("\r\n*UP Left");
            }
            else // X轴不动
            {
                Uart1Prints("\r\n*[UP XXXX");
            }
        }
        else if ((!Rocker_State.bits.Up) && (Rocker_State.bits.Down)) // 下
        {
            if (Rocker_State.bits.Right) // 右
            {
                Uart1Prints("\r\n*DOWN Right");
            }
            else if (Rocker_State.bits.Left) // 左
            {
                Uart1Prints("\r\n*DOWN Left");
            }
            else // X轴不动
            {
                Uart1Prints("\r\n*DOWN XXXX");
            }
        }
    }
}

通过对X,Y两个轴的AD采集数据,然后对两个数据进行判断来区别上下左右甚至360°方向识别。

2.4 变量定义(示例):

/* Defines ------------------------------------------------------------------*/
#define Rocker_GPIO_RCC RCC_APB2Periph_GPIOA
#define Rocker_AFIO_RCC RCC_APB2Periph_AFIO
#define Rocker_ADC_RCC  RCC_APB2Periph_ADC1
#define Rocker_GPIO     GPIOA
#define ADC_TYPE        ADC1
#define ADCX_Pin        GPIO_Pin_4
#define ADCY_Pin        GPIO_Pin_5//根据实际引脚配置

/* Variables Define ---------------------------------------------------------*/
struct ST_ROCKER{
	   struct
	   {
		     uint8_t  Up:1;//上
			 uint8_t  Down:1;//下
			 uint8_t  Right:1;//右		
			 uint8_t  Left:1;//左		
			 uint8_t  Swing_mark:1;//摆动标志
	  }bits;
	  uint8_t Up_Shift;//上挡位
	  uint8_t Down_Shift;//下挡位
	  uint8_t Right_Shift;//右挡位
	  uint8_t Left_Shift;//左挡位			
};
extern struct ST_ROCKER Rocker_State;

extern uint16_t X_Value;//ADC_X
extern uint16_t Y_Value;//ADC_Y

3.测试结果

以下是我用摇杆开关任意方向转动,串口打印的值,可以发现当摇杆回归原点,会打印出*STOP$

在这里插入图片描述


四、 总结

以上就是今天要讲的内容,本文仅仅简单介绍了摇杆开关的使用,而摇杆开关的使用还远远不止这一些,有兴趣的可以看看,玩一玩,感谢你的观看,谢谢!

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaobuding_QAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值