找回密码
 立即注册

QQ登录

只需一步,快速开始

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

adxl345传感器计步器 单片机程序

[复制链接]
跳转到指定楼层
楼主
adxl345传感器计步器程序

  1. #include<reg52.h>
  2. #include<math.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int

  5. #include  <INTRINS.H>

  6. #define        SlaveAddress   0xA6          //1010 0110    定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
  7. sbit rs=P2^0;
  8. sbit rw=P2^1;
  9. sbit en=P2^2;                              //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A 0011 1010
  10. sbit sclk=P1^2;
  11. sbit sda=P1^3;
  12. sbit stop=P3^2;

  13. uchar BUF[8];                              //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A 0011 1010

  14. float  dis_datax,dis_datay,dis_dataz,acc,acc1=1000;

  15. uchar wan,qian,bai,shi ,ge,flag,miao,miao1,n,g,s,b;
  16. uint count,count_hou,cishu,v,a;


  17. void delay(uint z)
  18. {
  19.         uint x,y;
  20.         for(x=z;x>0;x--)
  21.                 for(y=110;y>0;y--);
  22. }

  23. void write_com(uchar com)
  24. {
  25.         rs=0;
  26.         P0=com;
  27.         delay(5);
  28.         en=1;
  29.         delay(5);
  30.         en=0;
  31. }
  32. void write_dat(uchar dat)
  33. {
  34.         rs=1;
  35.         P0=dat;
  36.         delay(1);
  37.         en=1;
  38.         delay(5);
  39.         en=0;
  40. }
  41. void init()
  42. {
  43.         rw=0;
  44.         en=0;
  45.         write_com(0x38);
  46.         write_com(0x0c);
  47.         write_com(0x06);
  48.         write_com(0x01);
  49. //        write_com(0x80+0x10);
  50. }

  51. void conversion(uint temp_data)  
  52. {  
  53.     wan=temp_data/10000+0x30 ;
  54.     temp_data=temp_data%10000;   //取余运算
  55.        
  56.         qian=temp_data/1000+0x30 ;
  57.     temp_data=temp_data%1000;    //取余运算
  58.    
  59.         bai=temp_data/100+0x30   ;
  60.     temp_data=temp_data%100;     //取余运算                                 -e----------------eee-e
  61.    
  62.         shi=temp_data/10+0x30    ;
  63.     temp_data=temp_data%10;      //取余运算
  64.    
  65.         ge=temp_data+0x30;        
  66. }
  67. void delay6us()                 //6us延时函数
  68. {

  69.         _nop_();        _nop_();          



  70. }

  71. void delay_ms(uint n)       //N ms延时函数
  72. {
  73.         uint x,y;
  74.         for(x=n;x>0;x--)
  75.                 for(y=110;y>0;y--);       
  76. }

  77.                                                                                                                                                                 /////

  78. void ADXL345_Start()
  79. {
  80.     sda = 1;                    //拉高数据线
  81.     sclk = 1;                    //拉高时钟线
  82.     delay6us();                 //延时
  83.     sda = 0;                    //产生下降沿
  84.     delay6us();                 //延时
  85.     sclk = 0;                    //拉低时钟线
  86. }

  87. void ADXL345_Stop()
  88. {
  89.     sda = 0;                    //拉低数据线
  90.     sclk = 1;                    //拉高时钟线
  91.     delay6us();                 //延时
  92.     sda = 1;                    //产生上升沿
  93.     delay6us();                 //延时
  94. }

  95. void ADXL345_SendACK(bit ack)
  96. {
  97.     sda = ack;                  //写应答信号
  98.     sclk = 1;                    //拉高时钟线
  99.     delay6us();                 //延时
  100.     sclk = 0;                    //拉低时钟线
  101.     delay6us();                 //延时
  102. }


  103. bit ADXL345_RecvACK()
  104. {
  105.     sclk = 1;                    //拉高时钟线
  106.     delay6us();                 //延时
  107.     CY = sda;                   //读应答信号
  108.     sclk = 0;                    //拉低时钟线
  109.     delay6us();                 //延时

  110.     return CY;
  111. }


  112. void ADXL345_SendByte(uchar dat)
  113. {
  114.     uchar i;
  115. //        sclk = 0;                //拉低时钟线

  116.     for (i=0; i<8; i++)         //8位计数器
  117.     {
  118.         dat <<= 1;              //移出数据的最高位
  119.         sda = CY;               //送数据口
  120.         sclk = 1;                //拉高时钟线
  121.         delay6us();             //延时
  122.         sclk = 0;                //拉低时钟线
  123.         delay6us();             //延时
  124.     }
  125.     ADXL345_RecvACK();
  126. }


  127. uchar ADXL345_RecvByte()
  128. {
  129.     uchar i;
  130.     uchar dat = 0;

  131.     sda = 1;
  132.         //        write_com(0x80);
  133.                    //使能内部上拉,准备读取数据,
  134.     for (i=0; i<8; i++)         //8位计数器
  135.     {
  136.         dat <<= 1;
  137.         sclk = 1;                //拉高时钟线
  138.         delay6us();             //延时
  139.         dat |= sda;             //读数据               
  140.         sclk = 0;                //拉低时钟线
  141.         delay6us();             //延时

  142.     }


  143.     return dat;
  144. }

  145. void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
  146. {
  147.     ADXL345_Start();                  //起始信号
  148.     ADXL345_SendByte(SlaveAddress);   //发送设备地址+写信号
  149.     ADXL345_SendByte(REG_Address);    //内部寄存器地址,请参考中文pdf22页
  150.     ADXL345_SendByte(REG_data);       //内部寄存器数据,请参考中文pdf22页
  151.     ADXL345_Stop();                   //发送停止信号
  152. }

  153. uchar Single_Read_ADXL345(uchar REG_Address)
  154. {
  155.         uchar REG_data;
  156.     ADXL345_Start();            //起始信号
  157.     ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号
  158.     ADXL345_SendByte(REG_Address);                   //发送存储单元地址,从0开始       
  159.     ADXL345_Start();                          //起始信号
  160.     ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号
  161.     REG_data=ADXL345_RecvByte();              //读出寄存器数据
  162.         ADXL345_SendACK(1);   
  163.         ADXL345_Stop();                           //停止信号
  164.     return REG_data;
  165. }

  166. void Multiple_read_ADXL345()
  167. {   
  168.         uchar i;
  169.     ADXL345_Start();                          //起始信号
  170.     ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号           1010 0110
  171.     ADXL345_SendByte(0x32);                   //发送存储单元地址,从0x32开始 0011 0010
  172.     ADXL345_Start();                          //起始信号
  173.     ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号           1010 0111
  174.         for (i=0; i<6; i++)                      //连续读取6个地址数据,存储中BUF
  175.     {
  176.         BUF[i] = ADXL345_RecvByte();          //BUF[0]存储0x32地址中的数据
  177.         if(i == 5)        ADXL345_SendACK(1);       //最后一个数据需要回NOACK
  178.         else        ADXL345_SendACK(0);           //回应ACK
  179.     }
  180.     ADXL345_Stop();                          //停止信号
  181.     delay_ms(10);
  182. }

  183. void Init_ADXL345()           //初始化ADXL345,根据需要请参考pdf进行修改***********************
  184. {
  185. //        delay(500);                                          //上电延时
  186.    Single_Write_ADXL345(0x31,0x2B);   //测量范围,正负16g,13位模式
  187.    Single_Write_ADXL345(0x2C,0x06);   //0000 0110速率设定为6.25 参考pdf13页
  188.    Single_Write_ADXL345(0x2D,0x08);   //选择电源模式   参考pdf24页
  189.    Single_Write_ADXL345(0x2E,0x80);   //使能 DATA_READY 中断
  190.    Single_Write_ADXL345(0x1E,0x00);   //X 偏移量 根据测试传感器的状态写入pdf29页
  191.    Single_Write_ADXL345(0x1F,0x00);   //Y 偏移量 根据测试传感器的状态写入pdf29页
  192.    Single_Write_ADXL345(0x20,0x05);   //Z 偏移量 根据测试传感器的状态写入pdf29页
  193. }


  194. float operation(uchar starti)
  195. {
  196.         float  dis_data        ;
  197.         int temp;
  198.         temp=(BUF[starti+1]<<8)+BUF[starti];  //合成数据
  199. //        write_com(0x80);  
  200.         if(temp<0)
  201.         {
  202.                 temp=-temp;
  203.                 flag=1;

  204.         }
  205.         else flag=0; //显示空格

  206.     dis_data=(float)temp*3.9;  //计算数据和显示,查考ADXL345快速入门第4页
  207.   return dis_data;
  208. }
  209. void display_x()         //显示x轴
  210. {   
  211.    conversion(dis_datax);          //转换出显示需要的数据
  212.    
  213.         write_com(0x80);
  214.         if(flag==0)        write_dat(' ');
  215.         else write_dat('-');
  216.         write_dat('X');
  217.         write_dat(':');
  218.         write_dat(qian);

  219.         write_dat('.');
  220.         write_dat(bai);
  221.         write_dat(shi);
  222.         write_dat('g');       
  223.        
  224.                                   write_dat(' ');
  225.                                                                                                                 write_dat('v');
  226.                                                                                                                 write_dat(':');
  227.                                                                                                                 write_dat(v/100+0x30);
  228.                                   write_dat((v%100)/10+0x30);
  229.                                   write_dat(v%10+0x30);
  230. }

  231. void display_y()        //显示y轴
  232. {   
  233.    
  234.   // dis_datay=operation(2);
  235.     conversion(dis_datay);          //转换出显示需要的数据
  236.         write_com(0x80+8);
  237.         if(flag==0)         write_dat(' ');
  238.         else write_dat('-');
  239.         write_dat('Y');
  240.         write_dat(':');
  241.         write_dat(qian);

  242.         write_dat('.');
  243.         write_dat(bai);
  244.         write_dat(shi);
  245.         write_dat('g');

  246.        
  247.                                   write_dat(' ');
  248.                                                                                                                 write_dat('v');
  249.                                                                                                                 write_dat(':');
  250.                                                                                                                 write_dat(v/100+0x30);
  251.                                   write_dat((v%100)/10+0x30);
  252.                                   write_dat(v%10+0x30);
  253. }

  254. void display_z()           //显示z轴
  255. {  

  256. //  dis_dataz=operation(4);
  257.     conversion(dis_dataz);           //转换出显示需要的数据
  258.         write_com(0x80+0x40);
  259.         if(flag==0)                  write_dat(' ');
  260.         else write_dat('-');
  261.         write_dat('Z');
  262.         write_dat(':');
  263.         write_dat(qian);

  264.         write_dat('.');
  265.         write_dat(bai);
  266.         write_dat(shi);
  267.         write_dat('g');
  268.         ///gai  guo
  269.                                   write_dat(' ');
  270.                                                                                                                 write_dat('v');
  271.                                                                                                                 write_dat(':');
  272.                                                                                                                 write_dat(v/100+0x30);
  273.                                   write_dat((v%100)/10+0x30);
  274.                                   write_dat(v%10+0x30);
  275.        
  276. }

  277. void countstep()
  278. {
  279.         dis_datax=operation(0);
  280.         dis_datay=operation(2);
  281.    dis_dataz=operation(4);

  282.         acc1=acc;
  283.         acc=sqrt(dis_dataz*dis_dataz+dis_datax*dis_datax+dis_datay*dis_datay)  ;
  284.         if(acc1<990&&acc>1010)
  285. //        if(fabs(acc-acc1)>140&&miao1!=miao)

  286.         {//if(stop=0)
  287.         //        miao1=miao;
  288.                 count++;
  289.         }
  290.        
  291.        
  292.         write_com(0x80);
  293.         conversion(acc);
  294.         write_dat('A');
  295.         write_dat(':');
  296.         write_dat(qian);

  297.         write_dat('.');
  298.         write_dat(bai);
  299.         write_dat(shi);
  300.         write_dat('g');
  301.        
  302.                           write_dat(' ');
  303.         write_dat('v');
  304.         write_dat(':');
  305.         write_dat(v/100+0x30);
  306.         write_dat((v%100)/10+0x30);
  307.     write_dat(v%10+0x30);
  308.         write_com(0x80+0x40);
  309.         write_dat('C');
  310.         write_dat('o');
  311.         write_dat('u');
  312.         write_dat('n');
  313.         write_dat('t');
  314.         write_dat(':');
  315.         write_dat(count_hou/100+0x30);
  316.         write_dat((count_hou%100)/10+0x30);
  317.         write_dat(count_hou%10+0x30);


  318. }
  319. void ADXL345_Measure()                         //测量角度值并显示
  320. {
  321.         Multiple_read_ADXL345();     //连续读出数据,存储在BUF中
  322.         countstep();

  323. }



  324. void main()
  325. {
  326.         unsigned int j,k=1;
  327.         stop=1;
  328.         init();

  329.         TMOD=0X01;                        //设置定时器0为模式一,即16位计算模式
  330.   TH0 =(65536-50000)/256;
  331.   TL0 =(65536-50000)%256;
  332.         EA=1;                //开启总中断
  333.         ET0=1;                //开启定时器0中断
  334.         TR0=1;                //启动定时器0
  335.        
  336.        
  337.         write_com(0x80);
  338.         write_dat('O');
  339.         write_dat('N');
  340.         delay(1500);
  341.         Init_ADXL345();
  342.        
  343.         while(1)
  344.         {
  345.                                                 if(stop==0)                //检测按键K1是否按下
  346.                                                 {
  347.                                                                 delay(10);//消除抖动
  348.                                                                 if(stop==0)
  349.                                                                 {
  350.                                                                                                                 while(k==1)
  351.                                                                                                         {
  352.                                                                                                                         j=count;
  353.                                                                                                                         count_hou=j;
  354.                                                                                                                         write_com(0x80);
  355.                                                                                                                         conversion(acc);
  356.                                                                                                                        
  357.                                                                                                                         write_dat('s');
  358.                               write_dat('t');
  359.                                                                                                                         write_dat('o');
  360.                                                                                                                         write_dat('p');
  361.                                                                                                                         write_dat('!');
  362.                                                                                                                  write_dat(' ');
  363.                                                                                                                 write_dat(' ');
  364.                                                                                                                 write_dat(' ');
  365.                                                                                                                
  366.                                                                                                                 write_dat('v');
  367.                                                                                                                 write_dat(':');
  368.                                                                                                                 write_dat(v/100+0x30);
  369.                                   write_dat((v%100)/10+0x30);
  370.                                   write_dat(v%10+0x30);
  371.                                                                                                                 EA=0;
  372.                                                                                                                         delay(1000);
  373.                                                                                                                         delay(100);
  374.                                                                                                                  
  375.                                                                                                                                 if(stop==0)
  376.                                                                                                                                 {
  377.                                                                                                                                         Init_ADXL345();
  378.                                                                                                                                  count=0;
  379.                                                                                                                                         k=0;
  380.                                                                                                                                         EA=1;
  381.                                                                                                                                 }                                                                                                               
  382.                                                                                                         }                                                               
  383.                                                                 }
  384.                                                 }               
  385.         count_hou=count;       
  386.         ADXL345_Measure();

  387.   }       
  388. }


  389. void timeinit()
  390. {
  391.         TMOD=0X01;                        //设置定时器0为模式一,即16位计算模式
  392.   TH0 =(65536-50000)/256;
  393.   TL0 =(65536-50000)%256;
  394.         EA=1;                //开启总中断
  395.         ET0=1;                //开启定时器0中断
  396.         TR0=1;                //启动定时器0
  397.        
  398. }

  399. void time0(void) interrupt 1
  400. {
  401.   TH0 =(65536-50000)/256;
  402.   TL0 =(65536-50000)%256;
  403.         cishu++;
  404.         if(cishu>=100)
  405.         {
  406.           cishu=0;
  407.                
  408.                 v=(count-a)*12;
  409.                 a=count;
  410.         }
  411.        
  412. }
