找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 5900|回復(fù): 2
收起左側(cè)

基于51單片機(jī)的2.4g小車制作資料 帶app

[復(fù)制鏈接]
ID:143982 發(fā)表于 2016-10-22 22:20 | 顯示全部樓層 |閱讀模式
2.4g無重力感應(yīng)小車?yán)锩嬷话存I跟2.4g模塊通訊部分,想要添加重力感應(yīng),需要移植藍(lán)牙有重力感應(yīng)小車部分代碼
0.png
所有制作資料打包下載:
2.4g小車.7z (7.7 MB, 下載次數(shù): 75)

下面是小車的原理圖:



0.png 0.png

控制程序說明:
加速度模塊不同傾角時(shí),向計(jì)算機(jī)發(fā)送不同數(shù)據(jù)
1 左偏時(shí),發(fā)送0a
2 右偏時(shí),發(fā)送a0
3 前偏時(shí),發(fā)送aa
3 后偏是,發(fā)送55

發(fā)送數(shù)據(jù)時(shí),數(shù)據(jù)類型具備優(yōu)先級(jí),當(dāng)左右方向現(xiàn)有數(shù)據(jù)時(shí),優(yōu)先發(fā)送左右控制字符

優(yōu)化了部分程序,刪除了多余的測(cè)試程序
優(yōu)化了數(shù)組,相比于版本3,刪除了多余的數(shù)組
  1. #include  <REG52.H>        
  2. #include  <basic.h>
  3. #include  <INTRINS.H>
  4. sbit          SCL=P1^6;      //IIC時(shí)鐘引腳定義
  5. sbit           SDA=P1^7;      //IIC數(shù)據(jù)引腳定義
  6. #define        SlaveAddress   0xA6          //定義器件在IIC總線中的從地址,根據(jù)ALT  ADDRESS地址引腳不同修改
  7. #define JudgeP_M  0x8000   //正負(fù)數(shù)判斷
  8. #define Left_cmp  0x006e   //方向數(shù)據(jù)比較值,數(shù)值越小,越靈敏
  9. #define Right_cmp 0x006e
  10. #define Go_cmp    0x006e
  11. #define Back_cmp  0x006e
  12. #define Go    0xaa                   //小車實(shí)際動(dòng)作控制字符,以實(shí)物為準(zhǔn)
  13. #define Back  0x55
  14. #define Left  0xa5
  15. #define Right 0x5a
  16. #define Stop  0x00                   //停止控制字符
  17. Byte BUF[8];                         //接收數(shù)據(jù)緩存區(qū)
  18. Byte Sbuf[8];
  19. Word Wbuf[2];            
  20. void Init_ADXL345(void);             //初始化ADXL345
  21. void Single_Write_ADXL345(Byte REG_Address,Byte REG_data);   //單個(gè)寫入數(shù)據(jù)
  22. void Multiple_Read_ADXL345();                                  //連續(xù)的讀取內(nèi)部寄存器數(shù)據(jù)
  23. void Delay5us();
  24. void Delay5ms();
  25. void Delay20ms();
  26. void ADXL345_Start();
  27. void ADXL345_Stop();
  28. void ADXL345_SendACK(bit ack);
  29. bit  ADXL345_RecvACK();
  30. void ADXL345_SendByte(Byte dat);
  31. Byte ADXL345_RecvByte();
  32. void send();
  33. void uart();
  34. void Data_Convert();
  35. void Data_Process();
  36. void direction_judge();
  37. //******主程序********
  38. void main()
  39. {
  40.         void Delay20ms();                                   //上電延時(shí)                                   
  41.         uart();        
  42.         Init_ADXL345();                         //初始化ADXL345
  43.         while(1)                                 //循環(huán)
  44.         {
  45.                 Multiple_Read_ADXL345();               //連續(xù)讀出數(shù)據(jù),存儲(chǔ)在BUF中
  46.                 Data_Convert();
  47.         Data_Process();
  48.                 direction_judge();
  49.                 Delay20ms();                           //延時(shí)      
  50.         }
  51. }

  52. /*******************************/
  53. void Delay20ms()                //@11.0592MHz
  54. {
  55.         unsigned char i, j, k;

  56.         _nop_();
  57.         _nop_();
  58.         i = 1;
  59.         j = 216;
  60.         k = 35;
  61.         do
  62.         {
  63.                 do
  64.                 {
  65.                         while (--k);
  66.                 } while (--j);
  67.         } while (--i);
  68. }                                
  69. /**************************************
  70. 延時(shí)5微秒(STC90C52RC@12M)
  71. 不同的工作環(huán)境,需要調(diào)整此函數(shù),注意時(shí)鐘過快時(shí)需要修改
  72. 當(dāng)改用1T的MCU時(shí),請(qǐng)調(diào)整此延時(shí)函數(shù)
  73. **************************************/
  74. void Delay5us()
  75. {
  76.     _nop_();_nop_();_nop_();_nop_();
  77.     _nop_();_nop_();_nop_();_nop_();
  78.         _nop_();_nop_();_nop_();_nop_();
  79. }
  80. /**************************************
  81. 延時(shí)5毫秒(STC90C52RC@12M)
  82. 不同的工作環(huán)境,需要調(diào)整此函數(shù)
  83. 當(dāng)改用1T的MCU時(shí),請(qǐng)調(diào)整此延時(shí)函數(shù)
  84. **************************************/
  85. void Delay5ms()
  86. {
  87.     Word n = 560;

  88.     while (n--);
  89. }
  90. /**************************************
  91. 起始信號(hào)
  92. **************************************/
  93. void ADXL345_Start()
  94. {
  95.     SDA = 1;                    //拉高數(shù)據(jù)線
  96.     SCL = 1;                    //拉高時(shí)鐘線
  97.     Delay5us();                 //延時(shí)
  98.     SDA = 0;                    //產(chǎn)生下降沿
  99.     Delay5us();                 //延時(shí)
  100.     SCL = 0;                    //拉低時(shí)鐘線
  101. }
  102. /**************************************
  103. 停止信號(hào)
  104. **************************************/
  105. void ADXL345_Stop()
  106. {
  107.     SDA = 0;                    //拉低數(shù)據(jù)線
  108.     SCL = 1;                    //拉高時(shí)鐘線
  109.     Delay5us();                 //延時(shí)
  110.     SDA = 1;                    //產(chǎn)生上升沿
  111.     Delay5us();                 //延時(shí)
  112. }
  113. /**************************************
  114. 發(fā)送應(yīng)答信號(hào)
  115. 入口參數(shù):ack (0:ACK 1:NAK)
  116. **************************************/
  117. void ADXL345_SendACK(bit ack)
  118. {
  119.     SDA = ack;                  //寫應(yīng)答信號(hào)
  120.     SCL = 1;                    //拉高時(shí)鐘線
  121.     Delay5us();                 //延時(shí)
  122.     SCL = 0;                    //拉低時(shí)鐘線
  123.     Delay5us();                 //延時(shí)
  124. }
  125. /**************************************
  126. 接收應(yīng)答信號(hào)
  127. **************************************/
  128. bit ADXL345_RecvACK()
  129. {
  130.     SCL = 1;                    //拉高時(shí)鐘線
  131.     Delay5us();                 //延時(shí)
  132.     CY = SDA;                   //讀應(yīng)答信號(hào)
  133.     SCL = 0;                    //拉低時(shí)鐘線
  134.     Delay5us();                 //延時(shí)

  135.     return CY;
  136. }
  137. /**************************************
  138. 向IIC總線發(fā)送一個(gè)字節(jié)數(shù)據(jù)
  139. **************************************/
  140. void ADXL345_SendByte(Byte dat)
  141. {
  142.     Byte i;

  143.     for (i=0; i<8; i++)         //8位計(jì)數(shù)器
  144.     {
  145.         dat <<= 1;              //移出數(shù)據(jù)的最高位
  146.         SDA = CY;               //送數(shù)據(jù)口
  147.         SCL = 1;                //拉高時(shí)鐘線
  148.         Delay5us();             //延時(shí)
  149.         SCL = 0;                //拉低時(shí)鐘線
  150.         Delay5us();             //延時(shí)
  151.     }
  152.     ADXL345_RecvACK();
  153. }
  154. //從IIC總線接收一個(gè)字節(jié)數(shù)據(jù)
  155. Byte ADXL345_RecvByte()
  156. {
  157.     Byte i;
  158.     Byte dat = 0;
  159.     SDA = 1;                    //使能內(nèi)部上拉,準(zhǔn)備讀取數(shù)據(jù),
  160.     for (i=0; i<8; i++)         //8位計(jì)數(shù)器
  161.     {
  162.         dat <<= 1;
  163.         SCL = 1;                //拉高時(shí)鐘線
  164.         Delay5us();             //延時(shí)
  165.         dat |= SDA;             //讀數(shù)據(jù)               
  166.         SCL = 0;                //拉低時(shí)鐘線
  167.         Delay5us();             //延時(shí)
  168.     }
  169.     return dat;
  170. }
  171. //******單字節(jié)寫入*******************************************
  172. void Single_Write_ADXL345(Byte REG_Address,Byte REG_data)
  173. {
  174.     ADXL345_Start();                  //起始信號(hào)
  175.     ADXL345_SendByte(SlaveAddress);   //發(fā)送設(shè)備地址+寫信號(hào)
  176.     ADXL345_SendByte(REG_Address);    //內(nèi)部寄存器地址,請(qǐng)參考中文pdf22頁(yè)
  177.     ADXL345_SendByte(REG_data);       //內(nèi)部寄存器數(shù)據(jù),請(qǐng)參考中文pdf22頁(yè)
  178.     ADXL345_Stop();                   //發(fā)送停止信號(hào)
  179. }
  180. //連續(xù)讀出ADXL345內(nèi)部加速度數(shù)據(jù),地址范圍0x32~0x37
  181. void Multiple_read_ADXL345(void)
  182. {   Byte i;
  183.     ADXL345_Start();                          //起始信號(hào)
  184.     ADXL345_SendByte(SlaveAddress);           //發(fā)送設(shè)備地址+寫信號(hào)
  185.     ADXL345_SendByte(0x32);                   //發(fā)送存儲(chǔ)單元地址,從0x32開始        
  186.     ADXL345_Start();                          //起始信號(hào)
  187.     ADXL345_SendByte(SlaveAddress+1);         //發(fā)送設(shè)備地址+讀信號(hào)
  188.          for (i=0; i<6; i++)                      //連續(xù)讀取6個(gè)地址數(shù)據(jù),存儲(chǔ)中BUF
  189.     {
  190.         BUF[i] = ADXL345_RecvByte();          //BUF[0]存儲(chǔ)0x32地址中的數(shù)據(jù)
  191.         if (i == 5)
  192.         {
  193.            ADXL345_SendACK(1);                //最后一個(gè)數(shù)據(jù)需要回NOACK
  194.         }
  195.         else
  196.         {
  197.           ADXL345_SendACK(0);                //回應(yīng)ACK
  198.        }
  199.    }
  200.     ADXL345_Stop();                          //停止信號(hào)
  201.     Delay5ms();
  202. }
  203. //初始化ADXL345,根據(jù)需要請(qǐng)參考pdf進(jìn)行修改************************
  204. void Init_ADXL345()
  205. {
  206.    Single_Write_ADXL345(0x31,0x0B);   //測(cè)量范圍,正負(fù)16g,13位模式
  207.    Single_Write_ADXL345(0x2C,0x08);   //速率設(shè)定為12.5 參考pdf13頁(yè)
  208.    Single_Write_ADXL345(0x2D,0x08);   //選擇電源模式   參考pdf24頁(yè)
  209.    Single_Write_ADXL345(0x2E,0x80);   //使能 DATA_READY 中斷
  210.    Single_Write_ADXL345(0x1E,0x00);   //X 偏移量 根據(jù)測(cè)試傳感器的狀態(tài)寫入pdf29頁(yè)
  211.    Single_Write_ADXL345(0x1F,0x00);   //Y 偏移量 根據(jù)測(cè)試傳感器的狀態(tài)寫入pdf29頁(yè)
  212.    Single_Write_ADXL345(0x20,0x05);   //Z 偏移量 根據(jù)測(cè)試傳感器的狀態(tài)寫入pdf29頁(yè)
  213. }
  214. void uart()
  215. {
  216. SCON=0x50;
  217. TMOD=0x20;
  218. PCON=0x00;
  219. TH1=0xfd;
  220. TL1=0xfd;
  221. IE=0x90;
  222. TR1=1;
  223. }

  224. void send(unsigned char ch)
  225. {
  226. ES=0;
  227. SBUF=ch;
  228. while (TI==0);
  229. TI=0 ;
  230. ES=1;
  231. }
  232. void Data_Convert()                                                //將兩個(gè)八位數(shù)據(jù)合成為一個(gè)16位數(shù)據(jù)
  233. {
  234.   Wbuf[0]=BUF[1]<<8|BUF[0];
  235.   Wbuf[1]=BUF[3]<<8|BUF[2];
  236.   Wbuf[2]=BUF[5]<<8|BUF[4];
  237. }
  238. void Data_Process()
  239. {
  240.    Word i=0;
  241.     i=Wbuf[0]&JudgeP_M;           //X軸數(shù)據(jù)處理
  242.   if(i==0x8000)                   //當(dāng)結(jié)果為負(fù)數(shù)時(shí)
  243.   {
  244.    Wbuf[0]=~Wbuf[0]+1;
  245.    Wbuf[0]=Wbuf[0]&0x7fff;
  246.    if(Wbuf[0]>Left_cmp)
  247.    {
  248.    Sbuf[0]=Left;
  249.    }
  250.    else
  251.    {
  252.    Sbuf[0]=Stop;
  253.    }
  254.   }
  255.   else                                           //當(dāng)結(jié)果為正數(shù)時(shí)
  256.   {
  257.    if(Wbuf[0]>Right_cmp)
  258.    {
  259.       Sbuf[0]=Right;
  260.    }
  261.    else
  262.    {
  263.            Sbuf[0]=Stop;
  264.    }
  265.   }
  266.   i=Wbuf[1]&JudgeP_M;                   //Y軸數(shù)據(jù)處理
  267.   if(i==0x8000)                   //當(dāng)結(jié)果為負(fù)數(shù)時(shí)
  268.   {
  269.    Wbuf[1]=~Wbuf[1]+1;
  270.    Wbuf[1]=Wbuf[1]&0x7fff;
  271.    if(Wbuf[1]>Back_cmp)
  272.    {
  273.    Sbuf[1]=Back;
  274.    }
  275.    else
  276.    {
  277.    Sbuf[1]=Stop;
  278.    }
  279.   }
  280.   else                                           //當(dāng)結(jié)果為正數(shù)時(shí)
  281.   {
  282.    if(Wbuf[1]>Go_cmp)
  283.    {
  284.      Sbuf[1]=Go;
  285.    }
  286.    else
  287.    {
  288.          Sbuf[1]=Stop;
  289.    }
  290.   }
  291. }
  292. void direction_judge()
  293. {

  294.   if(Sbuf[0]==Left|Sbuf[0]==Right)
  295.   {
  296.    send(Sbuf[0]);
  297.   }
  298.   else
  299.   {
  300.    send(Sbuf[1]);
  301.   }
  302. }
