找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12368|回复: 21
收起左侧

基于51单片机和GY-29 ADXL345传感器的计步器设计

  [复制链接]
ID:151000 发表于 2017-1-11 15:05 | 显示全部楼层 |阅读模式
分享一个计步器设计文件
这是一个基于51单片机 GY-29 ADXL345三轴加速度传感器的计步器
压缩包里的文件截图如下:
资料截图.png
这个计步器有开机出现“WELCOME!”(欢迎使用!)的界面,很好的交互性。
IMG_1327(20170105-192907).jpg

Z代表总步数,L代表总路程,单位(m),Steps代表的是步数。
IMG_1326(20170105-192931).jpg

总体来说,这个计步器的性能还是很不错的。但是,有一个缺点就是没有断电记忆功能,通俗的说就是断开电源后数据会丢失。不过只要一直有电就不会出现这种情况!
番外:
我也是一个在校大学生。这是我12月份做的一个项目,当时为了做好这个项目连续一个星期熬夜到凌晨两点,甚是艰苦!也在网上查阅了不少资料,我也是在这个时候找到了咱们51hei 电子论坛!很是幸运~在这里我也找到了不少有用的资料!非常感谢论坛里的大神们以及帮助过我的所有人
本着“我为人人,人人为我”的精神,我也感触深刻的明白有一份清晰明了的资料的重要性,所以我昨天用了一天的时间将资料整理打包好。今天上传上来,希望能给同学们力所能及的帮助!
  1. #include  <REG51.H>        
  2. #include  <math.h>    //Keil library  
  3. #include  <stdio.h>   //Keil library        
  4. #include  <INTRINS.H>
  5. #define   uchar unsigned char
  6. #define   uint unsigned int        
  7. #define   DataPort P0    //LCD1602数据端口
  8. sbit          SCL=P1^0;      //IIC时钟引脚定义
  9. sbit           SDA=P1^1;      //IIC数据引脚定义
  10. sbit      LCM_RS=P2^0;   //LCD1602命令端口               
  11. sbit      LCM_RW=P2^1;   //LCD1602命令端口               
  12. sbit      LCM_EN=P2^2;   //LCD1602命令端口

  13. #define        SlaveAddress   0xA6          //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
  14.                               //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A
  15. typedef unsigned char  BYTE;
  16. typedef unsigned short WORD;

  17. BYTE BUF[8];                         //接收数据缓存区              
  18. uchar ge,shi,bai,qian,wan;           //显示变量
  19. int  dis_data;                       //变量

  20. void delay(unsigned int k);
  21. void InitLcd();                      //初始化lcd1602
  22. void Init_ADXL345(void);             //初始化ADXL345

  23. void WriteDataLCM(uchar dataW);
  24. void WriteCommandLCM(uchar CMD,uchar Attribc);
  25. void DisplayOneChar(uchar X,uchar Y,uchar DData);
  26. void conversion(uint temp_data);

  27. void  Single_Write_ADXL345(uchar REG_Address,uchar REG_data);   //单个写入数据
  28. uchar Single_Read_ADXL345(uchar REG_Address);                   //单个读取内部寄存器数据
  29. void  Multiple_Read_ADXL345();                                  //连续的读取内部寄存器数据
  30. //------------------------------------
  31. void Delay5us();
  32. void Delay5ms();
  33. void ADXL345_Start();
  34. void ADXL345_Stop();
  35. void ADXL345_SendACK(bit ack);
  36. bit  ADXL345_RecvACK();
  37. void ADXL345_SendByte(BYTE dat);
  38. BYTE ADXL345_RecvByte();
  39. void ADXL345_ReadPage();
  40. void ADXL345_WritePage();
  41. //-----------------------------------

  42. //*********************************************************
  43. void conversion(uint temp_data)  
  44. {  
  45.     wan=temp_data/10000+0x30 ;
  46.     temp_data=temp_data%10000;   //取余运算
  47.         qian=temp_data/1000+0x30 ;
  48.     temp_data=temp_data%1000;    //取余运算
  49.     bai=temp_data/100+0x30   ;
  50.     temp_data=temp_data%100;     //取余运算
  51.     shi=temp_data/10+0x30    ;
  52.     temp_data=temp_data%10;      //取余运算
  53.     ge=temp_data+0x30;         
  54. }

  55. /*******************************/
  56. void delay(unsigned int k)        
  57. {                                                
  58. unsigned int i,j;                                
  59. for(i=0;i<k;i++)
  60. {                        
  61. for(j=0;j<121;j++)                        
  62. {;}}                                                
  63. }
  64. /*******************************/
  65. void WaitForEnable(void)        
  66. {                                       
  67. DataPort=0xff;               
  68. LCM_RS=0;LCM_RW=1;_nop_();
  69. LCM_EN=1;_nop_();_nop_();
  70. while(DataPort&0x80);        
  71. LCM_EN=0;                                
  72. }                                       
  73. /*******************************/
  74. void WriteCommandLCM(uchar CMD,uchar Attribc)
  75. {                                       
  76. if(Attribc)WaitForEnable();        
  77. LCM_RS=0;LCM_RW=0;_nop_();
  78. DataPort=CMD;_nop_();        
  79. LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  80. }                                       
  81. /*******************************/
  82. void WriteDataLCM(uchar dataW)
  83. {                                       
  84. WaitForEnable();               
  85. LCM_RS=1;LCM_RW=0;_nop_();
  86. DataPort=dataW;_nop_();        
  87. LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  88. }               
  89. /***********************************/
  90. void InitLcd()                                
  91. {                        
  92. WriteCommandLCM(0x38,1);        
  93. WriteCommandLCM(0x08,1);        
  94. WriteCommandLCM(0x01,1);        
  95. WriteCommandLCM(0x06,1);        
  96. WriteCommandLCM(0x0c,1);
  97. }                        
  98. /***********************************/
  99. void DisplayOneChar(uchar X,uchar Y,uchar DData)
  100. {                                                
  101. Y&=1;                                                
  102. X&=15;                                                
  103. if(Y)X|=0x40;                                       
  104. X|=0x80;                        
  105. WriteCommandLCM(X,0);               
  106. WriteDataLCM(DData);               
  107. }                                                

  108. /**************************************
  109. 延时5微秒(STC90C52RC@12M)
  110. 不同的工作环境,需要调整此函数,注意时钟过快时需要修改
  111. 当改用1T的MCU时,请调整此延时函数
  112. **************************************/
  113. void Delay5us()
  114. {
  115.     _nop_();_nop_();_nop_();_nop_();
  116.     _nop_();_nop_();_nop_();_nop_();
  117.         _nop_();_nop_();_nop_();_nop_();
  118. }

  119. /**************************************
  120. 延时5毫秒(STC90C52RC@12M)
  121. 不同的工作环境,需要调整此函数
  122. 当改用1T的MCU时,请调整此延时函数
  123. **************************************/
  124. void Delay5ms()
  125. {
  126.     WORD n = 560;

  127.     while (n--);
  128. }

  129. /**************************************
  130. 起始信号
  131. **************************************/
  132. void ADXL345_Start()
  133. {
  134.     SDA = 1;                    //拉高数据线
  135.     SCL = 1;                    //拉高时钟线
  136.     Delay5us();                 //延时
  137.     SDA = 0;                    //产生下降沿
  138.     Delay5us();                 //延时
  139.     SCL = 0;                    //拉低时钟线
  140. }

  141. /**************************************
  142. 停止信号
  143. **************************************/
  144. void ADXL345_Stop()
  145. {
  146.     SDA = 0;                    //拉低数据线
  147.     SCL = 1;                    //拉高时钟线
  148.     Delay5us();                 //延时
  149.     SDA = 1;                    //产生上升沿
  150.     Delay5us();                 //延时
  151. }

  152. /**************************************
  153. 发送应答信号
  154. 入口参数:ack (0:ACK 1:NAK)
  155. **************************************/
  156. void ADXL345_SendACK(bit ack)
  157. {
  158.     SDA = ack;                  //写应答信号
  159.     SCL = 1;                    //拉高时钟线
  160.     Delay5us();                 //延时
  161.     SCL = 0;                    //拉低时钟线
  162.     Delay5us();                 //延时
  163. }

  164. /**************************************
  165. 接收应答信号
  166. **************************************/
  167. bit ADXL345_RecvACK()
  168. {
  169.     SCL = 1;                    //拉高时钟线
  170.     Delay5us();                 //延时
  171.     CY = SDA;                   //读应答信号
  172.     SCL = 0;                    //拉低时钟线
  173.     Delay5us();                 //延时

  174.     return CY;
  175. }

  176. /**************************************
  177. 向IIC总线发送一个字节数据
  178. **************************************/
  179. void ADXL345_SendByte(BYTE dat)
  180. {
  181.     BYTE i;

  182.     for (i=0; i<8; i++)         //8位计数器
  183.     {
  184.         dat <<= 1;              //移出数据的最高位
  185.         SDA = CY;               //送数据口
  186.         SCL = 1;                //拉高时钟线
  187.         Delay5us();             //延时
  188.         SCL = 0;                //拉低时钟线
  189.         Delay5us();             //延时
  190.     }
  191.     ADXL345_RecvACK();
  192. }

  193. /**************************************
  194. 从IIC总线接收一个字节数据
  195. **************************************/
  196. BYTE ADXL345_RecvByte()
  197. {
  198.     BYTE i;
  199.     BYTE dat = 0;

  200.     SDA = 1;                    //使能内部上拉,准备读取数据,
  201.     for (i=0; i<8; i++)         //8位计数器
  202.     {
  203.         dat <<= 1;
  204.         SCL = 1;                //拉高时钟线
  205.         Delay5us();             //延时
  206.         dat |= SDA;             //读数据               
  207.         SCL = 0;                //拉低时钟线
  208.         Delay5us();             //延时
  209.     }
  210.     return dat;
  211. }

  212. //******单字节写入*******************************************

  213. void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
  214. {
  215.     ADXL345_Start();                  //起始信号
  216.     ADXL345_SendByte(SlaveAddress);   //发送设备地址+写信号
  217.     ADXL345_SendByte(REG_Address);    //内部寄存器地址,请参考中文pdf22页
  218.     ADXL345_SendByte(REG_data);       //内部寄存器数据,请参考中文pdf22页
  219.     ADXL345_Stop();                   //发送停止信号
  220. }

  221. //********单字节读取*****************************************
  222. uchar Single_Read_ADXL345(uchar REG_Address)
  223. {  uchar REG_data;
  224.     ADXL345_Start();                          //起始信号
  225.     ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号
  226.     ADXL345_SendByte(REG_Address);                   //发送存储单元地址,从0开始        
  227.     ADXL345_Start();                          //起始信号
  228.     ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号
  229.     REG_data=ADXL345_RecvByte();              //读出寄存器数据
  230.         ADXL345_SendACK(1);   
  231.         ADXL345_Stop();                           //停止信号
  232.     return REG_data;
  233. }
  234. //*********************************************************
  235. //
  236. //连续读出ADXL345内部加速度数据,地址范围0x32~0x37
  237. //
  238. //*********************************************************
  239. void Multiple_read_ADXL345(void)
  240. {   uchar i;
  241.     ADXL345_Start();                          //起始信号
  242.     ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号
  243.     ADXL345_SendByte(0x32);                   //发送存储单元地址,从0x32开始        
  244.     ADXL345_Start();                          //起始信号
  245.     ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号
  246.          for (i=0; i<6; i++)                      //连续读取6个地址数据,存储中BUF
  247.     {
  248.         BUF[i] = ADXL345_RecvByte();          //BUF[0]存储0x32地址中的数据
  249.         if (i == 5)
  250.         {
  251.            ADXL345_SendACK(1);                //最后一个数据需要回NOACK
  252.         }
  253.         else
  254.         {
  255.           ADXL345_SendACK(0);                //回应ACK
  256.        }
  257.    }
  258.     ADXL345_Stop();                          //停止信号
  259.     Delay5ms();
  260. }


  261. //*****************************************************************

  262. //初始化ADXL345,根据需要请参考pdf进行修改************************
  263. void Init_ADXL345()
  264. {
  265.    Single_Write_ADXL345(0x31,0x0B);   //测量范围,正负16g,13位模式
  266.    Single_Write_ADXL345(0x2C,0x08);   //速率设定为12.5 参考pdf13页
  267.    Single_Write_ADXL345(0x2D,0x08);   //选择电源模式   参考pdf24页
  268.    Single_Write_ADXL345(0x2E,0x80);   //使能 DATA_READY 中断
  269.    Single_Write_ADXL345(0x1E,0x00);   //X 偏移量 根据测试传感器的状态写入pdf29页
  270.    Single_Write_ADXL345(0x1F,0x00);   //Y 偏移量 根据测试传感器的状态写入pdf29页
  271.    Single_Write_ADXL345(0x20,0x05);   //Z 偏移量 根据测试传感器的状态写入pdf29页
  272. }
  273. //***********************************************************************
  274. //显示x轴
  275. void display_x()
  276. {   float temp;
  277.     dis_data=(BUF[1]<<8)+BUF[0];  //合成数据   
  278.         if(dis_data<0){
  279.         dis_data=-dis_data;
  280.     DisplayOneChar(2,0,'-');      //显示正负符号位
  281.         }
  282.         else DisplayOneChar(2,0,' '); //显示空格

  283.     temp=(float)dis_data*3.9;  //计算数据和显示,查考ADXL345快速入门第4页
  284.     conversion(temp);          //转换出显示需要的数据
  285.         DisplayOneChar(0,0,'X');   //第0行,第0列 显示X
  286.     DisplayOneChar(1,0,':');
  287.     DisplayOneChar(3,0,qian);
  288.         DisplayOneChar(4,0,'.');
  289.     DisplayOneChar(5,0,bai);
  290.     DisplayOneChar(6,0,shi);
  291.         DisplayOneChar(7,0,'g');
  292. }

  293. //***********************************************************************
  294. //显示y轴
  295. void display_y()
  296. {     float temp;
  297.     dis_data=(BUF[3]<<8)+BUF[2];  //合成数据   
  298.         if(dis_data<0){
  299.         dis_data=-dis_data;
  300.     DisplayOneChar(2,1,'-');      //显示正负符号位
  301.         }
  302.         else DisplayOneChar(2,1,' '); //显示空格

  303.     temp=(float)dis_data*3.9;  //计算数据和显示,查考ADXL345快速入门第4页
  304.     conversion(temp);          //转换出显示需要的数据
  305.         DisplayOneChar(0,1,'Y');   //第1行,第0列 显示y
  306.     DisplayOneChar(1,1,':');
  307.     DisplayOneChar(3,1,qian);
  308.         DisplayOneChar(4,1,'.');
  309.     DisplayOneChar(5,1,bai);
  310.     DisplayOneChar(6,1,shi);  
  311.         DisplayOneChar(7,1,'g');  
  312. }

  313. //***********************************************************************
  314. //显示z轴
  315. void display_z()
  316. {      float temp;
  317.     dis_data=(BUF[5]<<8)+BUF[4];    //合成数据   
  318.         if(dis_data<0){
  319.         dis_data=-dis_data;
  320.     DisplayOneChar(10,1,'-');       //显示负符号位
  321.         }
  322.         else DisplayOneChar(10,1,' ');  //显示空格

  323.     temp=(float)dis_data*3.9;  //计算数据和显示,查考ADXL345快速入门第4页
  324.     conversion(temp);          //转换出显示需要的数据
  325.         DisplayOneChar(10,0,'Z');  //第0行,第10列 显示Z
  326.     DisplayOneChar(11,0,':');
  327.     DisplayOneChar(11,1,qian);
  328.         DisplayOneChar(12,1,'.');
  329.     DisplayOneChar(13,1,bai);
  330.     DisplayOneChar(14,1,shi);
  331.         DisplayOneChar(15,1,'g');  
  332. }


  333. //*********************************************************
  334. //******主程序********
  335. //*********************************************************
  336. void main()
  337. {
  338.   uchar devid;
  339.   delay(500);                           //上电延时               
  340.   InitLcd();                      //液晶初始化ADXL345
  341.   Init_ADXL345();                 //初始化ADXL345
  342.   devid=Single_Read_ADXL345(0X00);//读出的数据为0XE5,表示正确
  343.   while(1)                         //循环
  344.   {
  345.     Multiple_Read_ADXL345();       //连续读出数据,存储在BUF中
  346.     display_x();                   //---------显示X轴
  347.     display_y();                   //---------显示Y轴
  348.     display_z();                   //---------显示Z轴
  349.     delay(200);                    //延时            
  350.   }
  351. }
