ADXL345.c 3.1 KB

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