代码
#include "AS5600.h"
#include "i2c.h"
void AS5600_init() {
uint8_t data = 0x03;
HAL_I2C_Mem_Write(&hi2c1, I2C_ADDRESS, _conf_hi, I2C_MEMADD_SIZE_8BIT, &data, 1, 0xff);//打开I2C
return;
}
/**************************************************************
* 函数名:uint8_t AS5600_readOneByte(uint8_t in_adr)
* 函数功能:给定地址读一个字节
* 输入参数:in_adr 待读数据的地址
* 输出参数:retVal读出的数据
* 返回值:无
**************************************************************/
uint8_t AS5600_readOneByte(uint8_t in_adr)//读一个字节函数,从5600的指定寄存器提取一个8位值
{
uint8_t a3 = 0x00;
HAL_I2C_Mem_Read(&hi2c1, I2C_ADDRESS, (uint16_t) in_adr, I2C_MEMADD_SIZE_8BIT, &a3, 1, 0xff);
return a3;
}
/**************************************************************
* 函数名:uint16_t AS5600_readTwoBytes(uint8_t h_adr, uint8_t l_adr)
* 函数功能:给定两个地址 各自读出一个字节
* 输入参数:in_adr 待读高位数据的地址 in_adr_lo待读低位数据的地址
* 输出参数:retVal读出的数据
* 返回值:无
**************************************************************/
uint16_t AS5600_readTwoBytes(uint8_t h_adr, uint8_t l_adr) {
uint16_t retVal = 0;
uint8_t low = 0, high = 0;
/* Read High Byte */
high = AS5600_readOneByte(h_adr);
high = high & 0x0f;
/* Read Low Byte */
low = AS5600_readOneByte(l_adr);
//将两个八位 合成一个16位
retVal = high << 8;
retVal = (retVal | low);
return retVal;//输出一个16位
}
/**************************************************************
* 函数名:uint8_t AS5600_detectMagnet(void)
* 函数功能:判断有无磁铁
* 输入参数:无
* 输出参数:1有磁铁 0无磁铁
* 返回值:无
**************************************************************/
uint8_t AS5600_detectMagnet(void) {
uint8_t retVal = 0;
HAL_I2C_Mem_Read(&hi2c1, I2C_ADDRESS, (uint16_t) _stat, I2C_MEMADD_SIZE_8BIT, &retVal, 1, 0xff);
// retVal = AS5600_readOneByte(_stat);
if (retVal & 0x20)
retVal = 1;
return retVal;
}
/**************************************************************
* 函数名:float AS5600_ReadSensorRawData(void)
* 函数功能:读取传感器原始数据
* 输入参数:无
* 输出参数:有磁铁 传感器原始数据(范围0-4095) 无磁铁 返回上次的数据
* 返回值:无
**************************************************************/
float AS5600_ReadSensorRawData(void) {
static float data = 0;
static uint8_t raw_data[2];
if (AS5600_detectMagnet()) {
/* Read High Byte */
HAL_I2C_Mem_Read(&hi2c1, I2C_ADDRESS, (uint16_t) _raw_ang_hi, I2C_MEMADD_SIZE_8BIT, raw_data, 2, 0xff);
//将两个八位 合成一个16位
data = (raw_data[0] & 0x0f) << 8 | raw_data[1];
/* Raw data reports 0 - 4095 segments */
if (data < 0) {
data += 4095.0f;
}
}
return data;
}
#ifndef __AS5600_H__
#define __AS5600_H__
#include "main.h"
#define I2C_ADDRESS (0x36<<1)
typedef enum
{
/* set i2c address */
_ams5600_Address = 0x36,
_zmco = 0x00,
_zpos_hi = 0x01,
_zpos_lo = 0x02,
_mpos_hi = 0x03,
_mpos_lo = 0x04,
_mang_hi = 0x05,
_mang_lo = 0x06,
_conf_hi = 0x07,
_conf_lo = 0x08,
_raw_ang_hi = 0x0c,
_raw_ang_lo = 0x0d,
_ang_hi = 0x0e,
_ang_lo = 0x0f,
_stat = 0x0b,
_agc = 0x1a,
_mag_hi = 0x1b,
_mag_lo = 0x1c,
_burn = 0xff
}AMS5600Registers_t;
void AS5600_init();
uint8_t AS5600_readOneByte(uint8_t in_adr); //读一个字节函数,从5600的指定寄存器提取一个8位值
uint16_t AS5600_readTwoBytes(uint8_t h_adr, uint8_t l_adr); //给定两个地址 各自读出一个字节
float AS5600_ReadSensorRawData(void); //读取传感器角度值
#endif
原理与结构
参考
有初始化:
校准标定磁块【checkMagnetPresence()函数,通过返回值确定磁块位置是否准确距离】→读取初始角度值【ReadRawAngle()读取当前的绝对位置角度值信息】→
进入循环(每次循环都是有耗时,故转速不能超过某特定的值):
读取更新当前的角度值【ReadRawAngle()函数】→计算转过的角度数值【correctAngle()函数,可以计算角度值】→计算、累计转过的圈数【checkQuadrant()函数,通每次读取的象限,来确定是否转过一周】→更新显示屏的数值信息【refreshDisplay()函数】