基于stm32的ps2手柄代码
时间: 2023-09-17 11:15:08 浏览: 77
以下是基于STM32的PS2手柄代码,其中使用了SPI和定时器来读取和解析手柄数据:
```c
#include "stm32f10x.h"
#define SPI_CS_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_4)
#define SPI_CS_HIGH() GPIO_SetBits(GPIOA, GPIO_Pin_4)
#define PS2_CMD_ENTER_CFG 0x01
#define PS2_CMD_EXIT_CFG 0x81
#define PS2_CMD_ENABLE 0x43
#define PS2_CMD_SET_MODE 0x44
#define PS2_CMD_POLL 0x01
#define PS2_MODE_ANALOG 0x01
#define PS2_MODE_DIGITAL 0x00
#define PS2_ACKNOWLEDGE 0x00
#define PS2_COMPLETE 0x01
#define PS2_ERROR 0x02
#define PS2_BUTTON_SELECT 0x0001
#define PS2_BUTTON_L3 0x0002
#define PS2_BUTTON_R3 0x0004
#define PS2_BUTTON_START 0x0008
#define PS2_BUTTON_UP 0x0010
#define PS2_BUTTON_RIGHT 0x0020
#define PS2_BUTTON_DOWN 0x0040
#define PS2_BUTTON_LEFT 0x0080
#define PS2_BUTTON_L2 0x0100
#define PS2_BUTTON_R2 0x0200
#define PS2_BUTTON_L1 0x0400
#define PS2_BUTTON_R1 0x0800
#define PS2_BUTTON_TRIANGLE 0x1000
#define PS2_BUTTON_CIRCLE 0x2000
#define PS2_BUTTON_CROSS 0x4000
#define PS2_BUTTON_SQUARE 0x8000
uint8_t PS2_Cmd(uint8_t cmd);
void PS2_Init(void);
void PS2_ReadData(void);
void PS2_SetMode(uint8_t mode);
void PS2_EnterCfg(void);
void PS2_ExitCfg(void);
void PS2_Enable(void);
uint16_t PS2_Buffer;
uint8_t PS2_Ready = 0;
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI1, &SPI_InitStructure);
TIM_TimeBase_InitStructure.TIM_Period = 9999;
TIM_TimeBase_InitStructure.TIM_Prescaler = 71;
TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM4, &TIM_TimeBase_InitStructure);
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM4, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
PS2_Init();
while (1)
{
if (PS2_Ready)
{
// 处理手柄数据
PS2_Ready = 0;
}
}
}
void PS2_Init(void)
{
PS2_EnterCfg();
PS2_Cmd(PS2_CMD_SET_MODE);
PS2_Cmd(PS2_MODE_ANALOG);
PS2_ExitCfg();
PS2_Enable();
}
uint8_t PS2_Cmd(uint8_t cmd)
{
uint8_t i, ack;
SPI_CS_LOW();
SPI_I2S_SendData(SPI1, cmd);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
ack = SPI_I2S_ReceiveData(SPI1);
SPI_CS_HIGH();
for (i = 0; i < 10; i++);
return ack;
}
void PS2_EnterCfg(void)
{
PS2_Cmd(PS2_CMD_ENTER_CFG);
}
void PS2_ExitCfg(void)
{
PS2_Cmd(PS2_CMD_EXIT_CFG);
}
void PS2_Enable(void)
{
PS2_Cmd(PS2_CMD_ENABLE);
}
void PS2_SetMode(uint8_t mode)
{
PS2_Cmd(PS2_CMD_SET_MODE);
PS2_Cmd(mode);
}
void PS2_ReadData(void)
{
static uint8_t ps2_data[9];
static uint8_t byte_count = 0;
uint8_t byte, i;
GPIO_ResetBits(GPIOA, GPIO_Pin_4);
SPI_I2S_SendData(SPI1, PS2_CMD_POLL);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
byte = SPI_I2S_ReceiveData(SPI1);
ps2_data[byte_count] = byte;
byte_count++;
if (byte_count == 9)
{
byte_count = 0;
if (ps2_data[0] == 0x01 && ps2_data[1] == 0x42 && ps2_data[2] == 0x5a)
{
PS2_Buffer = 0;
for (i = 2; i < 8; i++)
{
PS2_Buffer <<= 8;
PS2_Buffer |= ps2_data[i];
}
PS2_Ready = 1;
}
}
GPIO_SetBits(GPIOA, GPIO_Pin_4);
}
void TIM4_IRQHandler(void)
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
PS2_ReadData();
}
}
```
其中,PS2_Init()函数用于初始化手柄,PS2_ReadData()函数用于读取手柄数据。在主函数中,通过检测PS2_Ready是否为1来判断是否有新的手柄数据可用。可以根据PS2_Buffer中的值来判断手柄按键状态。
阅读全文