找回密码
 立即注册

QQ登录

只需一步,快速开始

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

用ADXL345做的计步器(带温度显示)附程序和ADXL345中文PDF

  [复制链接]
跳转到指定楼层
楼主
免费下哦(PS:有部分资料是从51黑论坛里找的哦)

全部资料下载(带ADXL345中文PDF):
基于ADXL345的计步器.zip (961.37 KB, 下载次数: 471)



主程序预览:
  1. #include  <reg52.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. sbit          SCL=P3^1;      //IIC时钟引脚定义
  8. sbit           SDA=P3^2;      //IIC数据引脚定义
  9. sbit          key=P3^7;      //按键引脚定义

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


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

  17. bit flag1s = 0;          //1s定时标志

  18. uint num1=0,num2=0;  //1总步数,2步数
  19. int aaa=0;           //不重复变量

  20. void Init_ADXL345(void);             //初始化ADXL345

  21. void ConfigTimer0(unsigned int ms);
  22. unsigned char IntToString(unsigned char *str, int dat);
  23. extern bit Start18B20();
  24. extern bit Get18B20Temp(int *temp);
  25. extern void delay(unsigned int k);
  26. extern void Lcd_init();
  27. extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);//定义指针变量,把字符串数组的地址送到该指针变量上(便于指向X并显示X)
  28. extern void DisplayOneChar(uchar x, uchar y, uchar str);
  29. void conversion(uint temp_data);

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

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

  58.                                        

  59. /**************************************
  60. 延时5微秒(STC90C52RC---12MHz---12T)
  61. 不同的工作环境,需要调整此函数,注意时钟过快时需要修改
  62. 当改用1T的MCU时,请调整此延时函数
  63. **************************************/
  64. void Delay5us()
  65. {
  66.     _nop_();_nop_();_nop_();_nop_();
  67.     _nop_();_nop_();_nop_();_nop_();
  68.         _nop_();_nop_();_nop_();_nop_();
  69. }

  70. /**************************************
  71. 延时5毫秒(STC90C52RC@12M)
  72. 不同的工作环境,需要调整此函数
  73. 当改用1T的MCU时,请调整此延时函数
  74. **************************************/
  75. void Delay5ms()
  76. {
  77.     WORD n = 560;

  78.     while (n--);
  79. }

  80. /**************************************
  81. 起始信号
  82. **************************************/
  83. void ADXL345_Start()
  84. {
  85.     SDA = 1;                    //拉高数据线
  86.     SCL = 1;                    //拉高时钟线
  87.     Delay5us();                 //延时
  88.     SDA = 0;                    //产生下降沿
  89.     Delay5us();                 //延时
  90.     SCL = 0;                    //拉低时钟线
  91. }

  92. /**************************************
  93. 停止信号
  94. **************************************/
  95. void ADXL345_Stop()
  96. {
  97.     SDA = 0;                    //拉低数据线
  98.     SCL = 1;                    //拉高时钟线
  99.     Delay5us();                 //延时
  100.     SDA = 1;                    //产生上升沿
  101.     Delay5us();                 //延时
  102. }

  103. /**************************************
  104. 发送应答信号
  105. 入口参数:ack (0:ACK 1:NAK)
  106. **************************************/
  107. void ADXL345_SendACK(bit ack)
  108. {
  109.     SDA = ack;                  //写应答信号
  110.     SCL = 1;                    //拉高时钟线
  111.     Delay5us();                 //延时
  112.     SCL = 0;                    //拉低时钟线
  113.     Delay5us();                 //延时
  114. }

  115. /**************************************
  116. 接收应答信号
  117. **************************************/
  118. bit ADXL345_RecvACK()
  119. {
  120.     SCL = 1;                    //拉高时钟线
  121.     Delay5us();                 //延时
  122.     CY = SDA;                   //读应答信号
  123.     SCL = 0;                    //拉低时钟线
  124.     Delay5us();                 //延时

  125.     return CY;
  126. }

  127. /**************************************
  128. 向IIC总线发送一个字节数据
  129. **************************************/
  130. void ADXL345_SendByte(BYTE dat)
  131. {
  132.     BYTE i;

  133.     for (i=0; i<8; i++)         //8位计数器
  134.     {
  135.         dat <<= 1;              //移出数据的最高位
  136.         SDA = CY;               //送数据口
  137.         SCL = 1;                //拉高时钟线
  138.         Delay5us();             //延时
  139.         SCL = 0;                //拉低时钟线
  140.         Delay5us();             //延时
  141.     }
  142.     ADXL345_RecvACK();
  143. }

  144. /**************************************
  145. 从IIC总线接收一个字节数据
  146. **************************************/
  147. BYTE ADXL345_RecvByte()
  148. {
  149.     BYTE i;
  150.     BYTE dat = 0;

  151.     SDA = 1;                    //使能内部上拉,准备读取数据,
  152.     for (i=0; i<8; i++)         //8位计数器
  153.     {
  154.         dat <<= 1;
  155.         SCL = 1;                //拉高时钟线
  156.         Delay5us();             //延时
  157.         dat |= SDA;             //读数据               
  158.         SCL = 0;                //拉低时钟线
  159.         Delay5us();             //延时
  160.     }
  161.     return dat;
  162. }

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

  164. void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
  165. {
  166.     ADXL345_Start();                  //起始信号
  167.     ADXL345_SendByte(SlaveAddress);   //发送设备地址+写信号
  168.     ADXL345_SendByte(REG_Address);    //内部寄存器地址,请参考中文pdf22页
  169.     ADXL345_SendByte(REG_data);       //内部寄存器数据,请参考中文pdf22页
  170.     ADXL345_Stop();                   //发送停止信号
  171. }

  172. //********单字节读取*****************************************
  173. /*uchar Single_Read_ADXL345(uchar REG_Address)
  174. {   uchar REG_data;
  175.     ADXL345_Start();                          //起始信号
  176.     ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号
  177.     ADXL345_SendByte(REG_Address);            //发送存储单元地址,从0开始        
  178.     ADXL345_Start();                          //起始信号
  179.     ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号
  180.     REG_data=ADXL345_RecvByte();              //读出寄存器数据
  181.         ADXL345_SendACK(1);   
  182.         ADXL345_Stop();                           //停止信号
  183.     return REG_data;
  184. }          */
  185. //*********************************************************
  186. //
  187. //连续读出ADXL345内部加速度数据,地址范围0x32~0x37
  188. //
  189. //*********************************************************
  190. void Multiple_read_ADXL345(void)
  191. {   uchar i;
  192.     ADXL345_Start();                          //起始信号
  193.     ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号
  194.     ADXL345_SendByte(0x32);                   //发送存储单元地址,从0x32开始        
  195.     ADXL345_Start();                          //起始信号
  196.     ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号
  197.          for (i=0; i<6; i++)                      //连续读取6个地址数据,存储中BUF
  198.     {
  199.         BUF[i] = ADXL345_RecvByte();          //BUF[0]存储0x32地址中的数据
  200.         if (i == 5)
  201.         {
  202.            ADXL345_SendACK(1);                //最后一个数据需要回NOACK
  203.         }
  204.         else
  205.         {
  206.           ADXL345_SendACK(0);                //回应ACK
  207.        }
  208.    }
  209.     ADXL345_Stop();                          //停止信号
  210.     Delay5ms();
  211. }


  212. //*****************************************************************

  213. //初始化ADXL345,根据需要请参考pdf进行修改************************
  214. void Init_ADXL345()
  215. {
  216.    Single_Write_ADXL345(0x31,0x0B);   //测量范围,正负16g,13位模式
  217.    Single_Write_ADXL345(0x2C,0x08);   //速率设定为12.5 参考pdf13页
  218.    Single_Write_ADXL345(0x2D,0x08);   //选择电源模式   参考pdf24页
  219.    Single_Write_ADXL345(0x2E,0x80);   //使能 DATA_READY 中断
  220.    Single_Write_ADXL345(0x1E,0x00);   //X 偏移量 根据测试传感器的状态写入pdf29页
  221.    Single_Write_ADXL345(0x1F,0x00);   //Y 偏移量 根据测试传感器的状态写入pdf29页
  222.    Single_Write_ADXL345(0x20,0x05);   //Z 偏移量 根据测试传感器的状态写入pdf29页
  223. }

  224. //***********************************************************************
  225. //显示x轴
  226. void display_x()
  227. {   
  228.     dis_data=(BUF[1]<<8)+BUF[0];  //合成数据   
  229.         
  230.         if(dis_data<30)           //灵敏度设置, 0 灵敏度最高
  231.         {
  232.                 aaa=1;
  233.         }
  234.         else
  235.         {
  236.                 if(aaa==1)
  237.                 {
  238.                         aaa=0;
  239.                         num1++;           //总步数 累加
  240.                         num2++;           //步数 累加
  241.                 }
  242.         }   
  243.         
  244.         conversion(num2);          //步数数据         
  245.         DisplayOneChar(0,0,'B');   //第0行,第0列 显示X
  246.     DisplayOneChar(1,0,':');
  247.     DisplayOneChar(2,0,wan);
  248.     DisplayOneChar(3,0,qian);
  249.     DisplayOneChar(4,0,bai);
  250.     DisplayOneChar(5,0,shi);
  251.     DisplayOneChar(6,0,ge);


  252.         conversion(num1);          //总步数数据
  253.         DisplayOneChar(0,1,'Z');   //第1行,第0列 显示X
  254.     DisplayOneChar(1,1,'B');
  255.         DisplayOneChar(2,1,':');
  256.     DisplayOneChar(3,1,wan);
  257.     DisplayOneChar(4,1,qian);
  258.     DisplayOneChar(5,1,bai);
  259.     DisplayOneChar(6,1,shi);
  260.     DisplayOneChar(7,1,ge);
  261. }



  262. //*********************************************************
  263. //******主程序********
  264. //*********************************************************
  265. void main()
  266. {

  267.         bit res;
  268.     int temp;        //读取到的当前温度值
  269.     int intT, decT;  //温度值的整数和小数部分
  270.     unsigned char len;
  271.     unsigned char str[12];

  272.     EA = 1;            //开总中断
  273.     ConfigTimer0(10);  //T0定时10ms
  274.     Start18B20();      //启动DS18B20

  275.   //uchar devid;
  276.   delay(500);                          //上电延时               
  277.   Lcd_init();                      //液晶初始化ADXL345
  278.   Init_ADXL345();                 //初始化ADXL345
  279.   //devid=Single_Read_ADXL345(0X00);//读出的数据为0XE5,表示正确
  280.   while(1)                          //循环
  281.           {
  282.                     Multiple_Read_ADXL345();       //连续读出数据,存储在BUF中
  283.                     display_x();                   //---------显示X轴
  284.                     delay(200);                    //延时            
  285.                
  286.                         if( key == 0 )                       //按键
  287.                         {
  288.                            num2 = 0;                               //归零
  289.                         }

  290.                         DisplayOneChar(8,0,'T');
  291.                         DisplayOneChar(9,0,'e');
  292.                         DisplayOneChar(10,0,'m');
  293.                         DisplayOneChar(11,0,':');
  294.                         if (flag1s)  //每秒更新一次温度
  295.                 {
  296.                     flag1s = 0;
  297.                     res = Get18B20Temp(&temp);  //读取当前温度
  298.                     if (res)                    //读取成功时,刷新当前温度显示
  299.                     {
  300.                         intT = temp >> 4;             //分离出温度值整数部分
  301.                         decT = temp & 0xF;            //分离出温度值小数部分
  302.                         len = IntToString(str, intT); //整数部分转换为字符串
  303.                         str[len++] = '.';             //添加小数点
  304.                         decT = (decT*10) / 16;        //二进制的小数部分转换为1位十进制位
  305.                         str[len++] = decT + '0';      //十进制小数位再转换为ASCII字符
  306.                         while (len < 6)               //用空格补齐到6个字符长度
  307.                         {
  308.                             str[len++] = ' ';
  309.                         }
  310.                         str[len] = '\0';              //添加字符串结束符
  311.                         LcdShowStr(12, 0, str);        //“数字”显示到液晶屏上
  312.                     }
  313.                     else                        //读取失败时,提示错误信息
  314.                     {
  315.                         LcdShowStr(10, 1, "error!");
  316.                     }
  317.                     Start18B20();               //重新启动下一次转换
  318.                 }
  319.         
  320.           }
  321. }

  322. /* 整型数转换为字符串,str-字符串指针,dat-待转换数,返回值-字符串长度 */
  323. unsigned char IntToString(unsigned char *str, int dat)
  324. {
  325.     signed char i = 0;
  326.     unsigned char len = 0;
  327.     unsigned char buf[6];
  328.    
  329.     if (dat < 0)  //如果为负数,首先取绝对值,并在指针上添加负号
  330.     {
  331.         dat = -dat;
  332.         *str++ = '-';
  333.         len++;
  334.     }
  335.     do {          //先转换为低位在前的十进制数组
  336.         buf[i++] = dat % 10;
  337.         dat /= 10;
  338.     } while (dat > 0);
  339.     len += i;     //i最后的值就是有效字符的个数
  340.     while (i-- > 0)   //将数组值转换为ASCII码反向拷贝到接收指针上
  341.     {
  342.         *str++ = buf[i] + '0';
  343.     }
  344.     *str = '\0';  //添加字符串结束符
  345.    
  346.     return len;   //返回字符串长度
  347. }
  348. /* 配置并启动T0,ms-T0定时时间 */
  349. void ConfigTimer0(unsigned int ms)
  350. {
  351.     unsigned long tmp;  //临时变量
  352.    
  353.     tmp = 11059200 / 12;      //定时器计数频率
  354.     tmp = (tmp * ms) / 1000;  //计算所需的计数值
  355.     tmp = 65536 - tmp;        //计算定时器重载值
  356.     tmp = tmp + 12;           //补偿中断响应延时造成的误差
  357.     TMOD &= 0xF0;   //清零T0的控制位
  358.     TMOD |= 0x01;   //配置T0为模式1
  359.         TH0=(65536-50000)%256;
  360.         TL0=(65536-50000)%256;
  361.     ET0 = 1;        //使能T0中断
  362.     TR0 = 1;        //启动T0
  363. }
  364. /* T0中断服务函数,完成1秒定时 */
  365. void InterruptTimer0() interrupt 1
  366. {
  367.     static unsigned char tmr1s = 0;
  368.    
  369.         TH0=(65536-50000)%256;
  370.         TL0=(65536-50000)%256;
  371.     tmr1s++;
  372.     if (tmr1s >= 18)  //定时1s
  373.     {
  374.         tmr1s = 0;
  375.         flag1s = 1;
  376.     }
  377. }
