1. <nobr id="easjo"><address id="easjo"></address></nobr>

      <track id="easjo"><source id="easjo"></source></track>
      1. 
        

      2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
      3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>
          貴州做網站公司
          貴州做網站公司~專業!靠譜!
          10年網站模板開發經驗,熟悉國內外開源網站程序,包括DEDECMS,WordPress,ZBlog,Discuz! 等網站程序,可為您提供網站建設,網站克隆,仿站,網頁設計,網站制作,網站推廣優化等服務。我們專注高端營銷型網站,企業官網,集團官網,自適應網站,手機網站,網絡營銷,網站優化,網站服務器環境搭建以及托管運維等。為客戶提供一站式網站解決方案?。?!

          STM32——PS2遙控手柄[通俗易懂]

          來源:互聯網轉載 時間:2023-12-14 09:44:58

          1. PS2手柄介紹

          ps2 手柄由手柄與接收器兩部分組成,手柄主要負責發送按鍵信
          息;接收器與單片機(也可叫作主機,可直接用在PS2 游戲機上)
          相連,用于接收手柄發來的信息,并傳遞給單片機,單片機也可通過
          接收器,向手柄發送命令,配置手柄的發送模式。

          2. 使用說明

          1. DI/DAT:信號流向,從手柄到主機,此信號是一個8bit 的串行數
            據,同步傳送于時鐘的下降沿。信號的讀取在時鐘由高到低的變化過
            程中完成。
          2. DO/CMD:信號流向,從主機到手柄,此信號和DI 相對,信號是
            一個8bit 的串行數據,同步傳送于時鐘的下降沿。
          3. NC:空端口;
          4. GND:電源地;
          5. VDD:接收器工作電源,電源范圍3~5V;
          6. CS/SEL:用于提供手柄觸發信號。在通訊期間,處于低電平;
          7. CLK:時鐘信號,由主機發出,用于保持數據同步;
          8. NC:空端口;
          9. ACK:從手柄到主機的應答信號。此信號在每個8bits 數據發送的
            最后一個周期變低并且CS 一直保持低電平,如果CS 信號不變低,
            約60 微秒PS 主機會試另一個外設。在編程時未使用ACK 端口。


          時鐘頻率250KHz(4us),如果接收數據不穩定,可以適當的增加頻率。在通訊過程中,一串數據通訊完成后CS 才會由低轉高,不是1 個字節通訊完成后就由低轉高,在通訊期間,一直處于低電平。在時鐘下降沿時,完成數據(1bit)的發送與接收,發送和接收是同時完成的。當單片機想讀手柄數據或向手柄發送命令時,將會拉低CS 線電平,并發出一個命令“0x01”;手柄會回復它的ID“0x41=綠燈模式,0x73=紅燈模式”;在手柄發送ID 的同時,單片機將傳送0x42,請求數據;隨后手柄發送出0x5A,告訴單片機“數據來了”。

          idle:數據線空閑,該數據線無數據傳送。
          一個通訊周期有9 個字節(8 位),這些數據是依次按位傳送。

          當有按鍵按下,對應位為“0”,其他位為“1”,例如當鍵“SELECT”被按下時,Data[3]=11111110B。

          3. STM32F1例程

          需自己根據實際情況修改IO口

          #.c文件
          #include "pstwo.h"
          /********************************************************* **********************************************************/	 
          #define DELAY_TIME delay_us(5); 
          float PS2_LX,PS2_LY,PS2_RX,PS2_RY,PS2_KEY;         //PS2相關變量
          u16 Handkey;	// 按鍵值讀取,零時存儲。
          u8 Comd[2]={ 
          0x01,0x42};	//開始命令。請求數據
          u8 Data[9]={ 
          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //數據存儲數組
          u16 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
          };	
          /************************************************************************** 函數功能:PS2手柄初始化 入口參數:無 返回 值:無 **************************************************************************/	
          void PS2_Init(void)
          { 
          
          GPIO_InitTypeDef GPIO_InitStructure;
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOB, ENABLE); //使能端口時鐘
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;	            //端口配置
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //上拉輸入
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //50M
          GPIO_Init(GPIOD, &GPIO_InitStructure);					      //根據設定參數初始化GPIOD
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;	//端口配置
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;     // inpuT
          GPIO_Init(GPIOE, &GPIO_InitStructure);					      //根據設定參數初始化GPIOE
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13;	//端口配置
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      //
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //50M
          GPIO_Init(GPIOB, &GPIO_InitStructure);					      //根據設定參數初始化GPIOE
          }
          /************************************************************************** 函數功能:向手柄發送命令 入口參數:CMD指令 返回 值:無 **************************************************************************/
          void PS2_Cmd(u8 CMD)
          { 
          
          volatile u16 ref=0x01;
          Data[1] = 0;
          for(ref=0x01;ref<0x0100;ref<<=1)
          { 
          
          if(ref&CMD)
          { 
          
          DO_H;                   //輸出一位控制位
          }
          else DO_L;
          CLK_H;                        //時鐘拉高
          DELAY_TIME;
          CLK_L;
          DELAY_TIME;
          CLK_H;
          if(DI)
          Data[1] = ref|Data[1];
          }
          delay_us(16);
          }
          /************************************************************************** 函數功能:判斷是否為紅燈模式,0x41=模擬綠燈,0x73=模擬紅燈 入口參數:CMD指令 返回 值:0,紅燈模式 其他,其他模式 **************************************************************************/
          u8 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 u8 byte=0;
          volatile u16 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;
          DELAY_TIME;
          CLK_L;
          DELAY_TIME;
          CLK_H;
          if(DI)
          Data[byte] = ref|Data[byte];
          }
          delay_us(16);
          }
          CS_H;
          }
          /************************************************************************** 函數功能:對讀出來的PS2的數據進行處理,只處理按鍵部分 入口參數:CMD指令 返回 值:無 //只有一個按鍵按下時按下為0, 未按下為1 **************************************************************************/
          u8 PS2_DataKey()
          { 
          
          u8 index;
          PS2_ClearData();
          PS2_ReadData();
          Handkey=(Data[4]<<8)|Data[3];     //這是16個按鍵 按下為0, 未按下為1
          for(index=0;index<16;index++)
          { 
          	    
          if((Handkey&(1<<(MASK[index]-1)))==0)
          return index+1;
          }
          return 0;          //沒有任何按鍵按下
          }
          /************************************************************************** 函數功能:向手柄發送命令 入口參數:得到一個搖桿的模擬量 范圍0~256 返回 值:無 **************************************************************************/
          u8 PS2_AnologData(u8 button)
          { 
          
          return Data[button];
          }
          //清除數據緩沖區
          void PS2_ClearData()
          { 
          
          u8 a;
          for(a=0;a<9;a++)
          Data[a]=0x00;
          }
          /****************************************************** 函數功能: 手柄震動函數, Calls: void PS2_Cmd(u8 CMD); 入口參數: motor1:右側小震動電機 0x00關,其他開 motor2:左側大震動電機 0x40~0xFF 電機開,值越大 震動越大 返回 值:無 ******************************************************/
          void PS2_Vibration(u8 motor1, u8 motor2)
          { 
          
          CS_L;
          delay_us(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;
          delay_us(16);  
          }
          /************************************************************************** 函數功能:short poll 入口參數:無 返回 值:無 **************************************************************************/
          void PS2_ShortPoll(void)
          { 
          
          CS_L;
          delay_us(16);
          PS2_Cmd(0x01);  
          PS2_Cmd(0x42);  
          PS2_Cmd(0X00);
          PS2_Cmd(0x00);
          PS2_Cmd(0x00);
          CS_H;
          delay_us(16);	
          }
          /************************************************************************** 函數功能:進入配置 入口參數:無 返回 值:無 **************************************************************************/
          void PS2_EnterConfing(void)
          { 
          
          CS_L;
          delay_us(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;
          delay_us(16);
          }
          /************************************************************************** 函數功能:發送模式設置 入口參數:無 返回 值:無 **************************************************************************/
          void PS2_TurnOnAnalogMode(void)
          { 
          
          CS_L;
          PS2_Cmd(0x01);  
          PS2_Cmd(0x44);  
          PS2_Cmd(0X00);
          PS2_Cmd(0x01); //analog=0x01;digital=0x00 軟件設置發送模式
          PS2_Cmd(0x03); //Ox03鎖存設置,即不可通過按鍵“MODE”設置模式。
          //0xEE不鎖存軟件設置,可通過按鍵“MODE”設置模式。
          PS2_Cmd(0X00);
          PS2_Cmd(0X00);
          PS2_Cmd(0X00);
          PS2_Cmd(0X00);
          CS_H;
          delay_us(16);
          }
          /************************************************************************** 函數功能:振動設置 入口參數:無 返回 值:無 **************************************************************************/
          void PS2_VibrationMode(void)
          { 
          
          CS_L;
          delay_us(16);
          PS2_Cmd(0x01);  
          PS2_Cmd(0x4D);  
          PS2_Cmd(0X00);
          PS2_Cmd(0x00);
          PS2_Cmd(0X01);
          CS_H;
          delay_us(16);	
          }
          /************************************************************************** 函數功能:完成并保存配置 入口參數:無 返回 值:無 **************************************************************************/
          void PS2_ExitConfing(void)
          { 
          
          CS_L;
          delay_us(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;
          delay_us(16);
          }
          /************************************************************************** 函數功能:手柄配置初始化 入口參數:無 返回 值:無 **************************************************************************/
          void PS2_SetInit(void)
          { 
          
          PS2_ShortPoll();
          PS2_ShortPoll();
          PS2_ShortPoll();
          PS2_EnterConfing();		//進入配置模式
          PS2_TurnOnAnalogMode();	//“紅綠燈”配置模式,并選擇是否保存
          //PS2_VibrationMode(); //開啟震動模式
          PS2_ExitConfing();		//完成并保存配置
          }
          /************************************************************************** 函數功能:讀取PS2手柄的控制量 入口參數:無 返回 值:無 **************************************************************************/	
          void PS2_Read(void)
          { 
          
          static int Start, count=0;
          PS2_KEY=PS2_DataKey();          //讀取按鍵鍵值
          PS2_LX=PS2_AnologData(PSS_LX);  //讀取左邊遙感X軸方向的模擬量
          PS2_LY=PS2_AnologData(PSS_LY);  //讀取左邊遙感Y軸方向的模擬量
          PS2_RX=PS2_AnologData(PSS_RX);  //讀取右邊遙感X軸方向的模擬量
          PS2_RY=PS2_AnologData(PSS_RY);  //讀取右邊遙感Y軸方向的模擬量
          }
          
          #.h文件
          #ifndef __PSTWO_H
          #define __PSTWO_H
          #include "delay.h"
          #include "sys.h"
          #include "init.h"
          /********************************************************* **********************************************************/	 
          #define DI PEin(15) // 輸入引腳
          #define DO_H PDout(3)=1 //命令位高
          #define DO_L PDout(3)=0 //命令位低
          #define CS_H PBout(13)=1 //CS拉高
          #define CS_L PBout(13)=0 //CS拉低
          #define CLK_H PBout(12)=1 //時鐘拉高
          #define CLK_L PBout(12)=0 //時鐘拉低
          //手柄接口初始化 輸入 DI->PA0 
          // 輸出 DO->PA1 CS->PA2 CLK->PA3
          //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 8
          extern u8 Data[9];
          extern u16 MASK[16];
          extern u16 Handkey;
          extern float PS2_LX,PS2_LY,PS2_RX,PS2_RY,PS2_KEY;         //PS2相關變量
          void PS2_Init(void);
          u8 PS2_RedLight(void);   //判斷是否為紅燈模式
          void PS2_ReadData(void); //讀手柄數據
          void PS2_Cmd(u8 CMD);		  //向手柄發送命令
          u8 PS2_DataKey(void);		  //按鍵值讀取
          u8 PS2_AnologData(u8 button); //得到一個搖桿的模擬量
          void PS2_ClearData(void);	  //清除數據緩沖區
          void PS2_Vibration(u8 motor1, u8 motor2);//振動設置motor1 0xFF開,其他關,motor2 0x40~0xFF
          void PS2_EnterConfing(void);	 //進入配置
          void PS2_TurnOnAnalogMode(void); //發送模擬量
          void PS2_VibrationMode(void);    //振動設置
          void PS2_ExitConfing(void);	     //完成配置
          void PS2_SetInit(void);		     //配置初始化
          void PS2_Read(void);  //讀取PS2手柄的控制量
          #endif
          

          網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...

          在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...

          在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...

          華縣隸屬安陽市。1.河南省直管縣華縣位于河南省北部,與濮陽、安陽、鶴壁、新鄉接壤。南距鄭州130公里,北距安陽70公里,東北距濮陽53公里,西南距新鄉70公里。2.滑縣位于河南省北部平原,隸屬安陽市。目前是省直管縣,與濮陽、演金、??h、長垣、封丘、內黃接壤。北距安陽70km,東北距濮陽53km,西南距新鄉70km,西北距鶴壁新城25km。河南的滑縣屬于哪個市?河南省直管縣滑縣?;h是河南省直屬縣,...

          縱觀LOL歷屆S系列賽,哪一屆奪冠的含金量最高?哪一屆又最低?S1來自歐洲的FNC。當時隊伍不多。S2來自臺灣的TPA,在勝利面前擊敗熱火,急于奪冠。來自韓國的S3 SKT,faker的首次亮相是巔峰。魔王用他可怕的行動殺戮并將刀子壓在繩子上完成了統治之路?;始襆PL獲得第二名。來自韓國SSW的S4,前四名擊潰兄弟隊SSB,奪冠勢不可擋。LPL王室再次失利,獲得第二名。三星解散后,三星世子進入LP...

          excle表格如何查找重復姓名?在excel表格中,通過在條件格式中突出顯示單元規則,可以找出重復的名稱。這里以excel 2013版本為例。具體方法如下:1.首先,在電腦上打開要找出重名的Excel表格。2.然后選擇頁面頂部的條件格式。3.接下來,單擊突出顯示單元格規則。4.進入高亮顯示的單元格規則頁面后,選擇復制項目。5.然后在彈出的頁面中選擇【確定】,在excwps怎么搜索人名?在wps表中...

          TOP
          国产初高中生视频在线观看|亚洲一区中文|久久亚洲欧美国产精品|黄色网站入口免费进人
          1. <nobr id="easjo"><address id="easjo"></address></nobr>

              <track id="easjo"><source id="easjo"></source></track>
              1. 
                

              2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
              3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>