找回密码
 立即注册

QQ登录

只需一步,快速开始

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

自制手势遥控车 ADXL345+51单片机 带视频教程 源码 原理图

  [复制链接]
跳转到指定楼层
楼主
一个用51单片机和ADXL345传感器做的手势遥控车分享给51黑电子论坛的朋友们,作者是鼎鼎大名的Chinked-out工作室.

视频演示:

本遥控车的源程序详细解说视频:


手势遥控车驱动电路原理图:



手势遥控车手控电路原理图:



  
手势遥控车元件清单
  
名称
数量
规格/型号
备注
万能板
2
12*18cm
玻璃纤维板
单片机
1
STC15F2K32S2-SKDIP28
15F2K系列均可
单片机
1
STC15F2K32S2-SOPP28
15F2K系列均可
L293D
2
DIP16

SOP28转DIP28转接板
1


40pIC座
1


16pIC座



8p母座
4
2.54mm间距

拨动开关
1


直排针
40p


弯排针
40p


杜邦线
20P
公对母
与电机接线用
细导线(飞线)
若干


6p母座
1


USB转TTL下载器
1

PL303或CH340
杜邦线
4
母对母
下载程序和供电
M3*50mm铜柱
4


M3*50mm铜柱
4


M3螺母
4


减速电机
4


车轮
4
直径65mm

电机固定座
4


降压模块
1
LM2596S可调

锂电池
1
12V-6A-6800mah



