采用PS2游戏摇杆模块(Joystick)更适合机器臂的控制//=================================https://zhuanlan.zhihu.com/p/81884920
VRX,VRY(x,y)输出模拟量,相当于两个电位器;(模拟量STM32无法识别,需要转换为数字量 -> ADC)
SW(z)输出数字量,相当于按键,没按是为1,按下为0;
开启DMA可以减轻CPU负担
1,完成STM32Cubemx的基本配置(RCC,SYS,时钟树);
2,开启ADC1的6,7通道:
数据对齐方式 -> 右对齐扫描转换,连续转换 -> 激活转换次数 -> 2
六,七通道采样周期 -> 239.5//=============防止太快
再开启ADC的DMA:循环模式,从外设到内存,高速;
Memory地址自增,Peripheral与Memory的数据宽度都是Word
把PB8作为输入引脚(GPIO_Input),命名为JOY_Z,并上拉;(可以开一个串口,打印相关参数)
3,给Joystick模块5.0V电压,STM32的AD转换为12bit,AD转换的结果2^12 = 4096;
HAL_ADC_Start_DMA(&hadc1, JOY_VALUE, 2);//=========================================开启ADC
参数:
uint32_t JOY_VALUE[2];//===============================================通过DMA通道转换得到的值
__IO float ADC_VOL_VALUE[2];//=========================================保存转换计算后的电压值
int JOY_X, JOY_Y, JOY_Z ;
uint8_t key_value ;
//电压
ADC_VOL_VALUE[0] = (float)(JOY_VALUE[0] & 0xFFF) * 5.0 / 4096 ;//===================================取12bit数值;
ADC_VOL_VALUE[1] = (float)(JOY_VALUE[1] & 0xFFF) * 5.0 / 4096 ;
printf("x:%.2fv y:%.2fv\n", ADC_VOL_VALUE[0], ADC_VOL_VALUE[1]);//=========================打印电压值(0~5.0V);
//只取8位有效数据
JOY_X = JOY_VALUE[0] & 0xFF;
JOY_Y = JOY_VALUE[1] & 0xFF;
JOY_Z = HAL_GPIO_ReadPin(JOY_Z_GPIO_Port, JOY_Z_Pin);
printf("x:%d y:%d z:%d\n", JOY_X, JOY_Y, JOY_Z);//=============================打印X,Y值(0~255),Z值(0或1);
//===========================================================对JOY_X,JOY_Y,JOY_Z的值进行判断,并实现相应程序
//key_value = GET_KEY_VALUE(JOY_X, JOY_Y, JOY_Z);=======================附加程序
HAL_Delay(200);//============================================防止打印过快
int fputc(int ch, FILE* file)//========================================定义printf的重定向函数fputc,满足串口调试打印(魔术棒 -> 开启USB)
{
return HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, 100);
}
//=====================================================================附加程序,显示当前状态============================================================\\
#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
uint8_t GET_KEY_VALUE(int x, int y, int z)//========================获取摇杆键值,经过动手实践得出的6个方向的数值以及确定返回的键值的映射
{
if((0 == x) && (y > 100 && y < 255))
return UP;
else if((255 == x) && (y > 0 && y < 255))
return DOWN ;
else if((x > 0 && x < 255) && (255 == y))
return LEFT ;
else if((x > 0 && x < 255) && (0 == y))
return RIGHT ;
else if((0 == x) && (255 == y))
return LEFT_UP ;
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 RIGHT_DONW ;
else if(x > 0 && y > 0 && 0 == z)
return ENTER ;
return UNKNOW_KEY ;
}
switch(key_value)
{
case UP :
printf("上\n");
break ;
case DOWN :
printf("下\n");
break ;
case LEFT :
printf("左\n");
break ;
case RIGHT :
printf("右\n");
break ;
case LEFT_UP:
printf("左上\n");
break ;
case LEFT_DOWN:
printf("左下\n");
break ;
case RIGHT_UP:
printf("右上\n");
break ;
case RIGHT_DONW :
printf("右下\n");
break ;
case ENTER :
printf("确认\n");
break ;
default:
break ;
}