复制代码


计步器.zip

41.91 KB, 下载次数: 58, 下载积分: 黑币 -5

计步器测试程序.zip

39.73 KB, 下载次数: 42, 下载积分: 黑币 -5

计步器最小系统.zip

6.27 MB, 下载次数: 43, 下载积分: 黑币 -5

评分

参与人数 1黑币 +5 收起 理由
兜蔸窦 + 5 绝世好帖!

查看全部评分

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

使用道具 举报

沙发
ID:143128 发表于 2016-10-17 22:36 | 只看该作者
这是完整的代码了吗 不是部分代码吗?怎么没有1602头文件
回复

使用道具 举报

板凳
ID:107115 发表于 2016-10-18 18:58 | 只看该作者
fresh 发表于 2016-10-17 22:36
这是完整的代码了吗 不是部分代码吗?怎么没有1602头文件

都在main.c里头,这是比赛预赛题,我亲自做出来的,绝对可用
回复

使用道具 举报

地板
ID:143128 发表于 2016-10-19 11:01 | 只看该作者
复印件腹黑攻 发表于 2016-10-18 18:58
都在main.c里头,这是比赛预赛题,我亲自做出来的,绝对可用

可是我下载下来打开main.c是空的 ,你可以共享一下你的仿真图吗?  我有点想不明白仿真图怎么显示效果的,又不能移动
回复

