【STM32 嵌入式设计】PS2索尼游戏手柄解析和代码开发

本文介绍了如何在STM32上使用PS2索尼游戏手柄进行嵌入式设计,通过初始化IO端口,遵循PS2通讯时序,实现了手柄控制显示屏输出的功能。内容包括PS2手柄的接线方法、初始化代码、数据发送与接收的实现,并提供了读取手柄状态、摇杆值及振动功能的详细步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于PS2索尼游戏手柄开发

最近师妹拿了个PS2手柄给我

在这里插入图片描述
安排!!!!
代码下载链接
在这里插入图片描述
在32上面 成功用PS2 控制显示屏输出

PS2是一个很好学习通讯时序的的工具
这里写下他的实现代码和我的学习思路

1 2 3 4 5 6 7 8 9
DI/DAT DO/CMD NC VDD GND CS/SEL CLK NC ACK

我们不使用 NC NC ACK 这三个端口

NC:空端口;
ACK:从手柄到主机的应答信号。
此信号在每个 8bits 数据发送的最后一个周期变低
并且 CS 一直保持低电平,如
果CS 信号不变低,
约 60 微秒 PS 主机会试另一个外设。
在编程时未使用 ACK 端口。

我们接线如下
DI PB12 浮空输入 输入 数据
DO PB13 推挽输出 输出 数据

CS PB14 推挽输出 输出 数据
CLK PB15 推挽输出 输出 数据
首先是PS2 初始化 我们将IO配置成对应的模式

void PS2_Init(void)  //PB12 ÊäÈëÏÂÀ­ ÆäËûµÄÍÆÍìÊä³ö
{
   
    
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPD;
	GPIO_InitStruct.GPIO_Pin= GPIO_Pin_12;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	


	GPIO_InitStruct.GPIO_Mode= GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin= GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);	
}

然后 我们宏定义了一堆指令 为了简化我们后续的代码
这里用到了正点原子给的 sys.h 的32库

`#define DI   PBin(12)           //PB12 (DI 数据输入位)输入

#define DO_H PBout(13)=1        //令PB13 (DO 命令位/数据输出位) 输出高电平
#define DO_L PBout(13)=0        //令PB13 (DO 命令位/数据输出位)输出低电平

#define CS_H PBout(14)=1     //令PB14 (CS 使能位)输出拉高
#define CS_L PBout(14)=0     //令PB14 (CS 使能位)输出拉低

#define CLK_H PBout(15)=1      //令PB15 (CLK)输出拉高
#define CLK_L PBout(15)=0      //令PB15 (CLK)输出拉低


//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      26

//#define WHAMMY_BAR		8

//These are stick values
#define PSS_RX 5              右遥控数据
#define PSS_RY 6

#define PSS_LX 7
#define PSS_LY 8
`

再开始命令之前
我们定义一个数组存放我们要发的数据

u16 Handkey;
u8 Comd[2]={
   0x01,0x42};	
u8 Data[9]={
   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 

然后我们根据时序图设置我们要发送的代码
在这里插入图片描述
DI 是发送 DO 是接收 可以看出
DI DO 一次发送过程有8位 数据
发送的过程中 CS一直处于 低电平
而CLK是每发送一个数据 则发送出一个脉冲 (低电平——高电平)
所以我们根据时序规律写出代码

Tips:volatile是易变型变量,是防止编译器优化代码时假设这个变量的值,保证每次小心地重新读取值。

void PS2_Cmd(u8 CMD)
{
   
	volatile u16 ref=0x01;// 定义一个
	Data[1] = 0; //令数据位1 为0
	for(ref=0x01;ref<0x0100;ref<<=1) //发送一个8位的数据
	{
   
		if(ref&CMD)   //输入你要发送的数据 如果不是发送为0x00 则拉高电平 准备发送状态
			DO_H;                 
		else DO_L;   //否则拉低电平
		CLK_H;                        //每发送一个指令 给CLK一个>50us电平脉冲 
		delay_us(50);
		CLK_L;
		delay_us(50);
		CLK_H;  
		if(DI)             //如果输入得到了高电平
			Data[1] = ref|Data[1]; 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-ATAO----

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值