STM32 F411RE Nucleo SPI支持和编程PlayStation2控制器

时间:2017-05-19 21:02:46

标签: c stm32 stm32f4

欢迎。有几天我试图从STM32F411RE核上的PS2 PAD得到正确的答案。 我使用SPI和USART接收消息。 时钟频率设置为8MHz,采用SPI预分频器64配置,可提供125KHz(或KBits / s)。 第一位取自LSB,CPOL参数取为1,CPHA取自2. NSS软件控制,设置为GPIO输出(PA4-CS引脚)。我使用PA5引脚作为SCK(时钟)PA6-MISO,PA7-MOSI。 SPI设置为全双工主模式。 (USART异步和9600Bits / s,但它只是用于在PC上接收消息)。 我想补充说微控制器在HAL库上运行。 在main.c文件中:

#define CS_LOW HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET)
#define CS_HIGH HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET)

CS LOW - 将“注意”行设置为状态0,将CS_HIGH设置为状态1。 Functinon发送命令和返回数据(MISO-MOSI):

uint8_t PS2_RWByte(uint8_t komenda, uint8_t tablica, int wielkosc)
   {
     HAL_SPI_Transmit(&hspi1, &komenda, sizeof(komenda), 1);
     HAL_SPI_Receive(&hspi1, &tablica, sizeof(tablica), 1);
    return(tablica);
   }

发送字节串的函数:

uint8_t Get_PS2Dat(uint8_t buf[])
{
   CS_LOW;
   HAL_Delay(15/1000);
   buf[0]=PS2_RWByte(0x01, buf[0], 8);HAL_Delay(15/1000);
   buf[1]=PS2_RWByte(0x42, buf[1], 8);HAL_Delay(15/1000);
   buf[2]=PS2_RWByte(0x00, buf[2], 8);HAL_Delay(15/1000);
   buf[3]=PS2_RWByte(0x00, buf[3], 8);HAL_Delay(15/1000);
   buf[4]=PS2_RWByte(0x00, buf[4], 8);HAL_Delay(15/1000);
   buf[5]=PS2_RWByte(0x00, buf[5], 8);HAL_Delay(15/1000);
   buf[6]=PS2_RWByte(0x00, buf[6], 8);HAL_Delay(15/1000);
   buf[7]=PS2_RWByte(0x00, buf[7], 8);HAL_Delay(15/1000);
   buf[8]=PS2_RWByte(0x00, buf[8], 8);HAL_Delay(15/1000);
   CS_HIGH;
   if((buf[0]==0xff)&&(buf[1]==0x41)&&(buf[2]==0x5a))
   return 1;
   if((buf[0]==0xff)&&(buf[1]==0x73)&&(buf[2]==0x5a))
   return 2;
   return 0;
   }

在主要功能中:

int main(void){
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_SPI1_Init();
HAL_SPI_MspInit(&hspi1);
uint8_t PS2buf[10]={0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t wyswietl[30]={0};
while (1)
{Get_PS2Dat(PS2buf);
     for(int i=0;i<9;i++)
     {
     sprintf(wyswietl,"%u ,",PS2buf[i]);
     HAL_UART_Transmit(&huart2,wyswietl,30,250);
     }
 sprintf(wyswietl,"\n\r");
 HAL_UART_Transmit(&huart2,wyswietl,30,250);
 HAL_Delay(300);
 }
 }

发送信息后:0x01 0x42 0x00 0x00 0x00如果没有按下按钮,我应该得到0xFF 0x41 0x5A 0xFF 0xFF。当我得到这样的值时,3和4字节应该出现有关按下的键的信息: 65,255,255,255,255即0xFF 0xFF 0xFF 0xFF 0xFF。奇怪的是,第二个发送字节对应于第一个接收到的字节。另外一点是,如果按“模式”键,值65将更改为115(0x73),而其他值仍保持不变。 我提供了支持页面的链接:

PlayStation 2 Controller Interface

我还要补充一点就是这个PAD:

Link to page

也许有人提出了一些想法。请帮我。 :)

2 个答案:

答案 0 :(得分:2)

您应该使用HAL_SPI_TransmitReceive而不是HAL_SPI_Transmit和HAL_SPI_Receive的组合。

  • 函数HAL_SPI_Transmit仅发送数据并省略传入的字节。
  • 函数HAL_SPI_Receive发送虚拟数据并获取传入的字节。

所以基本上你收到的是每一个第二个角色。 65 = 0x42是第二个字符。因为您在接收数据时发送一个虚拟字节,所以ps2控制器无法理解剩余的消息,所以你得到0xFF。

更改你的PS2_RWByte功能,它应该可以工作:

uint8_t PS2_RWByte(uint8_t komenda, uint8_t tablica, int wielkosc)
{
  HAL_SPI_TransmitReceive(&hspi1, &komenda, &tablica, sizeof(uint8_t), 1);
  return(tablica);
}

答案 1 :(得分:0)

我不熟悉ps2 pad,但我相信你必须在你的spi-receive之后将NSS引脚设置回高位。 (所以你需要在每次写作之前设置为低......)