找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5123|回复: 2
打印 上一主题 下一主题
收起左侧

基于51单片机的2.4g小车制作资料 带app

[复制链接]
跳转到指定楼层
楼主
2.4g无重力感应小车里面只包含按键跟2.4g模块通讯部分,想要添加重力感应,需要移植蓝牙有重力感应小车部分代码

所有制作资料打包下载:
2.4g小车.zip (8.4 MB, 下载次数: 73)

下面是小车的原理图:





控制程序说明:
加速度模块不同倾角时,向计算机发送不同数据
1 左偏时,发送0a
2 右偏时,发送a0
3 前偏时,发送aa
3 后偏是,发送55

发送数据时,数据类型具备优先级,当左右方向现有数据时,优先发送左右控制字符

优化了部分程序,删除了多余的测试程序
优化了数组,相比于版本3,删除了多余的数组
  1. #include  <REG52.H>       
  2. #include  <basic.h>
  3. #include  <INTRINS.H>
  4. sbit          SCL=P1^6;      //IIC时钟引脚定义
  5. sbit           SDA=P1^7;      //IIC数据引脚定义
  6. #define        SlaveAddress   0xA6          //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
  7. #define JudgeP_M  0x8000   //正负数判断
  8. #define Left_cmp  0x006e   //方向数据比较值,数值越小,越灵敏
  9. #define Right_cmp 0x006e
  10. #define Go_cmp    0x006e
  11. #define Back_cmp  0x006e
  12. #define Go    0xaa                   //小车实际动作控制字符,以实物为准
  13. #define Back  0x55
  14. #define Left  0xa5
  15. #define Right 0x5a
  16. #define Stop  0x00                   //停止控制字符
  17. Byte BUF[8];                         //接收数据缓存区
  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);   //单个写入数据
  22. void Multiple_Read_ADXL345();                                  //连续的读取内部寄存器数据
  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();                                   //上电延时                                   
  41.         uart();       
  42.         Init_ADXL345();                         //初始化ADXL345
  43.         while(1)                                 //循环
  44.         {
  45.                 Multiple_Read_ADXL345();               //连续读出数据,存储在BUF中
  46.                 Data_Convert();
  47.         Data_Process();
  48.                 direction_judge();
  49.                 Delay20ms();                           //延时      
  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. 延时5微秒(STC90C52RC@12M)
  71. 不同的工作环境,需要调整此函数,注意时钟过快时需要修改
  72. 当改用1T的MCU时,请调整此延时函数
  73. **************************************/
  74. void Delay5us()
  75. {
  76.     _nop_();_nop_();_nop_();_nop_();
  77.     _nop_();_nop_();_nop_();_nop_();
  78.         _nop_();_nop_();_nop_();_nop_();
  79. }
  80. /**************************************
  81. 延时5毫秒(STC90C52RC@12M)
  82. 不同的工作环境,需要调整此函数
  83. 当改用1T的MCU时,请调整此延时函数
  84. **************************************/
  85. void Delay5ms()
  86. {
  87.     Word n = 560;

  88.     while (n--);
  89. }
  90. /**************************************
  91. 起始信号
  92. **************************************/
  93. void ADXL345_Start()
  94. {
  95.     SDA = 1;                    //拉高数据线
  96.     SCL = 1;                    //拉高时钟线
  97.     Delay5us();                 //延时
  98.     SDA = 0;                    //产生下降沿
  99.     Delay5us();                 //延时
  100.     SCL = 0;                    //拉低时钟线
  101. }
  102. /**************************************
  103. 停止信号
  104. **************************************/
  105. void ADXL345_Stop()
  106. {
  107.     SDA = 0;                    //拉低数据线
  108.     SCL = 1;                    //拉高时钟线
  109.     Delay5us();                 //延时
  110.     SDA = 1;                    //产生上升沿
  111.     Delay5us();                 //延时
  112. }
  113. /**************************************
  114. 发送应答信号
  115. 入口参数:ack (0:ACK 1:NAK)
  116. **************************************/
  117. void ADXL345_SendACK(bit ack)
  118. {
  119.     SDA = ack;                  //写应答信号
  120.     SCL = 1;                    //拉高时钟线
  121.     Delay5us();                 //延时
  122.     SCL = 0;                    //拉低时钟线
  123.     Delay5us();                 //延时
  124. }
  125. /**************************************
  126. 接收应答信号
  127. **************************************/
  128. bit ADXL345_RecvACK()
  129. {
  130.     SCL = 1;                    //拉高时钟线
  131.     Delay5us();                 //延时
  132.     CY = SDA;                   //读应答信号
  133.     SCL = 0;                    //拉低时钟线
  134.     Delay5us();                 //延时

  135.     return CY;
  136. }
  137. /**************************************
  138. 向IIC总线发送一个字节数据
  139. **************************************/
  140. void ADXL345_SendByte(Byte dat)
  141. {
  142.     Byte i;

  143.     for (i=0; i<8; i++)         //8位计数器
  144.     {
  145.         dat <<= 1;              //移出数据的最高位
  146.         SDA = CY;               //送数据口
  147.         SCL = 1;                //拉高时钟线
  148.         Delay5us();             //延时
  149.         SCL = 0;                //拉低时钟线
  150.         Delay5us();             //延时
  151.     }
  152.     ADXL345_RecvACK();
  153. }
  154. //从IIC总线接收一个字节数据
  155. Byte ADXL345_RecvByte()
  156. {
  157.     Byte i;
  158.     Byte dat = 0;
  159.     SDA = 1;                    //使能内部上拉,准备读取数据,
  160.     for (i=0; i<8; i++)         //8位计数器
  161.     {
  162.         dat <<= 1;
  163.         SCL = 1;                //拉高时钟线
  164.         Delay5us();             //延时
  165.         dat |= SDA;             //读数据               
  166.         SCL = 0;                //拉低时钟线
  167.         Delay5us();             //延时
  168.     }
  169.     return dat;
  170. }
  171. //******单字节写入*******************************************
  172. void Single_Write_ADXL345(Byte REG_Address,Byte REG_data)
  173. {
  174.     ADXL345_Start();                  //起始信号
  175.     ADXL345_SendByte(SlaveAddress);   //发送设备地址+写信号
  176.     ADXL345_SendByte(REG_Address);    //内部寄存器地址,请参考中文pdf22页
  177.     ADXL345_SendByte(REG_data);       //内部寄存器数据,请参考中文pdf22页
  178.     ADXL345_Stop();                   //发送停止信号
  179. }
  180. //连续读出ADXL345内部加速度数据,地址范围0x32~0x37
  181. void Multiple_read_ADXL345(void)
  182. {   Byte i;
  183.     ADXL345_Start();                          //起始信号
  184.     ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号
  185.     ADXL345_SendByte(0x32);                   //发送存储单元地址,从0x32开始       
  186.     ADXL345_Start();                          //起始信号
  187.     ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号
  188.          for (i=0; i<6; i++)                      //连续读取6个地址数据,存储中BUF
  189.     {
  190.         BUF[i] = ADXL345_RecvByte();          //BUF[0]存储0x32地址中的数据
  191.         if (i == 5)
  192.         {
  193.            ADXL345_SendACK(1);                //最后一个数据需要回NOACK
  194.         }
  195.         else
  196.         {
  197.           ADXL345_SendACK(0);                //回应ACK
  198.        }
  199.    }
  200.     ADXL345_Stop();                          //停止信号
  201.     Delay5ms();
  202. }
  203. //初始化ADXL345,根据需要请参考pdf进行修改************************
  204. void Init_ADXL345()
  205. {
  206.    Single_Write_ADXL345(0x31,0x0B);   //测量范围,正负16g,13位模式
  207.    Single_Write_ADXL345(0x2C,0x08);   //速率设定为12.5 参考pdf13页
  208.    Single_Write_ADXL345(0x2D,0x08);   //选择电源模式   参考pdf24页
  209.    Single_Write_ADXL345(0x2E,0x80);   //使能 DATA_READY 中断
  210.    Single_Write_ADXL345(0x1E,0x00);   //X 偏移量 根据测试传感器的状态写入pdf29页
  211.    Single_Write_ADXL345(0x1F,0x00);   //Y 偏移量 根据测试传感器的状态写入pdf29页
  212.    Single_Write_ADXL345(0x20,0x05);   //Z 偏移量 根据测试传感器的状态写入pdf29页
  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()                                                //将两个八位数据合成为一个16位数据
  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轴数据处理
  242.   if(i==0x8000)                   //当结果为负数时
  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                                           //当结果为正数时
  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轴数据处理
  267.   if(i==0x8000)                   //当结果为负数时
  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                                           //当结果为正数时
  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. }
复制代码

NRF24L01发送模块
  1. /*****************************************
  2. 创建:HAPPY 可儿
  3. 时间:2016.6.25
  4. 功能:工程主函数(主机发射部分)
  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) //如果检测到低电平,说明按键按下
  23.       {
  24.         Delay(10); //延时去抖,一般10-20ms
  25.         if(!KEY1) //再次确认按键是否按下,没有按下则退出
  26.          {
  27.             while(!KEY1)//如果确认按下按键等待按键释放,没有则退出
  28.             {
  29.                 TxDate[0] = 0;//前进
  30.                 TxDate[1] = 1;
  31.                 TxDate[2] = 0;
  32.                 TxDate[3] = 1;
  33.                 NRFSetTxMode(TxDate);//发送数据·
  34.                 while(CheckACK()); //检测是否发送完毕
  35.              }
  36.                          Delay(10); //延时去抖,一般10-20ms
  37.                          while(!KEY1);
  38.                          TxDate[0] = 1;//空操作
  39.              TxDate[1] = 1;
  40.              TxDate[2] = 1;
  41.              TxDate[3] = 1;
  42.                          NRFSetTxMode(TxDate);//发送数据·
  43.              while(CheckACK()); //检测是否发送完毕
  44.         }
  45.       }
  46. /********************************************************/
  47.    else if(!KEY2) //如果检测到低电平,说明按键按下
  48.    {
  49.      Delay(10); //延时去抖,一般10-20ms
  50.      if(!KEY2) //再次确认按键是否按下,没有按下则退出
  51.       {
  52.         while(!KEY2)//如果确认按下按键等待按键释放,没有则退出
  53.           {
  54.             TxDate[0] = 0;//向左转
  55.             TxDate[1] = 1;
  56.             TxDate[2] = 1;
  57.             TxDate[3] = 0;
  58.             NRFSetTxMode(TxDate);//发送数据
  59.             while(CheckACK()); //检测是否发送完毕
  60.          }
  61.                  Delay(10); //延时去抖,一般10-20ms
  62.                  while(!KEY1);
  63.                  TxDate[0] = 1;//空操作
  64.          TxDate[1] = 1;
  65.          TxDate[2] = 1;
  66.          TxDate[3] = 1;
  67.                  NRFSetTxMode(TxDate);//发送数据·
  68.          while(CheckACK()); //检测是否发送完毕
  69.      }
  70.    }
  71. /********************************************************/
  72.    else if(!KEY3) //如果检测到低电平,说明按键按下
  73.     {
  74.       Delay(10); //延时去抖,一般10-20ms
  75.       if(!KEY3) //再次确认按键是否按下,没有按下则退出
  76.         {
  77.           while(!KEY3)//如果确认按下按键等待按键释放,没有则退出
  78.             {
  79.               TxDate[0] = 1;//向右转
  80.               TxDate[1] = 0;
  81.               TxDate[2] = 0;
  82.               TxDate[3] = 1;
  83.               NRFSetTxMode(TxDate);//发送数据
  84.               while(CheckACK()); //检测是否发送完毕
  85.            }
  86.                    Delay(10); //延时去抖,一般10-20ms
  87.                          while(!KEY1);
  88.                      TxDate[0] = 1;//空操作
  89.              TxDate[1] = 1;
  90.              TxDate[2] = 1;
  91.              TxDate[3] = 1;
  92.                          NRFSetTxMode(TxDate);//发送数据·
  93.              while(CheckACK()); //检测是否发送完毕
  94.         }
  95.    }
  96. /********************************************************/
  97.    else if(!KEY4) //如果检测到低电平,说明按键按下
  98.     {
  99.       Delay(10); //延时去抖,一般10-20ms
  100.       if(!KEY4) //再次确认按键是否按下,没有按下则退出
  101.         {
  102.           while(!KEY4)//如果确认按下按键等待按键释放,没有则退出
  103.             {
  104.               TxDate[0] = 1;//后退
  105.               TxDate[1] = 0;
  106.               TxDate[2] = 1;
  107.               TxDate[3] = 0;
  108.               NRFSetTxMode(TxDate);//发送数据
  109.               while(CheckACK()); //检测是否发送完毕
  110.             }
  111.                          Delay(10); //延时去抖,一般10-20ms
  112.                          while(!KEY1);
  113.                          TxDate[0] = 1;//空操作
  114.              TxDate[1] = 1;
  115.              TxDate[2] = 1;
  116.              TxDate[3] = 1;
  117.                          NRFSetTxMode(TxDate);//发送数据·
  118.              while(CheckACK()); //检测是否发送完毕
  119.         }
  120.      }

  121. }  
  122. }
  123. /*********************主函数***************************/
  124. void main()
  125. {
  126.     NRF24L01Int(); //初始化NRF24L01
  127.     while(1)
  128.     {         
  129.           KeyScan();   
  130.         }
  131. }
复制代码


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:141094 发表于 2016-11-1 03:50 | 只看该作者
下载看看
回复

使用道具 举报

板凳
ID:326450 发表于 2019-6-12 12:02 | 只看该作者
十分感谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表