- #ifndef JOY_H_
- #define JOY_H_
- #include "adc_timtrig.h"
- //定义判断的按键值
- #define UP 0
- #define DOWN 1
- #define LEFT 2
- #define RIGHT 3
- #define LEFT_UP 4
- #define LEFT_DOWN 5
- #define RIGHT_UP 6
- #define RIGHT_DONW 7
- #define ENTER 8
- #define UNKNOW_KEY 99
- //Z-->PB3
- #define JOY_Z_Value GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3)
- extern u16 JOY_X, JOY_Y, JOY_Z ;
- void JOY_GPIO_Init(void);
- void GET_KEY_Basedata(void);
- uint8_t GET_KEY_VALUE(int x, int y, int z);
- #endif /* JOY_H_ */
joy.c:
- /*
- * joy.c
- *
- * Created on: Nov 27, 2020
- * Author: Administrator
- */
- #include "joy.h"
- #include "debug.h"
- //保存转换计算后的电压值
- float ADC_VOL_VALUE[2];
- //最终值
- u16 JOY_X, JOY_Y, JOY_Z ;
- //GPIO初始化,主要是Z PB3
- void JOY_GPIO_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //内部上拉
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- //获取摇杆X,Y对应的ADC值 Z输入状态0或1
- //X-->PB0 Y-->PB1 Z-->PB3(按键仅0或1)
- void GET_KEY_Basedata(void)
- {
- //3.3V位AD转换的参考电压值,STM32的AD转换为12bit,所以2^12=4096
- //故当输入参考电压为3.3V时,AD转换的结果为4096
- //取12bit数值
- Get_Adc_Average(1);
- //printf("X is :%d ,Y is :%d ",ADC_DATA[0],ADC_DATA[1]);
- ADC_VOL_VALUE[0]= (float)(ADC_DATA[0] & 0xFFF) * 3.3 / 4096 ;
- ADC_VOL_VALUE[1]= (float)(ADC_DATA[0] & 0xFFF) * 3.3 / 4096 ;
- //printf("x:%.2fv y:%.2fv\n", ADC_VOL_VALUE[0], ADC_VOL_VALUE[1]);
- //只取高8位有效数据
- JOY_X = ADC_DATA[0]>>4;
- JOY_Y = ADC_DATA[1]>>4;
- JOY_Z = JOY_Z_Value;
- }
- //获取摇杆键值
- uint8_t GET_KEY_VALUE(int x, int y, int z)
- {
- if((0 == x) && (y > 100 && y < 255))
- return RIGHT;//TEST
- else if((255 == x) && (y > 0 && y < 255))
- return LEFT ;//TEST
- else if((x > 0 && x < 255) && (255 == y))
- return DOWN ;//TEST
- else if((x > 0 && x < 255) && (0 == y))
- return UP ;//TEST
- else if((0 == x) && (255 == y))
- return RIGHT_DONW ;//
- else if((255 == x) && (255 == y))
- return LEFT_DOWN ;
- else if((0 == x) && (0 == y))
- return RIGHT_UP ;
- else if((255 == x) && (0 == y))
- return LEFT_UP ;//
- else if(x > 0 && y > 0 && 0 == z)
- return ENTER ;
- return UNKNOW_KEY ;
- }
ADC相关的文件:
ADC.H
- /*
- * adc_timtrig.h
- *
- * Created on: Nov 21, 2020
- * Author: Administrator
- */
- #ifndef ADC_TIMTRIG_H_
- #define ADC_TIMTRIG_H_
- #include "ch32v10x.h"
- //PB0-->ADC_IN8
- //PB1-->ADC_IN9
- extern u16 tmpadcbuf[2];
- extern u16 ADC_DATA[2];
- void ADC_Function_Init(void);
- void TIM1_PWM_In( u16 arr, u16 psc, u16 ccp );
- u16* GetADC(void);
- u16* Get_Adc_Average(u8 times);
- #endif /* ADC_TIMTRIG_H_ */
ADC.C
- /*
- * adc_timtrig.c
- *
- * Created on: Nov 21, 2020
- * Author: Administrator
- */
- #include "adc_timtrig.h"
- #include "debug.h"
- u16 tmpadcbuf[2]={0};
- u16 ADC_DATA[2]={0};
- /*******************************************************************************
- * Function Name : ADC_Function_Init
- * Description : Initializes ADC collection.
- * Input : None
- * Return : None
- *******************************************************************************/
- void ADC_Function_Init(void)
- {
- ADC_InitTypeDef ADC_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE );
- RCC_ADCCLKConfig(RCC_PCLK2_Div8);
- //PB0-->AD_IN8
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- //PB1-->AD_IN9
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- ADC_DeInit(ADC1);
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
- ADC_InitStructure.ADC_ScanConvMode = DISABLE;
- ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigInjecConv_T1_CC4;
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
- ADC_InitStructure.ADC_NbrOfChannel = 2;
- ADC_Init(ADC1, &ADC_InitStructure);
- ADC_InjectedSequencerLengthConfig(ADC1, 2);
- ADC_InjectedChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);
- ADC_InjectedChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_239Cycles5);
- ADC_DiscModeChannelCountConfig( ADC1, 1);
- ADC_InjectedDiscModeCmd(ADC1 , ENABLE);
- ADC_ExternalTrigInjectedConvCmd(ADC1, ENABLE);
- ADC_Cmd(ADC1, ENABLE);
- ADC_ResetCalibration(ADC1);
- while(ADC_GetResetCalibrationStatus(ADC1));
- ADC_StartCalibration(ADC1);
- while(ADC_GetCalibrationStatus(ADC1));
- }
- /*******************************************************************************
- * Function Name : TIM1_PWM_In
- * Description : Initializes TIM1 PWM output.
- * Input : arr: the period value.
- * psc: the prescaler value.
- * ccp: the pulse value.
- * Return : None
- *******************************************************************************/
- void TIM1_PWM_In( u16 arr, u16 psc, u16 ccp )
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- TIM_OCInitTypeDef TIM_OCInitStructure;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE );
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init( GPIOA, &GPIO_InitStructure);
- TIM_TimeBaseInitStructure.TIM_Period = arr;
- TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure);
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OCInitStructure.TIM_Pulse = ccp;
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
- TIM_OC4Init( TIM1, &TIM_OCInitStructure );
- TIM_CtrlPWMOutputs(TIM1, ENABLE );
- TIM_OC4PreloadConfig( TIM1, TIM_OCPreload_Disable );
- TIM_ARRPreloadConfig( TIM1, ENABLE );
- TIM_SelectOutputTrigger( TIM1, TIM_TRGOSource_Update );
- TIM_Cmd( TIM1, ENABLE );
- }
- u16* GetADC(void)
- {
- while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
- ADC_ClearFlag( ADC1, ADC_FLAG_EOC);
- while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_JEOC ));
- ADC_ClearFlag( ADC1, ADC_FLAG_JEOC);
- tmpadcbuf[0]=ADC1->IDATAR1;
- tmpadcbuf[1]=ADC1->IDATAR2;
- return tmpadcbuf;
- }
- u16* Get_Adc_Average(u8 times)
- {
- u32 temp_val[2]={0,0};
- u8 t;
- for(t=0;t<times;t++)
- {
- GetADC();
- temp_val[0]+=tmpadcbuf[0];
- temp_val[1]+=tmpadcbuf[1];
- Delay_Ms(5);
- }
- ADC_DATA[0]=temp_val[0]/times;
- ADC_DATA[1]=temp_val[1]/times;
- return ADC_DATA;
- }
在main.c初始化JOY相关引脚:
- ADC_Function_Init();
- TIM1_PWM_In( 1000, 48000-1, 500 );
- JOY_GPIO_Init();
在while里面查询。判断键值方向,并串口打印出:
- GET_KEY_Basedata();
- key_value = GET_KEY_VALUE(JOY_X, JOY_Y, JOY_Z);
- printf("x:%d y:%d z:%d\n", JOY_X,JOY_Y,JOY_Z);
- switch(key_value)
- {
- case UP :
- printf("UP\n");
- break ;
- case DOWN :
- printf("DOWN\n");
- break ;
- case LEFT :
- printf("LEFT\n");
- break ;
- case RIGHT :
- printf("RIGHT\n");
- break ;
- case LEFT_UP:
- printf("LEFT_UP\n");
- break ;
- case LEFT_DOWN:
- printf("LEFT_DOWN\n");
- break ;
- case RIGHT_UP:
- printf("RIGHT_UP\n");
- break ;
- case RIGHT_DONW :
- printf("RIGHT_DONW\n");
- break ;
- case ENTER :
- printf("ENTER\n");
- break ;
- default:
- break ;
- }
编译下载,对摇杆进行不同方向的操作,看串口输出:
这样我们的摇杆就能正常控制了,里游戏移植又近了一步了。