ADXL345.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. ADXL345三轴倾斜度模块
  3. */
  4. #include "main.h"
  5. /**
  6. * @brief ADXL345初始化
  7. * @param None
  8. * @retval None
  9. */
  10. uint8_t ADXL345_init(void)
  11. {
  12. if(ADXL345_read_reg(DEVICE_ID) == 0xE5)
  13. {
  14. ADXL345_write_reg(DATA_FORMAT,0X0B); // 低电平中断输出,13位全分辨率,输出数据右对齐,16g量程
  15. ADXL345_write_reg(BW_RATE,0x0E); // 数据输出速度为100Hz
  16. ADXL345_write_reg(POWER_CTL,0x08); // 链接使能,测量模式,省电特性
  17. ADXL345_write_reg(INT_ENABLE,0x80); // 不使用中断
  18. ADXL345_write_reg(OFSX,0x00);
  19. ADXL345_write_reg(OFSY,0x00);
  20. ADXL345_write_reg(OFSZ,0x05);
  21. return 0;
  22. }
  23. return 1;
  24. }
  25. /**
  26. * @brief ADXL345写寄存器
  27. * @param None
  28. * @retval None
  29. */
  30. uint8_t ADXL345_write_reg(u8 addr,u8 val)
  31. {
  32. IIC_start();
  33. IIC_send_byte(slaveaddress); // 发送写器件指令
  34. if(IIC_wait_ack())
  35. {
  36. return 1;
  37. }
  38. IIC_send_byte(addr); // 发送寄存器地址
  39. if(IIC_wait_ack())
  40. {
  41. return 2;
  42. }
  43. IIC_send_byte(val); // 发送值
  44. if(IIC_wait_ack())
  45. {
  46. return 3;
  47. }
  48. IIC_stop(); // 产生一个停止条件
  49. return 0;
  50. }
  51. /**
  52. * @brief ADXL345读寄存器
  53. * @param None
  54. * @retval None
  55. */
  56. u8 ADXL345_read_reg(u8 addr)
  57. {
  58. u8 temp=0;
  59. IIC_start();
  60. IIC_send_byte(slaveaddress); // 发送写器件指令
  61. if(IIC_wait_ack())
  62. {
  63. return 1;
  64. }
  65. IIC_send_byte(addr); // 发送寄存器地址
  66. if(IIC_wait_ack())
  67. {
  68. return 2;
  69. }
  70. IIC_start(); // 重新启动
  71. IIC_send_byte(regaddress); // 发送读器件指令
  72. if(IIC_wait_ack())
  73. {
  74. return 3;
  75. }
  76. temp=IIC_read_byte(0); // 读取一个字节,不继续再读,发送NAK
  77. IIC_stop(); // 产生一个停止条件
  78. return temp;
  79. }
  80. /**
  81. * @brief ADXL345读取数据
  82. * @param None
  83. * @retval None
  84. */
  85. void ADXL345_read_data(short *x,short *y,short *z)
  86. {
  87. u8 buf[6];
  88. u8 i;
  89. IIC_start();
  90. IIC_send_byte(slaveaddress); // 发送写器件指令
  91. IIC_wait_ack();
  92. IIC_send_byte(0x32); // 发送寄存器地址(数据缓存的起始地址为0X32)
  93. IIC_wait_ack();
  94. IIC_start(); // 重新启动
  95. IIC_send_byte(regaddress); // 发送读器件指令
  96. IIC_wait_ack();
  97. for(i=0;i<6;i++)
  98. {
  99. if(i==5)buf[i]=IIC_read_byte(0); // 读取一个字节,不继续再读,发送NACK
  100. else buf[i]=IIC_read_byte(1); // 读取一个字节,继续读,发送ACK
  101. }
  102. IIC_stop(); // 产生一个停止条件
  103. *x=(short)(((u16)buf[1]<<8)+buf[0]); // 合成数据
  104. *y=(short)(((u16)buf[3]<<8)+buf[2]);
  105. *z=(short)(((u16)buf[5]<<8)+buf[4]);
  106. }
  107. /**
  108. * @brief ADXL345连读读取几次取平均值
  109. * @param None
  110. * @retval None
  111. */
  112. void ADXL345_read_average(short *x,short *y,short *z,u8 times)
  113. {
  114. u8 i;
  115. short tx,ty,tz;
  116. *x=0;
  117. *y=0;
  118. *z=0;
  119. if(times)//读取次数不为0
  120. {
  121. for(i=0;i<times;i++)//连续读取times次
  122. {
  123. ADXL345_read_data(&tx,&ty,&tz);
  124. *x+=tx;
  125. *y+=ty;
  126. *z+=tz;
  127. DELAYClass.DelayMs(5);
  128. }
  129. *x/=times;
  130. *y/=times;
  131. *z/=times;
  132. }
  133. }
  134. /**
  135. * @brief ADXL345计算角度
  136. * @param None
  137. * @retval None
  138. */
  139. void get_angle(float *x_angle,float *y_angle,float *z_angle)
  140. {
  141. short ax,ay,az;
  142. ADXL345_read_average(&ax,&ay,&az,10);
  143. *x_angle=atan(ax/sqrt((az*az+ay*ay)))*180/3.14;
  144. *y_angle=atan(ay/sqrt((ax*ax+az*az)))*180/3.14;
  145. *z_angle=atan(sqrt((ax*ax+ay*ay)/az))*180/3.14;
  146. }