RobotHardware-UESTC/Hardware/Pibot驱动底盘/PiRobot_Firmware v1.0/STM32/Lib/PS2/pstwo.cpp

288 lines
5.7 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "pstwo.h"
#include "bsplib.h"
/*********************************************************
Copyright (C), 2015-2025, YFRobot.
www.yfrobot.com
FilePS2驱动程序
Authorpinggai Version:1.1 Data:2015/10/20
Description: PS2驱动程序
增加功能:
1、软件设置“红灯模式”、“绿灯模式”并可以设置“保存”通过手柄“模式按键”无法改变
2、设置手柄震动通过数值的设置改变左侧大震动电机震动频率。
通过数值的设置,开关右侧小震动电机。
History:
V1.0: 2015/05/16
1、手柄解码识别按键值读取模拟值。
**********************************************************/
#define DELAY_TIME delay_us(3);
unsigned short Handkey; // 按键值读取,零时存储。
unsigned char Comd[2]={0x01,0x42}; //开始命令。请求数据
unsigned char Data[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //数据存储数组
unsigned short MASK[]={
PSB_SELECT,
PSB_L3,
PSB_R3 ,
PSB_START,
PSB_PAD_UP,
PSB_PAD_RIGHT,
PSB_PAD_DOWN,
PSB_PAD_LEFT,
PSB_L2,
PSB_R2,
PSB_L1,
PSB_R1 ,
PSB_GREEN,
PSB_RED,
PSB_BLUE,
PSB_PINK
}; //按键值与按键明
//手柄接口初始化 输入 DI->PB12
// 输出 DO->PB13 CS->PB14 CLK->PB15
void PS2_Init(void)
{
//输入 DI->PB12
RCC->APB2ENR|=1<<3; //使能PORTB时钟
GPIOB->CRH&=0XFFF0FFFF;//PB12设置成输入 默认下拉
GPIOB->CRH|=0X00080000;
// DO->PB13 CS->PB14 CLK->PB15
RCC->APB2ENR|=1<<3; //使能PORTB时钟
GPIOB->CRH&=0X000FFFFF;
GPIOB->CRH|=0X33300000;//PB13、PB14、PB15 推挽输出
}
//向手柄发送命令
void PS2_Cmd(unsigned char CMD)
{
volatile unsigned short ref=0x01;
Data[1] = 0;
for(ref=0x01; ref<0x0100; ref<<=1) {
if(ref&CMD) {
DO_H; //输出一位控制位
} else {
DO_L;
}
CLK_H; //时钟拉高
DELAY_TIME;
CLK_L;
DELAY_TIME;
CLK_H;
if(DI)
Data[1] = ref|Data[1];
}
delay_us(16);
}
//判断是否为红灯模式,0x41=模拟绿灯0x73=模拟红灯
//返回值0红灯模式
// 其他,其他模式
unsigned char PS2_RedLight(void)
{
CS_L;
PS2_Cmd(Comd[0]); //开始命令
PS2_Cmd(Comd[1]); //请求数据
CS_H;
if( Data[1] == 0X73)
return 0 ;
return 1;
}
//读取手柄数据
void PS2_ReadData(void)
{
volatile unsigned char byte=0;
volatile unsigned short ref=0x01;
CS_L;
PS2_Cmd(Comd[0]); //开始命令
PS2_Cmd(Comd[1]); //请求数据
//开始接受数据
for(byte=2;byte<9;byte++) {
for(ref=0x01;ref<0x100;ref<<=1) {
CLK_H;
DELAY_TIME;
CLK_L;
DELAY_TIME;
CLK_H;
if(DI)
Data[byte] = ref|Data[byte];
}
delay_us(16);
}
CS_H;
}
//对读出来的PS2的数据进行处理,只处理按键部分
//只有一个按键按下时按下为0 未按下为1
unsigned char PS2_DataKey()
{
unsigned char index;
PS2_ClearData();
PS2_ReadData();
Handkey=(Data[4]<<8)|Data[3]; //这是16个按键 按下为0 未按下为1
for(index=0;index<16;index++) {
if((Handkey&(1<<(MASK[index]-1)))==0)
return index+1;
}
return 0; //没有任何按键按下
}
//得到一个摇杆的模拟量 范围0~256
unsigned char PS2_AnologData(unsigned char button)
{
return Data[button];
}
//清除数据缓冲区
void PS2_ClearData()
{
unsigned char a;
for(a=0;a<9;a++)
Data[a]=0x00;
}
/******************************************************
Function: void PS2_Vibration(unsigned char motor1, unsigned char motor2)
Description: 手柄震动函数,
Calls: void PS2_Cmd(unsigned char CMD);
Input: motor1:右侧小震动电机 0x00关其他开
motor2:左侧大震动电机 0x40~0xFF 电机开,值越大 震动越大
******************************************************/
void PS2_Vibration(unsigned char motor1, unsigned char motor2)
{
CS_L;
delay_us(16);
PS2_Cmd(0x01); //开始命令
PS2_Cmd(0x42); //请求数据
PS2_Cmd(0X00);
PS2_Cmd(motor1);
PS2_Cmd(motor2);
PS2_Cmd(0X00);
PS2_Cmd(0X00);
PS2_Cmd(0X00);
PS2_Cmd(0X00);
CS_H;
delay_us(16);
}
//short poll
void PS2_ShortPoll(void)
{
CS_L;
delay_us(16);
PS2_Cmd(0x01);
PS2_Cmd(0x42);
PS2_Cmd(0X00);
PS2_Cmd(0x00);
PS2_Cmd(0x00);
CS_H;
delay_us(16);
}
//进入配置
void PS2_EnterConfing(void)
{
CS_L;
delay_us(16);
PS2_Cmd(0x01);
PS2_Cmd(0x43);
PS2_Cmd(0X00);
PS2_Cmd(0x01);
PS2_Cmd(0x00);
PS2_Cmd(0X00);
PS2_Cmd(0X00);
PS2_Cmd(0X00);
PS2_Cmd(0X00);
CS_H;
delay_us(16);
}
//发送模式设置
void PS2_TurnOnAnalogMode(void)
{
CS_L;
PS2_Cmd(0x01);
PS2_Cmd(0x44);
PS2_Cmd(0X00);
PS2_Cmd(0x01); //analog=0x01;digital=0x00 软件设置发送模式
PS2_Cmd(0xEE); //Ox03锁存设置即不可通过按键“MODE”设置模式。
//0xEE不锁存软件设置可通过按键“MODE”设置模式。
PS2_Cmd(0X00);
PS2_Cmd(0X00);
PS2_Cmd(0X00);
PS2_Cmd(0X00);
CS_H;
delay_us(16);
}
//振动设置
void PS2_VibrationMode(void)
{
CS_L;
delay_us(16);
PS2_Cmd(0x01);
PS2_Cmd(0x4D);
PS2_Cmd(0X00);
PS2_Cmd(0x00);
PS2_Cmd(0X01);
CS_H;
delay_us(16);
}
//完成并保存配置
void PS2_ExitConfing(void)
{
CS_L;
delay_us(16);
PS2_Cmd(0x01);
PS2_Cmd(0x43);
PS2_Cmd(0X00);
PS2_Cmd(0x00);
PS2_Cmd(0x5A);
PS2_Cmd(0x5A);
PS2_Cmd(0x5A);
PS2_Cmd(0x5A);
PS2_Cmd(0x5A);
CS_H;
delay_us(16);
}
//手柄配置初始化
void PS2_SetInit(void)
{
PS2_ShortPoll();
PS2_ShortPoll();
PS2_ShortPoll();
PS2_EnterConfing(); //进入配置模式
PS2_TurnOnAnalogMode(); //“红绿灯”配置模式,并选择是否保存
PS2_VibrationMode(); //开启震动模式
PS2_ExitConfing(); //完成并保存配置
}