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手柄代码移植-合泰平台相关推荐

  1. STM32F4 高主频引起的PS2遥控手柄协议移植问题

    在STM32F103主板上运行正常的PS2手柄驱动协议,平移到STM32F405的板子上,遇到板子收不到手柄按键信号的情况.各种查找资料,各种测试之后,终于在这篇博文的启发下找到了问题.关于使用STM ...

  2. win8下cocos2dx3.2移植android平台及代码打包APK

      cocos2dx程序不能只在VS2012下运行,迟早是要搬运到Android和IOS上的.Windows下移植IOS平台先搁下不说比较困难,而且只有越狱的苹果机才可以运行,而且毕竟IOS高端.小众 ...

  3. MT6762平台NXP NFC代码移植要点

    1 找到官网,获取源码包 NXP NFC移植源码 https://github.com/NXPNFCProject 固件 https://github.com/NXP/nfc-NXPNFCC_FW/t ...

  4. 亚博智能PS2手柄学习笔记

    一.PS2 手柄介绍: PS2 由手柄与接收器两部分组成,手柄主要负责发送按键信息.都接通电源并打开手柄开关时,手柄与接收器自动配对连接(这是由于手柄与接收器之间依靠2.4G进行通信),在未配对成功的 ...

  5. 基于MPI的H.264并行编码代码移植与优化

    2010 03 25 基于MPI的H.264并行编码代码移植与优化 范 文 洛阳理工学院计算机信息工程系 洛阳 471023 摘 要 H.264获得出色压缩效果和质量的代价是压缩编码算法复杂度的增加. ...

  6. 为什么unity 安装完模块还是找不到sdk_Unity填坑笔记(四)——移植UWP平台

    0. 絮絮念 本来不想写这篇文章,一来做完这一波之后我再也不想做WSA平台--二来我觉得会做这个平台的人并不多,所以写下来意义也不大.不过在移植过程中ToLua的作者蒙哥给了我不少帮助,也说断断续续有 ...

  7. tar在linux编译为exe,将Linux代码移植到Windows的简单方法 1

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 一.前言 Linux拥有丰富各种源代码资源,但是大部分代码在Windows平台情况是无法正常编译的.Windows平台根本无法直接利用这些源代码资源.如果 ...

  8. 将Linux代码移植到Windows的简单方法

    将Linux代码移植到Windows的简单方法 一.前言 Linux拥有丰富各种源代码资源,但是大部分代码在Windows平台情况是无法正常编译的.Windows平台根本无法直接利用这些源代码资源.如 ...

  9. 将 5 万行 Java 代码移植到 Go 学到的经验

    原文地址: Lessons learned porting 50k loc from Java to Go 原文作者:Krzysztof Kowalczyk 译文出处: https://blog.ko ...

最新文章

  1. 提高mysql千万级大数据SQL查询优化30条经验(Mysql索引优化注意)
  2. K-means算法应用:压缩图片
  3. 阅读微信支付demo收获
  4. Tableau实战系列如何在 Google 云平台上安装 Tableau Server
  5. mybatis oracle trim,Mybatis trim标签
  6. 言图科技:GPU服务器选型
  7. 特征码的使用办法_小脚的美丽与哀愁,34/35码的她们都是怎么买鞋的?
  8. oracle高压水位线,Oracle 高水位线详解(HWM)
  9. windows server 2008安装wampserver后几种小问题个人总结
  10. mysql oltp_oltp数据库mysql
  11. .net Entity Framework初识1
  12. moodle 定义html文件,设置Moodle
  13. The Triple-A Supply Chain by Hau L. Lee
  14. Elasticsearch构建全文搜索系统
  15. IMFI DAO World of Balatroon:土地出售即将到来!
  16. vite-plugin-eslint缓存导致eslint一直报错的问题
  17. java gui是什么_Java GUI编程(一)
  18. realy-made and tailor-made
  19. 你为什么选择计算机这个专业英语,英文作文:为什么选择计算机作为你的专业...
  20. 2016新疆教师计算机等级考试,2019年11月7日的新疆中小学教师计算机等级..._教师资格考试_帮考网...

热门文章

  1. MongoDB可视化工具robomongo走起~
  2. 数值方法2:龙格库塔法在解微分方程中的应用
  3. Ubuntu 16.04前置音频输出没有声音
  4. CSS中p和span有什么区别
  5. java 计算百分比值
  6. html fixed垂直居中,前端垂直居中的几种简单实现
  7. hiredis linux 编译,linux下的hiredis的安装和使用
  8. 为什么采购订单管理非常重要?
  9. Linux 系统下Oracle数据库自动备份
  10. 【JavaScript】事件相关知识详解