复制代码


评分

参与人数 4黑币 +61 收起 理由
oyang123 + 5 很给力!
873839450 + 5 很给力!
hsbuggati + 1 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:169448 发表于 2017-3-13 15:08 | 只看该作者

谢谢楼主分享!!
回复

使用道具 举报

板凳
ID:129081 发表于 2017-3-22 19:14 | 只看该作者
谢谢分享
回复

使用道具 举报

地板
ID:292153 发表于 2018-3-15 09:59 | 只看该作者
感谢分享
回复

使用道具 举报

5#
ID:301547 发表于 2018-4-9 09:54 | 只看该作者
有没有 arduino版的
回复

使用道具 举报

6#
ID:311659 发表于 2018-4-20 16:38 | 只看该作者
感谢分享!
回复

使用道具 举报

7#
ID:320872 发表于 2018-5-2 22:51 | 只看该作者
赞,很给力,想下载
回复

使用道具 举报

8#
ID:308041 发表于 2018-5-7 23:13 | 只看该作者
很棒,有帮助
回复

使用道具 举报

9#
ID:341757 发表于 2018-5-30 22:20 来自手机 | 只看该作者
感谢分享
回复

使用道具 举报

10#
ID:341045 发表于 2018-5-31 06:48 | 只看该作者
谢谢分享
回复

