STM32--游戏摇杆模块JOYStick

Posted yasina

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32--游戏摇杆模块JOYStick相关的知识,希望对你有一定的参考价值。

技术图片

 

五个引脚分别为GND  +5V  x y z(按下)

原理: 

ps2摇杆 游戏摇杆模块 电子积木标准接口 及2.54mm插针 接口引出。

1、十字摇杆为一个双向的10k电阻器,随着摇杆方向不同,抽头的阻值随着变化。

2、本模块使用5v供电,原始状态下x,y读出电压为2.5v左右,当随箭头方向按下,读 电压值随着增加,最大到5v;箭头相反方向按下,读出电压值减少,最小为0v。

也就是说XY坐标可以通过ADC判断电压来确定位置!z是一个KEY

思路:

用两个ADC通道读取xy电压  一个I/O口来检测是否按下

ADC配置

 1 void  Adc_Init(void)
 2 {     
 3     GPIO_InitTypeDef  GPIO_InitStructure;
 4     ADC_InitTypeDef ADC_InitStruct;
 5     
 6     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1, ENABLE);     
 7 
 8     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;                 
 9     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;         
10     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         
11     GPIO_Init(GPIOA, &GPIO_InitStructure);                    
12     
13     RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置ADC的时钟,6分频,72m/6=12m<14m
14     ADC_DeInit(ADC1);//复位ADC1
15     
16     ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;//不开启连续转换(故为单次转换)
17     ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//数据右对齐
18     ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//触发方式为软件触发,所以设置为None
19     ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;//独立模式
20     ADC_InitStruct.ADC_NbrOfChannel=2;//一个通道
21     ADC_InitStruct.ADC_ScanConvMode=DISABLE;//扫描模式关闭
22     ADC_Init(ADC1,&ADC_InitStruct);
23     
24     ADC_Cmd(ADC1,ENABLE);//使能ADC1
25     
26     //校准
27     ADC_ResetCalibration(ADC1);//使能复位校准
28     while(ADC_GetResetCalibrationStatus(ADC1));//等待使能复位校准结束
29     ADC_StartCalibration(ADC1);//开始校准
30     while(ADC_GetCalibrationStatus(ADC1));//等待结束校准
31 
32 }                  
33 //获得ADC值
34 //ch:通道值 0~3
35 u16 Get_Adc(u8 ch)   
36 {
37       ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5);
38     /*ADC规则通道配置函数 ADC1的某个通道,第1个转换,采样周期239.5
39     如果有多个规则通道,需要多次配置此函数*/
40     
41     ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件转换启动
42     
43     while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//转换标志位,转换完成结束循环
44         
45     return ADC_GetConversionValue(ADC1);//返回转换结果
46 }
47 
48 u16 Get_Adc_Average(u8 ch,u8 times)
49 {
50     u32 temp_val=0;
51     u8 t;
52     for(t=0;t<times;t++)
53     {
54         temp_val+=Get_Adc(ch);
55         delay_ms(5);
56     }
57     return temp_val/times;
58 }      

KEY配置

void key_init()//key--PC0
{
  GPIO_InitTypeDef GPIO_InitStructure;                    //定义GPIO结构体    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);    //使能GPIOC时钟     
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;              //配置引脚    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;           //上拉输入    
    GPIO_Init(GPIOC,&GPIO_InitStructure);       //初始化GPIOC

}

int KEY_Scan(int mode)
{
    static u8 key_up=1;
    if(mode) key_up=1;
    if(key_up && (KEY==1))
    {
        delay_ms(10);
        key_up=0;
        if(KEY==1) 
            return 1;
    }
    else if(KEY==0) 
        key_up=1;
    return 0;
}

经过测试发现位置个电压之间存在如下关系

技术图片

 

 (视情况而定)

故写出如下判断函数

void Jok_boy()
{
    float tempx,tempy;
    u8 x,y,key,z;
    u16 adcx,adcy;
    key=KEY_Scan(0);//不支持连按
    if(key) z=1;
    else    z=0;
    adcx=Get_Adc_Average(ADC_Channel_1,2);
    adcy=Get_Adc_Average(ADC_Channel_2,2);
    tempx=(float)adcx*(3.3/4096);/*12位adc所以最大将3.3v电压分成4096份*/
    tempy=(float)adcy*(3.3/4096);
    x=tempx;y=tempy;
    if(x==2&&y==3) printf("Up");
    else if(x==3&&y==3) printf("Up to Left");
    else if(x==3&&y==2) printf("Left");
    else if(x==3&&y==0) printf("Down to Left");
    else if(x==2&&y==0) printf("Down");
    else if(x==0&&y==0) printf("Down to Right");
    else if(x==0&&y==2) printf("Right");
    else if(x==0&&y==3) printf("Up to Right");
    if(z==1)//按下key
        printf("ENTER
");
    else
        printf("输入ing……
");
}

主函数如下

#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "JOK_BOY.h"

int main(void)
 { 
    delay_init();
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    
    uart_init(115200);    
    Adc_Init();
    key_init();
    while(1)
    {
        Jok_boy();
    }                                            
}    

结果如下

技术图片

 

 (ps:最好设置个延时)

以上是关于STM32--游戏摇杆模块JOYStick的主要内容,如果未能解决你的问题,请参考以下文章

「雕爷学编程」Arduino动手做(38)——joystick双轴摇杆模块

单片机如何控制摇杆

关于Unity中摇杆的操作

安卓游戏软件摇杆

cocos2D 虚拟摇杆Joystick功能实现

STM32 USB主机+HID摇杆