ADXL345.c程序源码:
  1. #include "STC15F2K60S2.h"
  2. #include "string.h"
  3. #include  "stdio.h"   //Keil library        
  4. #include  <INTRINS.H>
  5. sbit          SCL=P1^0;      //IIC时钟引脚定义
  6. sbit           SDA=P1^1;      //IIC数据引脚定义
  7. unsigned char idata BUF[6];    //接收数据缓存区  X轴高八位,X轴低八位; Y轴高八位,Y轴低八位; Z轴高八位,Z轴第低八位
  8. unsigned char idata Sbuf[32];
  9. signed int idata XYZ_data[3];                        
  10. void Init_ADXL345(void);             //初始化ADXL345
  11. void  Single_Write_ADXL345(unsigned char REG_Address,unsigned char REG_data);   //单个写入数据
  12. void  Multiple_Read_ADXL345();                                  //连续的读取内部寄存器数据
  13. void Delay5us();
  14. void Delay5ms();
  15. void Delay300ms();
  16. void ADXL345_Start();
  17. void ADXL345_Stop();
  18. void ADXL345_SendACK(bit ack);
  19. bit  ADXL345_RecvACK();
  20. void ADXL345_SendByte(unsigned char dat);
  21. unsigned char ADXL345_RecvByte();
  22. void Send();
  23. void UartInit();
  24. void Data_Process();

  25. bit flag;

  26. //******主程序********
  27. void main()
  28. {
  29.         Delay300ms();                           
  30.         UartInit();        
  31.         Init_ADXL345();                         //初始化ADXL345
  32.         while(1)                                 //循环
  33.         {
  34.                 Multiple_Read_ADXL345();               //连续读出数据,存储在BUF中
  35.         Data_Process();
  36.                 Send();
  37.                 Delay300ms();   
  38.         }
  39. }

  40. /**************************************
  41. 起始信号
  42. **************************************/
  43. void ADXL345_Start()
  44. {
  45.     SDA = 1;                    //拉高数据线
  46.     SCL = 1;                    //拉高时钟线
  47.     Delay5us();                 //延时
  48.     SDA = 0;                    //产生下降沿
  49.     Delay5us();                 //延时
  50.     SCL = 0;                    //拉低时钟线
  51. }
  52. /**************************************
  53. 停止信号
  54. **************************************/
  55. void ADXL345_Stop()
  56. {
  57.     SDA = 0;                    //拉低数据线
  58.     SCL = 1;                    //拉高时钟线
  59.     Delay5us();                 //延时
  60.     SDA = 1;                    //产生上升沿
  61.     Delay5us();                 //延时
  62. }
  63. /**************************************
  64. 发送应答信号
  65. 入口参数:ack (0:ACK 1:NAK)
  66. **************************************/
  67. void ADXL345_SendACK(bit ack)
  68. {
  69.     SDA = ack;                  //写应答信号
  70.     SCL = 1;                    //拉高时钟线
  71.     Delay5us();                 //延时
  72.     SCL = 0;                    //拉低时钟线
  73.     Delay5us();                 //延时
  74. }
  75. /**************************************
  76. 接收应答信号
  77. **************************************/
  78. bit ADXL345_RecvACK()
  79. {
  80.     SCL = 1;                    //拉高时钟线
  81.     Delay5us();                 //延时
  82.     flag = SDA;                   //读应答信号
  83.     SCL = 0;                    //拉低时钟线
  84.     Delay5us();                 //延时

  85.     return flag;
  86. }
  87. /**************************************
  88. 向IIC总线发送一个字节数据
  89. **************************************/
  90. void ADXL345_SendByte(unsigned char dat)
  91. {
  92.     unsigned char i;

  93.     for (i=0; i<8; i++)         //8位计数器
  94.     {
  95.                 SDA=dat&0x80;
  96.         SCL = 1;                //拉高时钟线
  97.         Delay5us();             //延时
  98.         SCL = 0;                //拉低时钟线
  99.         Delay5us();             //延时
  100.                 dat <<= 1;
  101.     }
  102.     ADXL345_RecvACK();
  103. }
  104. //从IIC总线接收一个字节数据
  105. unsigned char ADXL345_RecvByte()
  106. {
  107.     unsigned char i;
  108.     unsigned char dat = 0;
  109.     SDA = 1;                    //使能内部上拉,准备读取数据,
  110.     for (i=0; i<8; i++)         //8位计数器
  111.     {
  112.         dat <<= 1;
  113.         SCL = 1;                //拉高时钟线
  114.         Delay5us();             //延时
  115.         dat |= SDA;             //读数据               
  116.         SCL = 0;                //拉低时钟线
  117.         Delay5us();             //延时
  118.     }
  119.     return dat;
  120. }
  121. //******单字节写入*******************************************
  122. void Single_Write_ADXL345(unsigned char REG_Address,unsigned char REG_data)
  123. {
  124.     ADXL345_Start();                  //起始信号
  125.     ADXL345_SendByte(0xA6);   //发送设备地址
  126.     ADXL345_SendByte(REG_Address);    //内部寄存器地址
  127.     ADXL345_SendByte(REG_data);       //内部寄存器数据
  128.     ADXL345_Stop();                   //发送停止信号
  129. }

  130. //连续读出ADXL345内部加速度数据,地址范围0x32~0x37
  131. void Multiple_read_ADXL345(void)
  132. {   
  133.         unsigned char i;
  134.     ADXL345_Start();                          //起始信号
  135.     ADXL345_SendByte(0xA6);           //发送设备地址+写信号
  136.     ADXL345_SendByte(0x32);                   //发送存储单元地址,从0x32开始        
  137.     ADXL345_Start();                          //起始信号
  138.     ADXL345_SendByte(0xA7);         //发送设备地址+读信号
  139.          for (i=0; i<6; i++)                      //连续读取6个地址数据,存储中BUF
  140.     {
  141.         BUF[i] = ADXL345_RecvByte();          //BUF[0]存储0x32地址中的数据
  142.         if (i == 5)ADXL345_SendACK(1);//最后一个数据需要回NOACK
  143.         else ADXL345_SendACK(0); //回应ACK
  144.    }
  145.     ADXL345_Stop();                          //停止信号
  146.     Delay5ms();
  147. }
  148. //初始化ADXL345,根据需要请参考pdf进行修改************************
  149. void Init_ADXL345()
  150. {
  151.    Single_Write_ADXL345(0x2C,0x08);   //速率设定为12.5
  152.    Single_Write_ADXL345(0x2D,0x08);   //选择电源模式   
  153.    Single_Write_ADXL345(0x31,0x0B);   //测量范围,正负16g,13位模式
  154. }
  155. void UartInit()                //9600bps@11.0592MHz
  156. {

  157.         SCON = 0x50;                //8位数据,可变波特率
  158.         AUXR |= 0x40;                //定时器1时钟为Fosc,即1T
  159.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  160.         TMOD &= 0x0F;                //设定定时器1为16位自动重装方式
  161.         TL1 = 0xE0;                //设定定时初值
  162.         TH1 = 0xFE;                //设定定时初值
  163.         ET1 = 0;                //禁止定时器1中断
  164.         TR1 = 1;                //启动定时器1
  165. }

  166. void Send()                                
  167. {
  168.         unsigned char i,j;
  169.         j=strlen(Sbuf);
  170.                 for(i=0;i<j;i++)
  171.                 {
  172.                         SBUF=Sbuf[i];
  173.                         while(!TI);
  174.                         TI=0;
  175.                 }
  176. }

  177. void Data_Process()                                          
  178. {
  179.         XYZ_data[0]=BUF[1]<<8|BUF[0];
  180.         XYZ_data[1]=BUF[3]<<8|BUF[2];
  181.         XYZ_data[2]=BUF[5]<<8|BUF[4];
  182.         
  183.         sprintf(Sbuf,"X=%d,Y=%d,Z=%d\n",XYZ_data[0],XYZ_data[1],XYZ_data[2]);
  184. }
  185. void Delay300ms()                //@11.0592MHz
  186. {
  187.         unsigned char i, j, k;

  188.         _nop_();
  189.         _nop_();
  190.         i = 13;
  191.         j = 156;
  192.         k = 83;
  193.         do
  194.         {
  195.                 do
  196.                 {
  197.                         while (--k);
  198.                 } while (--j);
  199.         } while (--i);
  200. }                                                                                
  201. void Delay5us()                //@11.0592MHz
  202. {
  203.         unsigned char i;

  204.         _nop_();
  205.         i = 11;
  206.         while (--i);
  207. }

  208. void Delay5ms()                //@11.0592MHz
  209. {
  210.         unsigned char i, j;

  211.         i = 54;
  212.         j = 199;
  213.         do
  214.         {
  215.                 while (--j);
  216.         } while (--i);
  217. }
