吐槽一下
最近買了個ps2手柄,結果買家發的例程全都是好幾年前的庫函式版本,嘗試移植基本沒啥可能,雖然PS2手柄已經被開發很久了,不過我看網上用hal庫來寫控制的很少,例程也都是用庫函式寫的,因此寫篇文章來幫助剛開始接觸PS2又懶得用庫函式的同學,
SPI通信協議
提一下,方便理解代碼
這個已經被破解很久了,具體的時序就這樣,PS2手柄開啟,接收器正常作業并接受以后,資料可以通過spi通信來發送接受,然后就可以通過單片機來完成資料接收和發送,
- SPI, serial peripheral interface, 串行外圍設備介面,高速的,全雙工的,同步通信總線,有四個引腳,需要注意的是,可能有的人被串口通信坑過,于是就把主機和從機的收發介面反接,SPI通信是一一對應的連接,DO借DO,DI接DI,時鐘和CS引腳也是如此,

很明顯可以看到是一一對應,
- 連接好后,CS引腳維持高電平,通信開始時把CS電平拉低(當然你也可以反過來,平時維持低電平通信高電平)每次發送接受資料時,時鐘(CLK,SCLK等)引腳如下圖變換,此時DO和DI口開始交換資料(沿時鐘上升沿或下降沿,可以在cubemx里設定)

( 當然你也可以選擇同步接受和發送,spi是支持的)
PS2通信協議
這個網上資料也很多了,我就大概提一下,提到編程需要知道的程度,
在連接好PS2手柄和接收器以后,接收器綠燈常亮(一般可以先試試只接電源,開啟手柄,看能否配對成功),硬體沒問題的情況下就可以開始編程了,
- 首先用單片機給PS2發送一個0x01,然后PS2會給你回傳一個ID(說明此時是綠燈mode還是紅燈mode),單片機再給他發送一個0x42(請求接受資料),PS2回傳0x5a(表示可以開始傳輸資料),剩下的就是接受他的搖桿和按鍵資料了,下面這個圖可以十分精確的說明,

接受完資料以后就是處理資料,然后用在你想用的地方就好了,
配置cubemx
我這邊用的是st的nucleo-f104開發板,只要你的開發板支持SPI和串口通信就好了,
- 首先是配置時鐘,沒啥好說的,

- 配置SPI,選幾個你插著舒服的引腳就好了,
根據PS2硬體資料,這里的SPI不能亂配置,需要注意的地方如下
- 全雙工模式,主機
- 不使能硬體nss,自己多設定一個輸出引腳當CS就好
- LSB先輸出
- CPOL設定為High
- CPHA設定為第一個邊沿
- 64分頻(非常重要,PS2支持的通信頻率只有250khz,要是你單片機通信頻率過高會造成PS2只回傳給你0xff,就是一直給你拉高電平)

串口自己設定就好,能證明你正常接收到資料就行,
- 主程式非常簡單,就是上面說的先拉低CS腳,發送一個0x01,等10us,然后發送0x42,并且接收data[1],就是手柄的ID(綠燈模式是0x41),然后再發送接收,根據接收到的資料判斷哪一位按下(按下為0,否則為1),具體時序網上都有,
uint8_t cmd[3] = {0x01,0x42,0x00}; // 請求接受資料
uint8_t PS2data[9] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //存盤手柄回傳資料
void PS2_Get(void) //接受ps2資料
{
uint8_t i = 0;
HAL_GPIO_WritePin(ENABLE_GPIO_Port,ENABLE_Pin,GPIO_PIN_RESET); //拉高,開始通訊
HAL_SPI_TransmitReceive(&hspi1,&cmd[0],&PS2data[0],1,0xffff); // 發送0x01,請求接受資料
delay_us(10);
HAL_SPI_TransmitReceive(&hspi1,&cmd[1],&PS2data[1],1,0xffff); // 發送0x42,接受0x01(PS2表示開始通信)
delay_us(10);
HAL_SPI_TransmitReceive(&hspi1,&cmd[2],&PS2data[2],1,0xffff); // 發送0x00,接受ID(紅綠燈模式)
delay_us(10);
for(i = 3;i <9;i++)
{
HAL_SPI_TransmitReceive(&hspi1,&cmd[2],&PS2data[i],1,0xffff); // 接受資料
delay_us(10);
}
HAL_GPIO_WritePin(ENABLE_GPIO_Port,ENABLE_Pin,GPIO_PIN_SET); //拉低,準備下次通訊
}
這樣子就能將資料存盤在單片機里了,
資料處理
我估計反正也沒人看,就隨便提一嘴,
按鍵的話,定義存盤的結構是uint8_t,沒有按鍵按下的時候回傳值(二進制看)11111111,有一個按鍵按下時就會有對應一個1變成0,比如10111111,具體測驗一下就知道了,通過位運算就可以很簡單的把所有按鍵值提取出來,做到全按鍵無沖突,
搖桿我個人習慣時1-1000范圍均勻變化,手柄回傳的值是0-255變化,這個強制轉換也就很簡單可以完成了,建議一直開著紅燈模式,不然搖桿不回傳模擬值,調小車占空比也是這個范圍嘛,
附個一個周期正常傳輸資料的圖(邏輯分析儀)

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/392256.html
標籤:其他
上一篇:傳感網應用開發知識點總結
下一篇:AB打包策略
