|
本作品Chinked-out工作室版權(quán)所有,給大家分享一款游戲用的無線方向盤的制作方法,是用51單片機(jī)加上ADXL345加速度傳感器打造的,源碼和原理圖都有分享給51黑電子論壇的朋友們吧,大家先看下面的視頻。
視頻演示:
無線方向盤重要說明
藍(lán)牙模塊使用注意:
(1)當(dāng)藍(lán)牙模塊連接到電路中后,會(huì)影響到單片機(jī)的程序下載,在下載程序之前,必須移除藍(lán)牙串口模塊。
(2)藍(lán)牙串口模塊在上單后會(huì)自行配對(duì),但在配對(duì)過程中,藍(lán)牙模塊會(huì)自動(dòng)溢出數(shù)據(jù),從而影響到接收端單片機(jī),進(jìn)而導(dǎo)致單片機(jī)向PC機(jī)發(fā)送亂碼。
為避免這種情況的發(fā)生,可上電后等待藍(lán)牙模塊配對(duì)成功后在打開單片機(jī)電源開關(guān)(原理圖中已經(jīng)是這樣設(shè)計(jì)了)。
或在已經(jīng)出現(xiàn)發(fā)送亂碼的情況下,將單片機(jī)復(fù)位即可。
發(fā)送端原理圖:
0.png (165.29 KB, 下載次數(shù): 129)
下載附件
2017-3-23 23:06 上傳
接收端原理圖:
0.png (226.29 KB, 下載次數(shù): 123)
下載附件
2017-3-23 23:09 上傳
元件清單:
名稱 | 規(guī)格 | 數(shù)量 | 備注 | 萬能板 | 9x15cm | 2 |
| 單片機(jī):STC12C5A60S2 | DIP40 | 2 |
| 40P單片機(jī)母座 |
| 2 |
| 晶振 | 11.0592Mhz | 2 |
| 陶瓷電容 | 22pF | 4 |
| 電解電容 | 22uF | 2 |
| 10K電阻 |
| 2 |
| 撥動(dòng)開關(guān) |
| 2 |
| 排針 | 1組40P | 1 |
| 杜邦線 | 1組40P | 1 |
| 6x6x7.3mm方頭按鍵 |
| 7 |
| A44圓形按鍵帽 | 顏色自選 | 5 | 按鍵帽與按鍵需匹配 | 5P排針母座 |
| 2 | 用于固定ADXL345 | 4P排針母座 |
| 2 | 用于固定藍(lán)牙模塊 | ADXL345傳感器 |
| 1 |
| USB轉(zhuǎn)TTL下載器 | CH340系列 | 1 |
| USB線 | 母對(duì)母 | 1 |
| CH376S模塊 |
| 2 |
| 藍(lán)牙串口模塊 | HC-05 | 2 |
|
無線方向盤發(fā)送端單片機(jī)源程序:
- #include "STC12C5A60S2.h"
- #include"intrins.h"
- #define key1 0x1d //黑色 剎車 Z
- #define key2 0xE1 //黃色 left shift
- #define key3 0x04 //紅色 油門 A
- #define key4 0x4f //右 右轉(zhuǎn) →
- #define key5 0x50 //左 左轉(zhuǎn) ←
- sbit SCL=P0^6; //IIC時(shí)鐘引腳定義
- sbit SDA=P0^7; //IIC數(shù)據(jù)引腳定義
- unsigned char idata BUF[6]; //接收數(shù)據(jù)緩存區(qū) X軸高八位,X軸低八位; Y軸高八位,Y軸低八位; Z軸高八位,Z軸第低八位
- unsigned char idata key_buf[5]={0x00,0x00,0x00,0x00,0x00};
- unsigned char code key_judge_tab[]={0x01,0x02,0x04,0x08,0x10};
- void UartInit(void);
- void Send();
- void Clear();
- void Input_Data_Process();
- void Init_ADXL345(void); //初始化ADXL345
- void Single_Write_ADXL345(unsigned char REG_Address,unsigned char REG_data); //單個(gè)寫入數(shù)據(jù)
- void Multiple_Read_ADXL345(); //連續(xù)的讀取內(nèi)部寄存器數(shù)據(jù)
- void ADXL345_Start();
- void ADXL345_Stop();
- void ADXL345_SendACK(bit ack);
- bit ADXL345_RecvACK();
- void ADXL345_SendByte(unsigned char dat);
- unsigned char ADXL345_RecvByte();
- void ADXL345_Data_Process();
- void Delay5us();
- void Delay5ms();
- void Delay50ms();
- void Delay150ms();
- signed int idata X_data;
- unsigned char Data,judge;
- bit key_flag=0,flag;
- void main()
- {
- Delay150ms();
- P0M1=0x00;
- P0M0=0x00;
- UartInit();
- Init_ADXL345();
- while(1)
- {
-
- Data=~P2&0x1f; //讀取按鍵狀態(tài)
-
- Multiple_Read_ADXL345(); //讀取ADXL345數(shù)據(jù)
- ADXL345_Data_Process(); //ADXL345數(shù)據(jù)分析、處理
- Input_Data_Process(); //按鍵數(shù)據(jù)分析、處理
- Send(); //發(fā)送鍵盤代碼
- Clear(); //清空緩存數(shù)據(jù)
- Delay50ms();
- }
- }
- void ADXL345_Data_Process()
- {
- X_data=BUF[1]<<8|BUF[0];
- if(X_data<-50)Data=Data|0x10;
- if(X_data>50) Data=Data|0x08;
- }
- void Input_Data_Process()
- {
- unsigned char i;
- for(i=0;i<5;i++)
- {
- judge=Data&key_judge_tab[i];
- switch (judge)
- {
- case 0x00: break;
- case 0x01: key_buf[0]=key1;break;
- case 0x02: key_buf[1]=key2;break;
- case 0x04: key_buf[2]=key3;break;
- case 0x08: key_buf[3]=key4;break;
- case 0x10: key_buf[4]=key5;break;
- default:break;
- }
- }
- }
- void Multiple_read_ADXL345()
- {
- unsigned char i;
- ADXL345_Start(); //起始信號(hào)
- ADXL345_SendByte(0xA6); //發(fā)送設(shè)備地址+寫信號(hào)
- ADXL345_SendByte(0x32); //發(fā)送存儲(chǔ)單元地址,從0x32開始
- ADXL345_Start(); //起始信號(hào)
- ADXL345_SendByte(0xA7); //發(fā)送設(shè)備地址+讀信號(hào)
- for (i=0; i<6; i++) //連續(xù)讀取6個(gè)地址數(shù)據(jù),存儲(chǔ)中BUF
- {
- BUF[i] = ADXL345_RecvByte(); //BUF[0]存儲(chǔ)0x32地址中的數(shù)據(jù)
- if (i == 5)ADXL345_SendACK(1);//最后一個(gè)數(shù)據(jù)需要回NOACK
- else ADXL345_SendACK(0); //回應(yīng)ACK
- }
- ADXL345_Stop(); //停止信號(hào)
- Delay5ms();
- }
- void Init_ADXL345()
- {
- Single_Write_ADXL345(0x2C,0x08); //速率設(shè)定為12.5
- Single_Write_ADXL345(0x2D,0x08); //選擇電源模式
- Single_Write_ADXL345(0x31,0x0B); //測(cè)量范圍,正負(fù)16g,13位模式
- }
- void Single_Write_ADXL345(unsigned char REG_Address,unsigned char REG_data)
- {
- ADXL345_Start(); //起始信號(hào)
- ADXL345_SendByte(0xA6); //發(fā)送設(shè)備地址
- ADXL345_SendByte(REG_Address); //內(nèi)部寄存器地址
- ADXL345_SendByte(REG_data); //內(nèi)部寄存器數(shù)據(jù)
- ADXL345_Stop(); //發(fā)送停止信號(hào)
- }
- void ADXL345_Start()
- {
- SDA = 1; //拉高數(shù)據(jù)線
- SCL = 1; //拉高時(shí)鐘線
- Delay5us(); //延時(shí)
- SDA = 0; //產(chǎn)生下降沿
- Delay5us(); //延時(shí)
- SCL = 0; //拉低時(shí)鐘線
- }
- void ADXL345_Stop()
- {
- SDA = 0; //拉低數(shù)據(jù)線
- SCL = 1; //拉高時(shí)鐘線
- Delay5us(); //延時(shí)
- SDA = 1; //產(chǎn)生上升沿
- Delay5us(); //延時(shí)
- }
- void ADXL345_SendACK(bit ack)
- {
- SDA = ack; //寫應(yīng)答信號(hào)
- SCL = 1; //拉高時(shí)鐘線
- Delay5us(); //延時(shí)
- SCL = 0; //拉低時(shí)鐘線
- Delay5us(); //延時(shí)
- }
- bit ADXL345_RecvACK()
- {
- SCL = 1; //拉高時(shí)鐘線
- Delay5us(); //延時(shí)
- flag = SDA; //讀應(yīng)答信號(hào)
- SCL = 0; //拉低時(shí)鐘線
- Delay5us(); //延時(shí)
- return flag;
- }
- void ADXL345_SendByte(unsigned char dat)
- {
- unsigned char i;
- for (i=0; i<8; i++) //8位計(jì)數(shù)器
- {
- SDA=dat&0x80;
- SCL = 1; //拉高時(shí)鐘線
- Delay5us(); //延時(shí)
- SCL = 0; //拉低時(shí)鐘線
- Delay5us(); //延時(shí)
- dat <<= 1;
- }
- ADXL345_RecvACK();
- }
- unsigned char ADXL345_RecvByte()
- {
- unsigned char i;
- unsigned char dat = 0;
- SDA = 1; //使能內(nèi)部上拉,準(zhǔn)備讀取數(shù)據(jù),
- for (i=0; i<8; i++) //8位計(jì)數(shù)器
- {
- dat <<= 1;
- SCL = 1; //拉高時(shí)鐘線
- Delay5us(); //延時(shí)
- dat |= SDA; //讀數(shù)據(jù)
- SCL = 0; //拉低時(shí)鐘線
- Delay5us(); //延時(shí)
- }
- return dat;
- }
- void Send()
- {
- unsigned char i;
- for(i=0;i<5;i++)
- {
- SBUF=key_buf[i];
- while(!TI);
- TI=0;
- }
- }
- void Clear()
- {
- unsigned char i;
- for(i=0;i<5;i++)
- {
- key_buf[i]=0x00;
- }
- }
- void UartInit(void) //9600bps@11.0592MHz
- {
- EA=1;
- PCON &= 0x7F; //波特率不倍速
- SCON = 0x50; //8位數(shù)據(jù),可變波特率
- AUXR |= 0x04; //獨(dú)立波特率發(fā)生器時(shí)鐘為Fosc,即1T
- BRT = 0xDC; //設(shè)定獨(dú)立波特率發(fā)生器重裝值
- AUXR |= 0x01; //串口1選擇獨(dú)立波特率發(fā)生器為波特率發(fā)生器
- AUXR |= 0x10; //啟動(dòng)獨(dú)立波特率發(fā)生器
- }
-
- void Delay5us() //@11.0592MHz
- {
- unsigned char i;
- _nop_();
- _nop_();
- _nop_();
- i = 10;
- while (--i);
- }
- void Delay5ms() //@11.0592MHz
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- i = 54;
- j = 198;
- do
- {
- while (--j);
- } while (--i);
- }
- void Delay50ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- _nop_();
- _nop_();
- i = 3;
- j = 26;
- k = 223;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- void Delay150ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- _nop_();
- _nop_();
- i = 7;
- j = 78;
- k = 167;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
復(fù)制代碼
接收端程序:
- #include "STC12C5A60S2.h"
- #include "CH375INC.H"
- unsigned char CMD=0xff;
- sbit CH375_INT_WIRE = P3^2; //P3.2, INT0, 連接CH375的INT#引腳,用于查詢中斷狀態(tài) */
- unsigned char idata buf[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- unsigned char idata Recbuf[6]={0x00,0x00,0x00,0x00,0x00,0x00};
- unsigned char Rec_count=0;
- typedef union _REQUEST_PACK{
- unsigned char buffer[8];
- struct{
- unsigned char bmReuestType; //標(biāo)準(zhǔn)請(qǐng)求字
- unsigned char bRequest; //請(qǐng)求代碼
- unsigned int wValue; //特性選擇高
- unsigned int wIndx; //索引
- unsigned int wLength; //數(shù)據(jù)長(zhǎng)度
- }r;
- } mREQUEST_PACKET, *mpREQUEST_PACKET;
- //設(shè)備描述符
- unsigned char code DevDes[]={
- 0x12 //描述符大小
- , 0x01 //常數(shù)DEVICE
- , 0x10 //USB規(guī)范版本信息
- , 0x01
- , 0x00 //類別碼,
- , 0x00 //子類別碼
- , 0x00 //協(xié)議碼
- , 0x08 //端點(diǎn)0的最大信息包大小
- , 0x3c //廠商ID
- , 0x41
- , 0x03 //產(chǎn)品ID
- , 0x20
- , 0x00 //設(shè)備版本信息
- , 0x02
- , 0x01 //索引值
- , 0x02
- , 0x00
- , 0x01 //可能配置的數(shù)目
- };
- //配置描述符
- unsigned char code ConDes[]={ //配置描述符
- 0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x04, 0xa0, 0x23,//配置描述符
- 0x09, 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x01, 0x05,//接口描述符
- 0x09, 0x21, 0x10, 0x01, 0x00, 0x01, 0x22, 0x41, 0x00,//HID類描述符
- 0x07, 0x05, 0x81, 0x03, 0x08, 0x00, 0x18 //端點(diǎn)描述符,只配置了輸入端點(diǎn),輸出端點(diǎn)用0端點(diǎn)
- }; //配置描述符
- /*報(bào)表描述符*/
- unsigned char code Hid_des[]={
- 0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x07, 0x19, 0xe0,
- 0x29, 0xe7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08,
- 0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x03, 0x75, 0x01,
- 0x05, 0x08, 0x19, 0x01, 0x29, 0x03, 0x91, 0x02, 0x95, 0x01, 0x75, 0x05,
- 0x91, 0x01, 0x95, 0x06, 0x75, 0x08, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05,
- 0x07, 0x19, 0x00, 0x2a, 0xff, 0x00, 0x81, 0x00, 0xc0
- };
- /*關(guān)于全局變量的定義*/
- unsigned char mVarSetupRequest; // ;USB請(qǐng)求碼
- unsigned char mVarSetupLength; // 后續(xù)數(shù)據(jù)長(zhǎng)度
- unsigned char code * VarSetupDescr; //描述符偏移地址
- unsigned char VarUsbAddress ;
- unsigned char idata UPDATA_FLAG;
- bit CH375FLAGERR; //錯(cuò)誤清0
- bit CH375CONFLAG;
- mREQUEST_PACKET request;
- /*硬件定義,根據(jù)硬件修改*/
- unsigned char volatile xdata CH375_CMD_PORT _at_ 0x81ff; /* CH375命令端口的I/O地址 */
- unsigned char volatile xdata CH375_DAT_PORT _at_ 0x80ff; /* CH375數(shù)據(jù)端口的I/O地址 */
- …………余下代碼請(qǐng)下載附件…………
復(fù)制代碼
工作室交流討論群:231931086
視頻中測(cè)試游戲?yàn)椤稑O品飛車14》,若用于其他游戲,根據(jù)游戲的操作鍵修改Send程序中key1至Key5對(duì)應(yīng)的鍵盤代碼即可。受8位單片機(jī)機(jī)能限制,當(dāng)前程序一次性最多發(fā)送6個(gè)不同鍵盤代碼。
0.png (49.79 KB, 下載次數(shù): 153)
下載附件
2017-3-23 23:11 上傳
制作資料下載:
無線方向盤資料包.zip
(1.65 MB, 下載次數(shù): 60)
2017-3-23 23:24 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
|