复制代码

接受程序:
  1. #include "STC15F2K60S2.h"
  2. #define Go    0xAA                   //小车实际动作控制字符,以实物为准
  3. #define Back  0x55
  4. #define Left  0x5A
  5. #define Right 0xA5
  6. #define Stop  0x00
  7. void UartInit();
  8. unsigned char Rec_Data=0;

  9. void main()
  10. {
  11.         UartInit();

  12.         while(1)
  13.         {
  14.                 if(Rec_Data==Go||Rec_Data==Back||Rec_Data==Left||Rec_Data==Right||Rec_Data==Stop)
  15.                 P1=Rec_Data;
  16.                 else  P1=Stop;
  17.                
  18.         }

  19. }

  20. void UartInit()                //9600bps@11.0592MHz
  21. {
  22.         EA=1;                           //开总中断
  23.         ES=1;                           //开串口中断
  24.         SCON = 0x50;                //8位数据,可变波特率
  25.         AUXR |= 0x40;                //定时器1时钟为Fosc,即1T
  26.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  27.         TMOD &= 0x0F;                //设定定时器1为16位自动重装方式
  28.         TL1 = 0xE0;                //设定定时初值
  29.         TH1 = 0xFE;                //设定定时初值
  30.         ET1 = 0;                //禁止定时器1中断
  31.         TR1 = 1;                //启动定时器1
  32. }
  33. void uart_receive(void) interrupt 4
  34. {
  35.         if(RI)
  36.         {
  37. …………余下代码请下载附件…………
复制代码

源代码说明:由于使用的是STC15系列单片机,所以需要包含STC15F系列的头文件,之前没有上传,现在给不上了,或自行到STC官方网学习添加方法。
原理图说明:原理图分为小车驱动电路和手势控制电路。小车驱动电路和手势控制电路的蓝牙母座连线有所不同,请注意区分。驱动电路中SET脚和3V3脚是短接的,而手控部分无需短接。
L293D的输入端和单片机P1端口相连,
当P1输出字符“AA”时,电机M1、M2、M3、M4全部正转,小车前进
当P1输出字符“55”时,电机M1、M2、M3、M4全部反转,小车后退
当P1输出字符“5A”时,电机M1、M2反转,M3、M4正转,小车向左转
当P1输出字符“A5”时,电机M1、M2正转,M3、M4反转,小车向右转
当P1输出字符“00”时,电机M1、M2、M3、M4两端无电压,小车不动
工作室交流讨论群:231931086


下载:
手势遥控车资料包.zip (241.71 KB, 下载次数: 154)




评分

参与人数 4黑币 +16 收起 理由
stu + 1 很给力!
于维淼 + 5 很给力!
Mr.Ren + 5 赞一个!
17395063853 + 5

查看全部评分

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

使用道具 举报

沙发
ID:183063 发表于 2017-3-24 13:53 | 只看该作者
赞一个,51黑有你更精彩
回复

使用道具 举报

板凳
ID:255421 发表于 2017-11-30 13:08 | 只看该作者
太好了很好实用
回复

使用道具 举报

地板
ID:295060 发表于 2018-3-21 15:44 | 只看该作者

楼主你好,遥控部分的ADXL345和send的程序是烧在一个单片机上的吗?
回复

使用道具 举报

5#
ID:417866 发表于 2018-11-22 23:37 | 只看该作者
51黑有你更精彩
回复

使用道具 举报

6#
ID:141106 发表于 2018-11-25 10:03 | 只看该作者

51黑有你更精彩
回复

使用道具 举报

7#
ID:16462 发表于 2018-11-28 13:28 来自手机 | 只看该作者
学习一下,做一个玩玩
回复

使用道具 举报

8#
ID:438420 发表于 2018-12-4 22:10 | 只看该作者
对遥控车很感兴趣啊!!
回复

使用道具 举报

9#
ID:269931 发表于 2018-12-26 10:16 | 只看该作者
有没有关于这个车的论文?
回复

使用道具 举报

10#
ID:458340 发表于 2018-12-29 21:36 | 只看该作者
51黑有你更精彩
回复

使用道具 举报

11#
ID:478058 发表于 2019-2-19 13:24 | 只看该作者
谢谢你的分享,作为初学者感觉很给力!
回复

使用道具 举报

12#
ID:483023 发表于 2019-4-3 07:38 来自手机 | 只看该作者
作者你好,你的原理图没有降压模块,但你的作品里用到了降压模块,望补全原理图
回复

使用道具 举报

13#
ID:483023 发表于 2019-4-3 08:24 | 只看该作者
原理图没有降压模块啊,怎么办啊
回复

使用道具 举报

14#
ID:483023 发表于 2019-4-3 08:34 来自手机 | 只看该作者
本帖最后由 黑魔力 于 2019-4-3 10:39 编辑

很好,就是不知道程序怎么烧
回复

使用道具 举报

15#
ID:483023 发表于 2019-4-3 19:42 | 只看该作者
蓝牙模块有讲究吗
回复

使用道具 举报

16#
ID:505599 发表于 2019-4-11 14:35 | 只看该作者
感谢分享
回复

使用道具 举报

17#
ID:304358 发表于 2019-4-20 10:24 | 只看该作者
黑魔力 发表于 2019-4-3 07:38
作者你好,你的原理图没有降压模块,但你的作品里用到了降压模块,望补全原理图

怎么样做好了吗?
回复

使用道具 举报

18#
ID:304358 发表于 2019-4-20 10:26 | 只看该作者
黑魔力 发表于 2019-4-3 07:38
作者你好,你的原理图没有降压模块,但你的作品里用到了降压模块,望补全原理图

降压模块是不是只需要提供一个5v电源 给单片机供电
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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