复制代码


所有制作资料下载:
基于单片机 GY-29ADXL345传感器计步器设计.zip (12.72 MB, 下载次数: 430)

评分

参与人数 2黑币 +108 收起 理由
wangtao123 + 8 共享资料的黑币奖励!
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:89286 发表于 2017-2-2 08:26 | 显示全部楼层
thanks for sharing
回复

使用道具 举报

ID:129081 发表于 2017-3-22 20:32 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:186896 发表于 2017-4-8 13:27 | 显示全部楼层
楼主大人,我看您分享的压缩包只有一个main.c 和一个.h文件。里面貌似没有计算步数的算法程序吧
回复

使用道具 举报

ID:202660 发表于 2017-5-19 20:03 来自手机 | 显示全部楼层
thanks for sharing
回复

使用道具 举报

ID:164371 发表于 2017-6-4 21:18 | 显示全部楼层
好厉害
回复

使用道具 举报

ID:164371 发表于 2017-6-4 21:18 | 显示全部楼层
好厉害
回复

使用道具 举报

ID:285028 发表于 2018-2-23 18:22 | 显示全部楼层
谢谢啦
回复

使用道具 举报

ID:302766 发表于 2018-4-12 10:31 | 显示全部楼层
赞美楼主
回复

使用道具 举报