使用道具 举报

11#
ID:110278 发表于 2018-5-31 19:58 | 只看该作者
点个赞。
回复

使用道具 举报

12#
ID:391171 发表于 2018-8-29 13:41 | 只看该作者
共享资料的黑币奖励
回复

使用道具 举报

13#
ID:345799 发表于 2018-8-29 14:21 | 只看该作者
下载学习
回复

使用道具 举报

14#
ID:519952 发表于 2019-4-24 16:45 | 只看该作者
  学习一波
回复

使用道具 举报

15#
ID:92810 发表于 2019-5-27 10:35 | 只看该作者
谢谢楼主分享了
回复

使用道具 举报

16#
ID:590547 发表于 2019-7-25 21:46 | 只看该作者

谢谢楼主分享了
回复

使用道具 举报

17#
ID:717494 发表于 2020-3-28 12:38 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

18#
ID:631827 发表于 2020-5-1 16:39 | 只看该作者
谢谢楼主,解答我的疑惑
回复

使用道具 举报

19#
ID:824356 发表于 2020-9-28 20:29 | 只看该作者
完美啊
回复

使用道具 举报

20#
ID:657845 发表于 2020-10-11 20:42 | 只看该作者
有没有32的?谢谢楼主了
回复

使用道具 举报

21#
ID:825327 发表于 2020-11-21 22:50 | 只看该作者
谢谢楼主!学习一下。
回复

使用道具 举报

22#
ID:889207 发表于 2021-3-7 13:52 | 只看该作者
遇到很多困难,来学习一下,非常感谢分享!
回复

使用道具 举报

23#
ID:601357 发表于 2021-4-5 11:39 | 只看该作者
谢谢分享啦 刚刚好需要用得上
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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