[ESP32] KTH57 磁感应IIC驱动

#include 
#include "esp_log.h"
#include "driver/i2c.h"
#include "kth57xx_iic.h"
#include 

static const char *TAG = "kth57xx_i2c";

/**
 * @brief i2c master initialization
 */
esp_err_t i2c_master_init(void)
{
  int i2c_master_port = I2C_MASTER_NUM;

  i2c_config_t conf = {
    .mode = I2C_MODE_MASTER,
    .sda_io_num = I2C_MASTER_SDA_IO,
    .scl_io_num = I2C_MASTER_SCL_IO,
    .sda_pullup_en = GPIO_PULLUP_ENABLE,
    .scl_pullup_en = GPIO_PULLUP_ENABLE,
    .master.clk_speed = I2C_MASTER_FREQ_HZ,
  };

  i2c_param_config(i2c_master_port, &conf);

  return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}

int kth57xx_set_mode(uint8_t u8_cmd, uint8_t axis, uint8_t *p_status)
{
  int ret = 0;
  uint8_t write_buf[2];

  write_buf[0] = u8_cmd|axis;

	ret = i2c_master_write_to_device(I2C_MASTER_NUM, KTH57XX_ADDR, write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
  ret = i2c_master_read_from_device(I2C_MASTER_NUM, KTH57XX_ADDR, p_status, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
  return ret;
}

/**
  * @brief  开启持续感应模式
  * @param  芯片工作状态(status)
  * @retval ret 0通信ok
  */
int kth57xx_continuous_sensing(uint8_t *p_status)
{
	return kth57xx_set_mode(KTH57XX_CMD_CONTINUOUS_SENSING, 0x06, p_status);//AB
}

/**
  * @brief  开启唤醒睡眠模式
  * @param  芯片工作状态(status)
  * @retval ret 0通信ok
  */
int kth57xx_wakeup_sleep(uint8_t *p_status)
{
	return kth57xx_set_mode(KTH57XX_CMD_WAKEUP_SLEEP, 0x06, p_status);//AB
}

/**
  * @brief  开启单次测量模式
  * @param  芯片工作状态(status)
  * @retval ret 0通信ok
  */
int kth57xx_single_conversion(uint8_t *p_status)
{
	return kth57xx_set_mode(KTH57XX_CMD_SINGLE_CONVERSION, 0x06, p_status);//AB
}

/**
  * @brief  开启空闲模式
  * @param  芯片工作状态(status)
  * @retval  ret 0通信ok
  */
int kth57xx_idle(uint8_t *p_status)
{
  return kth57xx_set_mode(KTH57XX_CMD_IDLE, 0x00, p_status);//AB
}

/**
  * @brief  芯片重置
  * @param  无
  * @retval ret 0通信ok
  */
int kth57xx_reset(void)
{
	int ret = 0;
  uint8_t write_buf[2];

  write_buf[0] = KTH57XX_CMD_RESET;		

  ret = i2c_master_write_to_device(I2C_MASTER_NUM, KTH57XX_ADDR, write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
	return ret;
}

/**
  * @brief  读取芯片测量结果 芯片测量结果放在 DataReadFrame 数组中 
  * @param  axis:ZYXT 设置对哪个测量项进行输出 
  *         p_status :芯片工作状态(status)
  *         p_read_data : 读数据
  * @retval ret 0通信ok
  */
int kth57xx_read_data_frame(uint8_t u8_axis, uint8_t *p_status, uint8_t *p_read_data)
{
  int ret = 0;
	uint8_t i;	
	uint8_t write_buf[2];
  uint8_t read_buf[9];
	uint8_t readLen = 1;//根据axis来计算一共需要读回多少测量数据,存放在counter中
	
	write_buf[0] = KTH57XX_CMD_DATA_READ | u8_axis;	
	
	for(i=0;i<4;i++)
	{
		readLen = readLen + ( u8_axis & 0x01 )*2;
		u8_axis = u8_axis >> 1;
	}

  ret = i2c_master_write_to_device(I2C_MASTER_NUM, KTH57XX_ADDR, write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
  if(ret != ESP_OK)
  {
    return ret;
  }
  ret = i2c_master_read_from_device(I2C_MASTER_NUM, KTH57XX_ADDR, read_buf, readLen, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
  *p_status = read_buf[0];
  memcpy(p_read_data, &read_buf[1], readLen-1);

	return ret;
	
}

/**
  * @brief  读取芯片测量结果 芯片测量结果放在 DataReadFrame 数组中 
  * @param  p_status :芯片工作状态(status)
  *         u16_p_data_angle : 读角度
  *         u16_p_data_B : 读磁场强度
  * @retval ret 0通信ok
  */
int kth57xx_read_AB(uint8_t *p_status, uint16_t *u16_p_data_angle, uint16_t *u16_p_data_B)
{
	int ret = 0;	
  uint8_t write_buf[2];
  uint8_t read_buf[5];
	
	write_buf[0] = KTH57XX_CMD_DATA_READ | 0x06;//0x06AB
	
  ret = i2c_master_write_to_device(I2C_MASTER_NUM, KTH57XX_ADDR, write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
  if(ret != ESP_OK)
  {
    return ret;
  }
  ret = i2c_master_read_from_device(I2C_MASTER_NUM, KTH57XX_ADDR, read_buf, 5, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
  *p_status = read_buf[0];

  *u16_p_data_angle = read_buf[1];
  *u16_p_data_angle = (*u16_p_data_angle)<<8;
  *u16_p_data_angle = (*u16_p_data_angle)|read_buf[2];

  *u16_p_data_B = read_buf[3];
  *u16_p_data_B = (*u16_p_data_B)<<8;
  *u16_p_data_B = (*u16_p_data_B)|read_buf[4];
  // ESP_LOGI(TAG, "[kth57xx_read_AB]%x,%x,%x,%x,%x\n", read_buf[0], read_buf[1], read_buf[2], read_buf[3], read_buf[4]);	
	return ret;
}

/**
  * @brief  读取寄存器数据 
  *         寄存器中的值以及芯片工作状态存
  * @param  u8_register:寄存器
  *         p_status :芯片工作状态(status)
  *         u16_p_read_data : 读寄存器数据
  * @retval IIC是否通信成功
  */
int kth57xx_read_register(uint8_t u8_register, uint8_t *p_status, uint16_t *u16_p_read_data)
{
	int ret = 0;
	uint8_t write_buf[2]; 
  uint8_t read_buf[3]; 
	
	write_buf[0] = KTH57XX_CMD_READ_REGISTER;
	write_buf[1] = u8_register << 2; //读取时寄存器要左移两位
  ret = i2c_master_write_to_device(I2C_MASTER_NUM, KTH57XX_ADDR, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
  if(ret != ESP_OK)
  {
    return ret;
  }
  ret = i2c_master_read_from_device(I2C_MASTER_NUM, KTH57XX_ADDR, read_buf, 3, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);

  *p_status = read_buf[0];
  *u16_p_read_data = read_buf[1];
  *u16_p_read_data = (*u16_p_read_data)<<8;
  *u16_p_read_data = (*u16_p_read_data)|read_buf[2];

	return ret;
}

/**
  * @brief  向寄存器中写入配置
  * @param  u16_write_data:写入寄存器的数据
  *         u8_register :需写入的寄存器
  *         p_status :芯片工作状态(status)
  * @retval ret
  */
int kth57xx_write_register (uint8_t u8_register, uint16_t u16_write_data, uint8_t *p_status)
{
  int ret = 0;
	uint8_t write_buf[4]; 
	
	write_buf[0] = KTH57XX_CMD_WRITE_REGISTER;
	write_buf[1] = (u16_write_data >> 8) & 0xff; 
	write_buf[2] = u16_write_data & 0xff;
	write_buf[3] = u8_register <<2 ;//寄存器要左移两位

  ret = i2c_master_write_to_device(I2C_MASTER_NUM, KTH57XX_ADDR, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
  if(ret != ESP_OK)
  {
    return ret;
  }
  ret = i2c_master_read_from_device(I2C_MASTER_NUM, KTH57XX_ADDR, p_status, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);

	return ret;
}


int kth57xx_set_zero(uint16_t u16_zero_angle)
{
  uint8_t u8_status = 0;
  uint16_t u16_zero_value = 0;
  u16_zero_value = 65536*u16_zero_angle/360/2;
  return kth57xx_write_register (KTH57XX_REG_ZERO, (-u16_zero_value)&0x7FFF, &u8_status);
}

int kth57xx_get_AB(float *u16_angle, uint16_t *u16_data_B)
{
  int ret = 0;
  uint8_t u8_status = 0;
  uint16_t u16_data_angle;
  ret = kth57xx_read_AB(&u8_status, &u16_data_angle, u16_data_B);
	*u16_angle =  u16_data_angle * 360.0 /65536;//角度	
  return ret;
}

void kth57xx_iic_init(void)
{
  uint8_t u8_status=0;

  ESP_ERROR_CHECK(i2c_master_init());
  ESP_LOGI(TAG, "I2C initialized successfully");
  vTaskDelay( 5/portTICK_PERIOD_MS );
  kth57xx_idle(&u8_status);
  vTaskDelay( 1/portTICK_PERIOD_MS );
  kth57xx_write_register (KTH57XX_REG_RESERVED_1C, 0x1430, &u8_status);
  kth57xx_write_register (KTH57XX_REG_MEAS_TIME_SEL, 0x0002, &u8_status);
  kth57xx_write_register (KTH57XX_REG_ZERO, 0x0000, &u8_status);	

  // ESP_ERROR_CHECK(i2c_driver_delete(I2C_MASTER_NUM));
  // ESP_LOGI(TAG, "I2C de-initialized successfully");
}

你可能感兴趣的:(c语言,单片机)