ID:363710 发表于 2018-7-3 09:56 | 显示全部楼层
谢谢楼主
回复

使用道具 举报

ID:363710 发表于 2018-7-3 09:59 | 显示全部楼层
赞美楼主
回复

使用道具 举报

ID:364936 发表于 2018-7-4 16:23 | 显示全部楼层
很有用,刚好在弄相关项目,借鉴一哈楼主的帖子。
回复

使用道具 举报

ID:365463 发表于 2018-7-5 11:12 | 显示全部楼层
谢谢,楼主大人
回复

使用道具 举报

ID:365463 发表于 2018-7-5 11:12 | 显示全部楼层
谢谢楼主大人
回复

使用道具 举报

ID:387247 发表于 2018-8-30 16:28 | 显示全部楼层
老哥能不能把你的代码给一下
回复

使用道具 举报

ID:115061 发表于 2018-11-23 18:09 | 显示全部楼层
这没有计步器算法
回复

使用道具 举报

ID:479008 发表于 2019-3-27 17:26 | 显示全部楼层
只是一个测试程序,没有算法的。
回复

使用道具 举报

ID:501442 发表于 2019-3-30 21:58 | 显示全部楼层
楼主我想问下你用什么软件仿真呢,我用的proteus没有adxl345这个元器件
回复

使用道具 举报

ID:512398 发表于 2019-4-21 22:34 | 显示全部楼层
我不知道- 发表于 2019-3-30 21:58
楼主我想问下你用什么软件仿真呢,我用的proteus没有adxl345这个元器件

朋友你找到了吗?带ADXL345的元件库
回复

使用道具 举报

ID:512398 发表于 2019-4-21 22:38 | 显示全部楼层
求楼主protues元件库。我的元件库里没有ADXL模块啊。求大佬分享
回复

使用道具 举报

ID:198530 发表于 2019-4-22 11:25 | 显示全部楼层
程序和图片上的现象不符。。。也没有计步算法
回复

使用道具 举报

ID:92810 发表于 2019-5-27 10:46 | 显示全部楼层
谢谢楼主分享了啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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