使用道具 举报

5#
ID:143128 发表于 2016-10-19 11:07 | 只看该作者
复印件腹黑攻 发表于 2016-10-18 18:58
都在main.c里头,这是比赛预赛题,我亲自做出来的,绝对可用

你能把程序加仿真图发到我邮箱吗?374122506@qq.com 谢谢
回复

使用道具 举报

6#
ID:143128 发表于 2016-10-19 11:10 | 只看该作者
复印件腹黑攻 发表于 2016-10-18 18:58
都在main.c里头,这是比赛预赛题,我亲自做出来的,绝对可用

能给个QQ号码吗
回复

使用道具 举报

7#
ID:154881 发表于 2016-12-15 00:17 | 只看该作者
有仿真图吗  我在做实物  遇到了瓶颈
回复

使用道具 举报

8#
ID:161764 发表于 2017-1-14 17:09 | 只看该作者
我打开main.c也是一片空白
回复

使用道具 举报

9#
ID:171386 发表于 2017-3-16 22:45 | 只看该作者
谢谢啦
回复

使用道具 举报

10#
ID:188124 发表于 2017-4-11 20:37 | 只看该作者
感谢分享!
回复

使用道具 举报

11#
ID:299262 发表于 2018-6-6 15:53 | 只看该作者
谢谢分享,学习一下!
回复

使用道具 举报

12#
ID:299262 发表于 2018-6-6 15:54 | 只看该作者

感谢分享!
回复

使用道具 举报

13#
ID:515167 发表于 2019-4-19 14:36 | 只看该作者
楼主,这个a和v是显示什么,我最近也在做这个,能指导一下吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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