代码

  1. #include "AS5600.h"
  2. #include "i2c.h"
  3. void AS5600_init() {
  4. uint8_t data = 0x03;
  5. HAL_I2C_Mem_Write(&hi2c1, I2C_ADDRESS, _conf_hi, I2C_MEMADD_SIZE_8BIT, &data, 1, 0xff);//打开I2C
  6. return;
  7. }
  8. /**************************************************************
  9. * 函数名:uint8_t AS5600_readOneByte(uint8_t in_adr)
  10. * 函数功能:给定地址读一个字节
  11. * 输入参数:in_adr 待读数据的地址
  12. * 输出参数:retVal读出的数据
  13. * 返回值:无
  14. **************************************************************/
  15. uint8_t AS5600_readOneByte(uint8_t in_adr)//读一个字节函数,从5600的指定寄存器提取一个8位值
  16. {
  17. uint8_t a3 = 0x00;
  18. HAL_I2C_Mem_Read(&hi2c1, I2C_ADDRESS, (uint16_t) in_adr, I2C_MEMADD_SIZE_8BIT, &a3, 1, 0xff);
  19. return a3;
  20. }
  21. /**************************************************************
  22. * 函数名:uint16_t AS5600_readTwoBytes(uint8_t h_adr, uint8_t l_adr)
  23. * 函数功能:给定两个地址 各自读出一个字节
  24. * 输入参数:in_adr 待读高位数据的地址 in_adr_lo待读低位数据的地址
  25. * 输出参数:retVal读出的数据
  26. * 返回值:无
  27. **************************************************************/
  28. uint16_t AS5600_readTwoBytes(uint8_t h_adr, uint8_t l_adr) {
  29. uint16_t retVal = 0;
  30. uint8_t low = 0, high = 0;
  31. /* Read High Byte */
  32. high = AS5600_readOneByte(h_adr);
  33. high = high & 0x0f;
  34. /* Read Low Byte */
  35. low = AS5600_readOneByte(l_adr);
  36. //将两个八位 合成一个16位
  37. retVal = high << 8;
  38. retVal = (retVal | low);
  39. return retVal;//输出一个16位
  40. }
  41. /**************************************************************
  42. * 函数名:uint8_t AS5600_detectMagnet(void)
  43. * 函数功能:判断有无磁铁
  44. * 输入参数:无
  45. * 输出参数:1有磁铁 0无磁铁
  46. * 返回值:无
  47. **************************************************************/
  48. uint8_t AS5600_detectMagnet(void) {
  49. uint8_t retVal = 0;
  50. HAL_I2C_Mem_Read(&hi2c1, I2C_ADDRESS, (uint16_t) _stat, I2C_MEMADD_SIZE_8BIT, &retVal, 1, 0xff);
  51. // retVal = AS5600_readOneByte(_stat);
  52. if (retVal & 0x20)
  53. retVal = 1;
  54. return retVal;
  55. }
  56. /**************************************************************
  57. * 函数名:float AS5600_ReadSensorRawData(void)
  58. * 函数功能:读取传感器原始数据
  59. * 输入参数:无
  60. * 输出参数:有磁铁 传感器原始数据(范围0-4095) 无磁铁 返回上次的数据
  61. * 返回值:无
  62. **************************************************************/
  63. float AS5600_ReadSensorRawData(void) {
  64. static float data = 0;
  65. static uint8_t raw_data[2];
  66. if (AS5600_detectMagnet()) {
  67. /* Read High Byte */
  68. HAL_I2C_Mem_Read(&hi2c1, I2C_ADDRESS, (uint16_t) _raw_ang_hi, I2C_MEMADD_SIZE_8BIT, raw_data, 2, 0xff);
  69. //将两个八位 合成一个16位
  70. data = (raw_data[0] & 0x0f) << 8 | raw_data[1];
  71. /* Raw data reports 0 - 4095 segments */
  72. if (data < 0) {
  73. data += 4095.0f;
  74. }
  75. }
  76. return data;
  77. }
  1. #ifndef __AS5600_H__
  2. #define __AS5600_H__
  3. #include "main.h"
  4. #define I2C_ADDRESS (0x36<<1)
  5. typedef enum
  6. {
  7. /* set i2c address */
  8. _ams5600_Address = 0x36,
  9. _zmco = 0x00,
  10. _zpos_hi = 0x01,
  11. _zpos_lo = 0x02,
  12. _mpos_hi = 0x03,
  13. _mpos_lo = 0x04,
  14. _mang_hi = 0x05,
  15. _mang_lo = 0x06,
  16. _conf_hi = 0x07,
  17. _conf_lo = 0x08,
  18. _raw_ang_hi = 0x0c,
  19. _raw_ang_lo = 0x0d,
  20. _ang_hi = 0x0e,
  21. _ang_lo = 0x0f,
  22. _stat = 0x0b,
  23. _agc = 0x1a,
  24. _mag_hi = 0x1b,
  25. _mag_lo = 0x1c,
  26. _burn = 0xff
  27. }AMS5600Registers_t;
  28. void AS5600_init();
  29. uint8_t AS5600_readOneByte(uint8_t in_adr); //读一个字节函数,从5600的指定寄存器提取一个8位值
  30. uint16_t AS5600_readTwoBytes(uint8_t h_adr, uint8_t l_adr); //给定两个地址 各自读出一个字节
  31. float AS5600_ReadSensorRawData(void); //读取传感器角度值
  32. #endif

原理与结构

参考

有初始化:
校准标定磁块【checkMagnetPresence()函数,通过返回值确定磁块位置是否准确距离】→读取初始角度值【ReadRawAngle()读取当前的绝对位置角度值信息】→
进入循环(每次循环都是有耗时,故转速不能超过某特定的值):
读取更新当前的角度值【ReadRawAngle()函数】→计算转过的角度数值【correctAngle()函数,可以计算角度值】→计算、累计转过的圈数【checkQuadrant()函数,通每次读取的象限,来确定是否转过一周】→更新显示屏的数值信息【refreshDisplay()函数】