ist8310.c完整代码
//
// Created by Goldengrandpa on 2022/11/4.
//
#include “ist8310.h”
rt_err_t ist8310_iic_write(rt_uint8_t write_addr, rt_uint8_t data, rt_uint32_t number)
{
rt_uint8_t buf[2];
buf[0] = write_addr;
buf[1] = data;
rt_size_t result;
result = rt_i2c_master_send(ist8310_i2c_bus, IST8310_ADDR, RT_I2C_WR, buf, 2);
rt_thread_mdelay(10);
if (result == 2)
{
rt_kprintf(“IST8310 write failed,ERR is:%drn”, result);
return -RT_ERROR;
}
}
void ist8310_delay_us(uint16_t us)
{
uint32_t ticks = 0;
uint32_t told = 0, tnow = 0, tcnt = 0;
uint32_t reload = 0;
reload = SysTick-》LOAD;
ticks = us * 72;
told = SysTick-》VAL;
while (1)
{
tnow = SysTick-》VAL;
if (tnow != told)
{
if (tnow 《 told)
{
tcnt += told - tnow;
}
else
{
tcnt += reload - tnow + told;
}
told = tnow;
if (tcnt 》= ticks)
{
break;
}
}
}
}
rt_err_t ist8310_iic_read(rt_uint8_t read_addr, rt_uint32_t len, rt_uint8_t *buf)
{
//通知要读哪个设备的哪个内存地址的内容,(告知是需要读read_addr)
rt_i2c_master_send(ist8310_i2c_bus, IST8310_ADDR, RT_I2C_WR, &read_addr, 1);
//读取到的内容存入buf
rt_i2c_master_recv(ist8310_i2c_bus, IST8310_ADDR, RT_I2C_RD, buf, len); //地址读数据
}
rt_err_t ist8310_IIC_write_single_reg(rt_uint8_t reg, rt_uint8_t data)
{
rt_uint8_t buf[2];
buf[0] = reg;
buf[1] = data;
if (rt_i2c_master_send(ist8310_i2c_bus, IST8310_ADDR, 0, buf, 2) == 2)
{
return RT_EOK;
}
else
{
return -RT_ERROR;
}
}
uint8_t ist8310_IIC_read_single_reg(rt_uint8_t reg, rt_uint8_t len, rt_uint8_t *buf)
{
struct rt_i2c_msg msgs[2];
msgs[0].addr = IST8310_ADDR; /* 从机地址 */
msgs[0].flags = RT_I2C_WR; /* 写标志 */
msgs[0].buf = ® /* 从机寄存器地址 */
msgs[0].len = 1; /* 发送数据字节数 */
msgs[1].addr = IST8310_ADDR; /* 从机地址 */
msgs[1].flags = RT_I2C_RD; /* 读标志 */
msgs[1].buf = buf; /* 读取数据指针 */
msgs[1].len = len; /* 读取数据字节数 */
if (rt_i2c_transfer(ist8310_i2c_bus, msgs, 2) == 2)
{
return RT_EOK;
}
else
{
return -RT_ERROR;
}
}
void ist8310_RST_H(void)
{
rt_pin_write(IST8310_RSTN_PIN_NUM, 1);
}
void ist8310_RST_L(void)
{
rt_pin_write(IST8310_RSTN_PIN_NUM, 0);
}
void ist8310_read_mag(float mag[3])
{
uint8_t buf[6];
int16_t temp_ist8310_data = 0;
//read the “DATAXL” register (0x03)
ist8310_iic_read(0x03, 6, buf);
temp_ist8310_data = (int16_t) ((buf[1] 《《 8) | buf[0]);
mag[0] = MAG_SEN * temp_ist8310_data;
temp_ist8310_data = (int16_t) ((buf[3] 《《 8) | buf[2]);
mag[1] = MAG_SEN * temp_ist8310_data;
temp_ist8310_data = (int16_t) ((buf[5] 《《 8) | buf[4]);
mag[2] = MAG_SEN * temp_ist8310_data;
}
rt_uint8_t ist8310_init(const char*name)
{
rt_uint8_t temp[2] = { 0, 0 };
ist8310_i2c_bus = (struct rt_i2c_bus_device *) rt_device_find(name);
rt_uint8_t res[2] = { 0, 0 };
rt_uint8_t writeNum = 0;
if (ist8310_i2c_bus == RT_NULL)
{
rt_kprintf(“can’t find %s device!n”, name);
}
else
{
ist8310_RST_L();
rt_thread_mdelay(sleepTime);
ist8310_RST_H();
rt_thread_mdelay(sleepTime);
ist8310_IIC_read_single_reg(IST8310_WHO_AM_I, 1, res);
if (res[0] != IST8310_WHO_AM_I_VALUE)
{
initialized = RT_TRUE;
return IST8310_NO_SENSOR;
}
for (writeNum = 0; writeNum 《 IST8310_WRITE_REG_NUM; writeNum++)
{
ist8310_IIC_write_single_reg(ist8310_write_reg_data_error[writeNum][0],
ist8310_write_reg_data_error[writeNum][1]);
ist8310_delay_us(wait_time);
ist8310_IIC_read_single_reg(ist8310_write_reg_data_error[writeNum][0], 1, res);
ist8310_delay_us(wait_time);
if (res[0] != ist8310_write_reg_data_error[writeNum][1])
{
return ist8310_write_reg_data_error[writeNum][2];
}
}
initialized = RT_TRUE;
return IST8310_NO_ERROR;
}
}
static void i2c_ist8310_sample(int argc, char *argv[])
{
rt_uint8_t buf;
rt_uint8_t result=0;
float msg[3] = { 0, 0, 0 };
char name[RT_NAME_MAX];
if (argc == 2)
{
rt_strncpy(name, argv[1], RT_NAME_MAX);
}
else
{
rt_strncpy(name, IST8310_I2C_BUS_NAME, RT_NAME_MAX);
}
if (!initialized)
{
/* 传感器初始化 */
result=ist8310_init(name);
}
if (initialized)
{
ist8310_read_mag(msg);
rt_kprintf(“read ist8310 sensor x:%f y:%f z:%fn”, msg[0], msg[1], msg[2]);
}
else
{
rt_kprintf(“%dn”,result);
rt_kprintf(“initialize sensor failed!n”);
}
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(i2c_ist8310_sample, ist8310_sample);
ist8310.h
//
// Created by Goldengrandpa on 2022/11/4.
//
#ifndef RTTHREAD_IST8310_H
#define RTTHREAD_IST8310_H
#include 《rtthread.h》
#include 《rtdevice.h》
#include “board.h”
#define IST8310_I2C_BUS_NAME “i2c3” /* 传感器连接的I2C总线设备名称 */
#define IST8310_ADDR 0X0E /* 从机地址 */
#define IST8310_CALIBRATION_CMD 0xE1 /* 校准命令 */
#define IST8310_NORMAL_CMD 0xA8 /* 一般命令 */
#define IST8310_GET_DATA 0xAC /* 获取数据命令 */
#define IST8310_WRITE_REG_NUM 4
#define IST8310_WHO_AM_I 0x00 //ist8310 “who am I ”
#define IST8310_WHO_AM_I_VALUE 0x10 //device ID
#define IST8310_DATA_READY_BIT 2
#define IST8310_NO_ERROR 0x00
#define IST8310_NO_SENSOR 0x40
static const uint8_t wait_time = 150;
static const uint8_t sleepTime = 50;
#define IST8310_RSTN_PIN_NUM GET_PIN(G,6)
#define MAG_SEN 0.3f //raw int16 data change to uT unit. 原始整型数据变成 单位ut
typedef struct ist8310_real_data_t
{
uint8_t status;
float mag[3];
} ist8310_real_data_t;
//the first column:the registers of IST8310. 第一列:IST8310的寄存器
//the second column: the value to be writed to the registers.第二列:需要写入的寄存器值
//the third column: return error value.第三列:返回的错误码
static const rt_uint8_t ist8310_write_reg_data_error[IST8310_WRITE_REG_NUM][3] ={
{0x0B, 0x08, 0x01}, //enalbe interrupt and low pin polarity.开启中断,并且设置低电平
{0x41, 0x09, 0x02}, //average 2 times.平均采样两次
{0x42, 0xC0, 0x03}, //must be 0xC0. 必须是0xC0
{0x0A, 0x0B, 0x04}}; //200Hz output rate.200Hz输出频率
static struct rt_i2c_bus_device *ist8310_i2c_bus = RT_NULL; /* I2C总线设备句柄 */
static rt_bool_t initialized = RT_FALSE; /* 传感器初始化状态 */
rt_err_t ist8310_iic_write(rt_uint8_t write_addr, rt_uint8_t data, rt_uint32_t number);
rt_err_t ist8310_iic_read(rt_uint8_t read_addr, rt_uint32_t len, rt_uint8_t *buf);
void ist8310_read_mag(float mag[3]);
static void read_mag(struct rt_i2c_bus_device *bus,float *cur_mag);/*读取磁场*/
void ist8310_RST_H(void);/*设置RSTN引脚为1*/
void ist8310_RST_L(void);/*设置RSTN引脚为0*/
void ist8310_delay_us(rt_uint16_t us);
rt_err_t ist8310_IIC_write_single_reg(rt_uint8_t reg, rt_uint8_t data);
rt_uint8_t ist8310_IIC_read_single_reg(rt_uint8_t reg, rt_uint8_t len, rt_uint8_t *buf);
static void i2c_ist8310_sample(int argc, char *argv[]);
#endif //RTTHREAD_IST8310_H
运行结果: