索尼的 PS2游戲手柄, 通過上下左右4個按鍵來控制 單片機的4個燈亮滅。 同時 也可以控制 游戲手柄的震動
V94M2(M[NWI7M1FISDB$$~Q.png (45.25 KB, 下載次數: 50)
下載附件
串口打印
2018-8-30 20:44 上傳
0.jpg (57.53 KB, 下載次數: 54)
下載附件
2018-8-30 23:03 上傳
源程序如下:
- # include "public.h"
- # include "printf.h"
- # include "systick.h"
- # include "ps2.h"
- # include "led.h"
- int main()
- {
- u8 key;
- LED_Init();
- printf_init(); //printf串口初始化
- PS2_Init();
- led_display();
- //PS2_SetInit(); //配配置初始化,配置“紅綠燈模式”,并選擇是否可以修改
- //開啟震動模式
- printf(" 已開啟游戲手柄\r\n");
- /*
- while(1)
- {
- key=PS2_DataKey();
- if(key!=0) //有按鍵按下
- {
- printf(" \r\n %d is light \r\n",Data[1]);//ID
- printf(" \r\n %d is pressed \r\n",key);
- if(key == 11)
- {
- PS2_Vibration(0xFF,0x00); //發出震動后必須有延時 delay_ms(1000);
- delay_ms(500);
- }
- else if(key == 12)
- {
- PS2_Vibration(0x00,0xFF); //發出震動后必須有延時 delay_ms(1000);
- delay_ms(500);
- }
- else
- PS2_Vibration(0x00,0x00);
- }
- printf(" %5d %5d %5d %5d\r\n",PS2_AnologData(PSS_LX),PS2_AnologData(PSS_LY),
- PS2_AnologData(PSS_RX),PS2_AnologData(PSS_RY) );
- delay_ms(60000);
- }
- */
- while (1)
- {
- key=PS2_DataKey();
- if(key!=0) //有按鍵按下
- {
- printf(" \r\n %d is light \r\n",Data[1]);//ID
- printf(" \r\n %d is pressed \r\n",key);
- if(key == 5)
- {
- printf(" 按鍵向上 !\r\n");
- led1();
- }
- else if(key == 7)
- {
- printf(" 按鍵向下 !\r\n");
- led2();
- }
- else if(key == 6)
- {
- printf(" 按鍵向右 !\r\n");
- led3();
- }
- else if(key == 8)
- {
- printf(" 按鍵向左 !\r\n");
- led4();
- }
- printf(" 輸入成功!\r\n");
- }
- delay_us(60000);
- }
-
- }
復制代碼- #include "ps2.h"
- #include "systick.h"
- 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
- }; //按鍵值與按鍵明
- //手柄接口初始化 輸入 DI->PB12
- // 輸出 DO->PB13 CS->PB14 CLK->PB15
- void PS2_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能GPIOF時鐘
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//普通輸出模式
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
- GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
-
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//普通輸出模式
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
- GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
- }
- //向手柄發送命令
- 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_us(10);
- CLK_L;
- delay_us(10);
- CLK_H;
- if(DI)
- Data[1] = ref|Data[1];
- }
- delay_us(16);
- }
- //判斷是否為紅燈模式,0x41=模擬綠燈,0x73=模擬紅燈
- //返回值;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_us(10);
- CLK_L;
- delay_us(10);
- CLK_H;
- if(DI)
- Data[byte] = ref|Data[byte];
- }
- delay_us(16);
- }
- CS_H;
- }
- //對讀出來的PS2的數據進行處理,只處理按鍵部分
- //只有一個按鍵按下時按下為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;
- }
- /******************************************************
- Function: void PS2_Vibration(u8 motor1, u8 motor2)
- Description: 手柄震動函數,
- Calls: void PS2_Cmd(u8 CMD);
- Input: 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(0xEE); //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);
- }
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
全部資料51hei下載地址:
PS2 震動+上下左右按鍵.rar
(910.7 KB, 下載次數: 68)
2018-8-30 23:05 上傳
點擊文件名下載附件
PS2手柄控制 下載積分: 黑幣 -5
|