PS2手柄代码移植-合泰平台
PS2手柄代码移植-合泰平台
1、PS2手柄端口及通讯协议
PS2手柄的通讯协议是SPI协议是一种高速的、全双工、同步的通信总线,并且在芯片的管脚上只占用四根线(DI、DO、CS、CLK),PS2手柄的通讯协议破解后在C51、STM32、Arduino、FPGA等平台上均有应用,其端口、通讯协议及使用方法的介绍在网上一搜一大堆,大家自行下载即可。
博主本科期间由于项目需求,需要在合泰芯片上实现ps2手柄控制的代码。于是将ps2的代码从别的平台上移植到合泰芯片平台上,具体型号为合泰HT66F70A(好像是开发板型号,不一定是芯片型号),如今整理出来,希望能帮助到有需要的朋友。
2、移植代码:文件主要包括三份:ps2.c、ps2.h、main.c
ps2.c
#include "PS2.h"
#include "HT66F70A.h"//全局变量区
unsigned short int Handkey;
unsigned char Comd[2] = {0x01,0x42};//开始命令。请求数据
unsigned char Data[9] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //数据存储数组
unsigned short int 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->PB2_pcc4 = 1;//PB12设置成输入 默认下拉 _pcpu4 = 0;//DO->PB3 CS->PB4 CLK->PB5_pcc5 = 0;//PB3、PB4、PB5 推挽输出_pcc6 = 0;_pcc7 = 0;_pcpu5 = 0;_pcpu6 = 0;_pcpu7 = 0;
}void PS2_Cmd(unsigned char CMD)
{volatile unsigned short int ref = 0x01;Data[1] = 0;for(ref=0x01;ref<0x0100;ref<<=1){if(ref&CMD){DO_H; //输出以为控制位}else DO_L;CLK_H; //时钟拉高GCC_DELAY(5);//delay_us(50);CLK_L;GCC_DELAY(5);//delay_us(50);CLK_H;if(DI)Data[1] = ref|Data[1];}GCC_DELAY(16);
} //判断是否为红灯模式
//返回值;0,红灯模式
// 其他,其他模式
unsigned char PS2_RedLight(void)
{CS_L;PS2_Cmd(Comd[0]); //开始命令PS2_Cmd(Comd[1]); //请求数据CS_H;if( Data[1] == 0X73) return 0 ;else return 1;
}//读取手柄数据
void PS2_ReadData(void)
{volatile unsigned char byte=0;volatile unsigned short int 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;GCC_DELAY(5);CLK_L;GCC_DELAY(5);//delay_us(50);CLK_H;if(DI)Data[byte] = ref|Data[byte];}GCC_DELAY(16);//delay_us(16);}CS_H; }//对读出来的PS2的数据进行处理 只处理了按键部分 默认数据是红灯模式 只有一个按键按下时
//按下为0, 未按下为1
unsigned char PS2_DataKey(void)
{unsigned char index;PS2_ClearData();PS2_ClearData();PS2_ReadData();Handkey=(Data[4]<<8)|Data[3]; //这是16个按键 按下为0, 未按下为1for(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;
}//short poll
void PS2_ShortPoll(void)
{CS_L;GCC_DELAY(16);//delay_us(16);PS2_Cmd(0x01);PS2_Cmd(0x42);PS2_Cmd(0x00);PS2_Cmd(0x00);PS2_Cmd(0x00);CS_H;GCC_DELAY(16);
}//进入配置
void PS2_EnterConfig(void)
{CS_L;GCC_DELAY(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;GCC_DELAY(16);
}//发送模式设置
void PS2_TurnOnAnalogMode(void)
{CS_L;//GCC_DELAY(16);PS2_Cmd(0x01);PS2_Cmd(0x44);PS2_Cmd(0x00);PS2_Cmd(0x01);//analog=0x01;digital=0x00 软件设置发送模式PS2_Cmd(0xEE);//0x03锁存设置,即不可通过按键"MODE"设置模式//0xEE不锁存软件设置,可通过按键"MODE"设置模式PS2_Cmd(0x00);PS2_Cmd(0x00);PS2_Cmd(0x00);PS2_Cmd(0x00);CS_H;GCC_DELAY(16);
}//震动设置
void PS2_VibrationMode(void)
{CS_L;GCC_DELAY(16);PS2_Cmd(0x01);PS2_Cmd(0x4D);PS2_Cmd(0x00);PS2_Cmd(0x00);PS2_Cmd(0x01);CS_H;GCC_DELAY(16);
}//完成并保存配置
void PS2_ExitConfig(void)
{CS_L;GCC_DELAY(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;GCC_DELAY(16);
}//手柄配置初始化
void PS2_SetInit(void)
{PS2_ShortPoll();PS2_ShortPoll();PS2_ShortPoll();PS2_EnterConfig();//进入配置模式PS2_TurnOnAnalogMode();//"红绿灯"配置模式,并选择是否保存PS2_VibrationMode();//开启震动模式PS2_ExitConfig();//完成并保存配置
}//只有PS2_VibrationMode();开启之后可用
//motor1:右侧小振动电机 0x00关,其他开
//motor2:左侧大震动电机 0x40~0xFF 电机开,值越大,震动越大
void PS2_Vibration(unsigned char motor1,unsigned char motor2)
{CS_L;GCC_DELAY(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;GCC_DELAY(16);
}
ps2.h
#ifndef _PS2_H_
#define _PS2_H_#define DI _pc4 //PB2 输入
#define DO_H _pc5=1 //命令位高
#define DO_L _pc5=0 //命令位低
#define CS_H _pc6=1 //CS拉高
#define CS_L _pc6=0 //CS拉低
#define CLK_H _pc7=1 //时钟拉高
#define CLK_L _pc7=0 //时钟拉低//These are our button constants
#define PSB_SELECT 1
#define PSB_L3 2
#define PSB_R3 3
#define PSB_START 4
#define PSB_PAD_UP 5
#define PSB_PAD_RIGHT 6
#define PSB_PAD_DOWN 7
#define PSB_PAD_LEFT 8
#define PSB_L2 9
#define PSB_R2 10
#define PSB_L1 11
#define PSB_R1 12
#define PSB_GREEN 13
#define PSB_RED 14
#define PSB_BLUE 15
#define PSB_PINK 16
#define PSB_TRIANGLE 13
#define PSB_CIRCLE 14
#define PSB_CROSS 15
#define PSB_SQUARE 16
//#define WHAMMY_BAR 8//These are stick values
#define PSS_RX 5 //右摇杆X轴数据
#define PSS_RY 6
#define PSS_LX 7
#define PSS_LY 8extern unsigned char Data[9];
extern unsigned short int MASK[16];
extern unsigned short int Handkey;void PS2_INIT(void);//PS2初始化
unsigned char PS2_RedLight(void);//判断是否为红灯模式
void PS2_ReadData(void);//
void PS2_Cmd(unsigned char CMD);//
unsigned char PS2_DataKey(void);//键值读取
unsigned char PS2_AnologData(unsigned char button); //得到一个摇杆的模拟量
void PS2_ClearData(void);//清除数据缓冲区
void PS2_ShortPoll(void);//short poll
void PS2_EnterConfig(void);//进入配置
void PS2_TurnOnAnalogMode(void);//发送模式设置
void PS2_VibrationMode(void);//震动设置
void PS2_ExitConfig(void);//完成并保存配置
void PS2_SetInit(void);//手柄配置初始化
void PS2_Vibration(unsigned char motor1,unsigned char motor2);//#endif
main.c
#include "HT66F70A.h"
#include "Interrupt.h"
#include "TM.h"
#include "UART.h"
#include "PS2.h"
#include "Motor.h"//全局变量区
extern char buff[num];
extern char Buff[32];
extern unsigned int count;//函数声明区
void delay1s(void);//主程序入口
void main()
{//初始化区_wdtc = 0xab;//看门狗失能unsigned char key;UART_INIT();PS2_INIT();MOTOR_INIT();//TO DO while(1){key = PS2_DataKey(); GCC_DELAY(16); switch(key){case 1:GCC_DELAY(2000); if((key = PS2_DataKey()) == 1) Send( "1\r\n"); break;case 2:GCC_DELAY(2000); if((key = PS2_DataKey()) == 2) Send( "2\r\n");break;case 3:GCC_DELAY(2000); if((key = PS2_DataKey()) == 3) Send( "3\r\n");break;case 4:GCC_DELAY(2000); if((key = PS2_DataKey()) == 4) Send( "4\r\n");break;case 5:GCC_DELAY(2000); if((key = PS2_DataKey()) == 5) Send( "5\r\n");Motor(1,1,300);break;case 6:GCC_DELAY(2000); if((key = PS2_DataKey()) == 6) Send( "6\r\n");Motor(1,1,300);break;case 7:GCC_DELAY(2000); if((key = PS2_DataKey()) == 7) Send( "7\r\n");Motor(1,1,1000);break;case 8:GCC_DELAY(2000); if((key = PS2_DataKey()) == 8) Send( "8\r\n");Motor(1,0,1000);break;case 9:GCC_DELAY(2000); if((key = PS2_DataKey()) == 9) Send( "9\r\n");break;case 10:GCC_DELAY(2000); if((key = PS2_DataKey()) == 10) Send("10\r\n");break;case 11:GCC_DELAY(2000); if((key = PS2_DataKey()) == 11) Send("11\r\n");break;case 12:GCC_DELAY(2000); if((key = PS2_DataKey()) == 12) Send("12\r\n");break;case 13:GCC_DELAY(2000); if((key = PS2_DataKey()) == 13) Send("13\r\n");break;case 14:GCC_DELAY(2000); if((key = PS2_DataKey()) == 14) Send("14\r\n");break;case 15:GCC_DELAY(2000); if((key = PS2_DataKey()) == 15) Send("15\r\n");break;case 16:GCC_DELAY(2000); if((key = PS2_DataKey()) == 16) Send("16\r\n");Motor_Stop(1);break;default:break;}} }void delay1s(void) //误差 -1us
{unsigned char a,b,c,n;for(c=205;c>0;c--)for(b=171;b>0;b--)for(a=8;a>0;a--);for(n=1;n>0;n--);
}
PS2手柄代码移植-合泰平台相关推荐
- STM32F4 高主频引起的PS2遥控手柄协议移植问题
在STM32F103主板上运行正常的PS2手柄驱动协议,平移到STM32F405的板子上,遇到板子收不到手柄按键信号的情况.各种查找资料,各种测试之后,终于在这篇博文的启发下找到了问题.关于使用STM ...
- win8下cocos2dx3.2移植android平台及代码打包APK
cocos2dx程序不能只在VS2012下运行,迟早是要搬运到Android和IOS上的.Windows下移植IOS平台先搁下不说比较困难,而且只有越狱的苹果机才可以运行,而且毕竟IOS高端.小众 ...
- MT6762平台NXP NFC代码移植要点
1 找到官网,获取源码包 NXP NFC移植源码 https://github.com/NXPNFCProject 固件 https://github.com/NXP/nfc-NXPNFCC_FW/t ...
- 亚博智能PS2手柄学习笔记
一.PS2 手柄介绍: PS2 由手柄与接收器两部分组成,手柄主要负责发送按键信息.都接通电源并打开手柄开关时,手柄与接收器自动配对连接(这是由于手柄与接收器之间依靠2.4G进行通信),在未配对成功的 ...
- 基于MPI的H.264并行编码代码移植与优化
2010 03 25 基于MPI的H.264并行编码代码移植与优化 范 文 洛阳理工学院计算机信息工程系 洛阳 471023 摘 要 H.264获得出色压缩效果和质量的代价是压缩编码算法复杂度的增加. ...
- 为什么unity 安装完模块还是找不到sdk_Unity填坑笔记(四)——移植UWP平台
0. 絮絮念 本来不想写这篇文章,一来做完这一波之后我再也不想做WSA平台--二来我觉得会做这个平台的人并不多,所以写下来意义也不大.不过在移植过程中ToLua的作者蒙哥给了我不少帮助,也说断断续续有 ...
- tar在linux编译为exe,将Linux代码移植到Windows的简单方法 1
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 一.前言 Linux拥有丰富各种源代码资源,但是大部分代码在Windows平台情况是无法正常编译的.Windows平台根本无法直接利用这些源代码资源.如果 ...
- 将Linux代码移植到Windows的简单方法
将Linux代码移植到Windows的简单方法 一.前言 Linux拥有丰富各种源代码资源,但是大部分代码在Windows平台情况是无法正常编译的.Windows平台根本无法直接利用这些源代码资源.如 ...
- 将 5 万行 Java 代码移植到 Go 学到的经验
原文地址: Lessons learned porting 50k loc from Java to Go 原文作者:Krzysztof Kowalczyk 译文出处: https://blog.ko ...
最新文章
- 提高mysql千万级大数据SQL查询优化30条经验(Mysql索引优化注意)
- K-means算法应用:压缩图片
- 阅读微信支付demo收获
- Tableau实战系列如何在 Google 云平台上安装 Tableau Server
- mybatis oracle trim,Mybatis trim标签
- 言图科技:GPU服务器选型
- 特征码的使用办法_小脚的美丽与哀愁,34/35码的她们都是怎么买鞋的?
- oracle高压水位线,Oracle 高水位线详解(HWM)
- windows server 2008安装wampserver后几种小问题个人总结
- mysql oltp_oltp数据库mysql
- .net Entity Framework初识1
- moodle 定义html文件,设置Moodle
- The Triple-A Supply Chain by Hau L. Lee
- Elasticsearch构建全文搜索系统
- IMFI DAO World of Balatroon:土地出售即将到来!
- vite-plugin-eslint缓存导致eslint一直报错的问题
- java gui是什么_Java GUI编程(一)
- realy-made and tailor-made
- 你为什么选择计算机这个专业英语,英文作文:为什么选择计算机作为你的专业...
- 2016新疆教师计算机等级考试,2019年11月7日的新疆中小学教师计算机等级..._教师资格考试_帮考网...