復(fù)制代碼

NRF24L01發(fā)送模塊
  1. /*****************************************
  2. 創(chuàng)建:HAPPY 可兒
  3. 時(shí)間:2016.6.25
  4. 功能:工程主函數(shù)(主機(jī)發(fā)射部分)
  5. /*****************************************/
  6. #include"reg52.h"
  7. #include"Allhead.h"
  8. /*按鍵定義*/
  9. sbit KEY1 = P2^6;
  10. sbit KEY2 = P2^4;
  11. sbit KEY3 = P2^5;
  12. sbit KEY4 = P2^7;
  13. sbit KEY5 = P1^4;
  14. sbit LED1 = P0^0;
  15. sbit LED2 = P0^1;

  16. /*鍵盤掃描*/
  17. void KeyScan()
  18. {
  19.    char TxDate[4];
  20.    {
  21.   
  22.      if(!KEY1) //如果檢測(cè)到低電平,說明按鍵按下
  23.       {
  24.         Delay(10); //延時(shí)去抖,一般10-20ms
  25.         if(!KEY1) //再次確認(rèn)按鍵是否按下,沒有按下則退出
  26.          {
  27.             while(!KEY1)//如果確認(rèn)按下按鍵等待按鍵釋放,沒有則退出
  28.             {
  29.                 TxDate[0] = 0;//前進(jìn)
  30.                 TxDate[1] = 1;
  31.                 TxDate[2] = 0;
  32.                 TxDate[3] = 1;
  33.                 NRFSetTxMode(TxDate);//發(fā)送數(shù)據(jù)·
  34.                 while(CheckACK()); //檢測(cè)是否發(fā)送完畢
  35.              }
  36.                          Delay(10); //延時(shí)去抖,一般10-20ms
  37.                          while(!KEY1);
  38.                          TxDate[0] = 1;//空操作
  39.              TxDate[1] = 1;
  40.              TxDate[2] = 1;
  41.              TxDate[3] = 1;
  42.                          NRFSetTxMode(TxDate);//發(fā)送數(shù)據(jù)·
  43.              while(CheckACK()); //檢測(cè)是否發(fā)送完畢
  44.         }
  45.       }
  46. /********************************************************/
  47.    else if(!KEY2) //如果檢測(cè)到低電平,說明按鍵按下
  48.    {
  49.      Delay(10); //延時(shí)去抖,一般10-20ms
  50.      if(!KEY2) //再次確認(rèn)按鍵是否按下,沒有按下則退出
  51.       {
  52.         while(!KEY2)//如果確認(rèn)按下按鍵等待按鍵釋放,沒有則退出
  53.           {
  54.             TxDate[0] = 0;//向左轉(zhuǎn)
  55.             TxDate[1] = 1;
  56.             TxDate[2] = 1;
  57.             TxDate[3] = 0;
  58.             NRFSetTxMode(TxDate);//發(fā)送數(shù)據(jù)
  59.             while(CheckACK()); //檢測(cè)是否發(fā)送完畢
  60.          }
  61.                  Delay(10); //延時(shí)去抖,一般10-20ms
  62.                  while(!KEY1);
  63.                  TxDate[0] = 1;//空操作
  64.          TxDate[1] = 1;
  65.          TxDate[2] = 1;
  66.          TxDate[3] = 1;
  67.                  NRFSetTxMode(TxDate);//發(fā)送數(shù)據(jù)·
  68.          while(CheckACK()); //檢測(cè)是否發(fā)送完畢
  69.      }
  70.    }
  71. /********************************************************/
  72.    else if(!KEY3) //如果檢測(cè)到低電平,說明按鍵按下
  73.     {
  74.       Delay(10); //延時(shí)去抖,一般10-20ms
  75.       if(!KEY3) //再次確認(rèn)按鍵是否按下,沒有按下則退出
  76.         {
  77.           while(!KEY3)//如果確認(rèn)按下按鍵等待按鍵釋放,沒有則退出
  78.             {
  79.               TxDate[0] = 1;//向右轉(zhuǎn)
  80.               TxDate[1] = 0;
  81.               TxDate[2] = 0;
  82.               TxDate[3] = 1;
  83.               NRFSetTxMode(TxDate);//發(fā)送數(shù)據(jù)
  84.               while(CheckACK()); //檢測(cè)是否發(fā)送完畢
  85.            }
  86.                    Delay(10); //延時(shí)去抖,一般10-20ms
  87.                          while(!KEY1);
  88.                      TxDate[0] = 1;//空操作
  89.              TxDate[1] = 1;
  90.              TxDate[2] = 1;
  91.              TxDate[3] = 1;
  92.                          NRFSetTxMode(TxDate);//發(fā)送數(shù)據(jù)·
  93.              while(CheckACK()); //檢測(cè)是否發(fā)送完畢
  94.         }
  95.    }
  96. /********************************************************/
  97.    else if(!KEY4) //如果檢測(cè)到低電平,說明按鍵按下
  98.     {
  99.       Delay(10); //延時(shí)去抖,一般10-20ms
  100.       if(!KEY4) //再次確認(rèn)按鍵是否按下,沒有按下則退出
  101.         {
  102.           while(!KEY4)//如果確認(rèn)按下按鍵等待按鍵釋放,沒有則退出
  103.             {
  104.               TxDate[0] = 1;//后退
  105.               TxDate[1] = 0;
  106.               TxDate[2] = 1;
  107.               TxDate[3] = 0;
  108.               NRFSetTxMode(TxDate);//發(fā)送數(shù)據(jù)
  109.               while(CheckACK()); //檢測(cè)是否發(fā)送完畢
  110.             }
  111.                          Delay(10); //延時(shí)去抖,一般10-20ms
  112.                          while(!KEY1);
  113.                          TxDate[0] = 1;//空操作
  114.              TxDate[1] = 1;
  115.              TxDate[2] = 1;
  116.              TxDate[3] = 1;
  117.                          NRFSetTxMode(TxDate);//發(fā)送數(shù)據(jù)·
  118.              while(CheckACK()); //檢測(cè)是否發(fā)送完畢
  119.         }
  120.      }

  121. }  
  122. }
  123. /*********************主函數(shù)***************************/
  124. void main()
  125. {
  126.     NRF24L01Int(); //初始化NRF24L01
  127.     while(1)
  128.     {         
  129.           KeyScan();   
  130.         }
  131. }
復(fù)制代碼


評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

ID:141094 發(fā)表于 2016-11-1 03:50 | 顯示全部樓層
下載看看
回復(fù)

使用道具 舉報(bào)

ID:326450 發(fā)表于 2019-6-12 12:02 | 顯示全部樓層
十分感謝分享
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表