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\r\n");
    else
        printf("輸入ing……\r\n");
}

主函數如下

#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:最好設置個延時)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM