Files
QD4C-firmware/libraries/zf_device/zf_device_imu660ra.c

340 lines
17 KiB
C
Raw Normal View History

2023-12-11 21:45:06 +08:00
/*********************************************************************************************************************
2023-12-14 21:18:55 +08:00
* CH32V307VCT6 Opensourec Library CH32V307VCT6 SDK
* Copyright (c) 2022 SEEKFREE
*
* CH32V307VCT6
*
* CH32V307VCT6
* GPLGNU General Public License GNU
* GPL 3 GPL3.0/
*
*
*
* GPL
*
* GPL
* <https://www.gnu.org/licenses/>
*
*
* 使 GPL3.0
* libraries/doc GPL3_permission_statement.txt
* libraries LICENSE
* 使
*
* zf_device_imu660ra
*
* libraries/doc version
* MounRiver Studio V1.8.1
* CH32V307VCT6
* https://seekfree.taobao.com/
*
*
*
* 2022-09-15 W first version
********************************************************************************************************************/
2023-12-11 21:45:06 +08:00
/*********************************************************************************************************************
2023-12-14 21:18:55 +08:00
* 线
* ------------------------------------
*
* // 硬件 SPI 引脚
* SCL/SPC zf_device_imu660ra.h IMU660RA_SPC_PIN
* SDA/DSI zf_device_imu660ra.h IMU660RA_SDI_PIN
* SA0/SDO zf_device_imu660ra.h IMU660RA_SDO_PIN
* CS zf_device_imu660ra.h IMU660RA_CS_PIN
* VCC 3.3V
* GND
*
*
* // 软件 IIC 引脚
* SCL/SPC zf_device_imu660ra.h IMU660RA_SCL_PIN
* SDA/DSI zf_device_imu660ra.h IMU660RA_SDA_PIN
* VCC 3.3V
* GND
*
* ------------------------------------
********************************************************************************************************************/
2023-12-11 21:45:06 +08:00
#include "zf_common_debug.h"
#include "zf_driver_delay.h"
#include "zf_driver_spi.h"
#include "zf_driver_gpio.h"
#include "zf_driver_soft_iic.h"
#include "zf_device_config.h"
#include "zf_device_imu660ra.h"
2023-12-14 21:18:55 +08:00
int16 imu660ra_gyro_x = 0;
int16 imu660ra_gyro_y = 0;
int16 imu660ra_gyro_z = 0; // 三轴陀螺仪数据 gyro (陀螺仪)
int16 imu660ra_acc_x = 0;
int16 imu660ra_acc_y = 0;
int16 imu660ra_acc_z = 0; // 三轴加速度计数据 acc (accelerometer 加速度计)
float imu660ra_temperature = 0;
float imu660ra_transition_factor[2] = {4096, 16.4f};
2023-12-11 21:45:06 +08:00
#if IMU660RA_USE_SOFT_IIC
static soft_iic_info_struct imu660ra_iic_struct;
2023-12-14 21:18:55 +08:00
#define imu660ra_write_register(reg, data) (soft_iic_write_8bit_register(&imu660ra_iic_struct, (reg), (data)))
#define imu660ra_write_registers(reg, data, len) (soft_iic_write_8bit_registers(&imu660ra_iic_struct, (reg), (data), (len)))
#define imu660ra_read_register(reg) (soft_iic_read_8bit_register(&imu660ra_iic_struct, (reg)))
#define imu660ra_read_registers(reg, data, len) (soft_iic_read_8bit_registers(&imu660ra_iic_struct, (reg), (data), (len)))
2023-12-11 21:45:06 +08:00
#else
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RA 写寄存器
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 imu660ra_write_register(IMU660RA_PWR_CONF, 0x00); // 关闭高级省电模式
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660ra_write_register(uint8 reg, uint8 data)
{
IMU660RA_CS(0);
spi_write_8bit_register(IMU660RA_SPI, reg | IMU660RA_SPI_W, data);
IMU660RA_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RA 写数据
// 参数说明 reg 寄存器地址
// 参数说明 data 数据
// 返回参数 void
// 使用示例 imu660ra_write_registers(IMU660RA_INIT_DATA, imu660ra_config_file, sizeof(imu660ra_config_file));
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660ra_write_registers(uint8 reg, const uint8 *data, uint32 len)
{
IMU660RA_CS(0);
spi_write_8bit_registers(IMU660RA_SPI, reg | IMU660RA_SPI_W, data, len);
IMU660RA_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RA 读寄存器
// 参数说明 reg 寄存器地址
// 返回参数 uint8 数据
// 使用示例 imu660ra_read_register(IMU660RA_CHIP_ID);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static uint8 imu660ra_read_register(uint8 reg)
{
uint8 data[2];
IMU660RA_CS(0);
spi_read_8bit_registers(IMU660RA_SPI, reg | IMU660RA_SPI_R, data, 2);
IMU660RA_CS(1);
return data[1];
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RA 读数据
// 参数说明 reg 寄存器地址
// 参数说明 data 数据缓冲区
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 imu660ra_read_registers(IMU660RA_ACC_ADDRESS, dat, 6);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void imu660ra_read_registers(uint8 reg, uint8 *data, uint32 len)
{
uint8 temp_data[8];
IMU660RA_CS(0);
spi_read_8bit_registers(IMU660RA_SPI, reg | IMU660RA_SPI_R, temp_data, len + 1);
IMU660RA_CS(1);
2023-12-14 21:18:55 +08:00
for (int i = 0; i < len; i++) {
*(data++) = temp_data[i + 1];
2023-12-11 21:45:06 +08:00
}
}
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IMU660RA 自检
// 参数说明 void
// 返回参数 uint8 1-自检失败 0-自检成功
// 使用示例 imu660ra_self_check();
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
2023-12-14 21:18:55 +08:00
static uint8 imu660ra_self_check(void)
2023-12-11 21:45:06 +08:00
{
2023-12-14 21:18:55 +08:00
uint8 dat = 0;
uint8 return_state = 0;
2023-12-11 21:45:06 +08:00
uint16 timeout_count = 0;
2023-12-14 21:18:55 +08:00
do {
if (timeout_count++ > IMU660RA_TIMEOUT_COUNT) {
return_state = 1;
2023-12-11 21:45:06 +08:00
break;
}
dat = imu660ra_read_register(IMU660RA_CHIP_ID);
system_delay_ms(1);
2023-12-14 21:18:55 +08:00
} while (0x24 != dat); // 读取设备 ID 是否等于 0X24如果不是 0X24 则认为没检测到设备
2023-12-11 21:45:06 +08:00
return return_state;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 IMU660RA 加速度计数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu660ra_get_acc(); // 执行该函数后,直接查看对应的变量即可
2023-12-14 21:18:55 +08:00
// 备注信息 使用 SPI 的采集时间为 69us
// 使用 IIC 的采集时间为 126us 采集加速度计的时间与采集陀螺仪的时间一致的原因是都只是读取寄存器数据
2023-12-11 21:45:06 +08:00
//-------------------------------------------------------------------------------------------------------------------
2023-12-14 21:18:55 +08:00
void imu660ra_get_acc(void)
2023-12-11 21:45:06 +08:00
{
uint8 dat[6];
imu660ra_read_registers(IMU660RA_ACC_ADDRESS, dat, 6);
2023-12-14 21:18:55 +08:00
imu660ra_acc_x = (int16)(((uint16)dat[1] << 8 | dat[0]));
imu660ra_acc_y = (int16)(((uint16)dat[3] << 8 | dat[2]));
imu660ra_acc_z = (int16)(((uint16)dat[5] << 8 | dat[4]));
2023-12-11 21:45:06 +08:00
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 获取 IMU660RA 陀螺仪数据
// 参数说明 void
// 返回参数 void
// 使用示例 imu660ra_get_gyro(); // 执行该函数后,直接查看对应的变量即可
2023-12-14 21:18:55 +08:00
// 备注信息 使用 SPI 的采集时间为 69us
// 使用 IIC 的采集时间为 126us
2023-12-11 21:45:06 +08:00
//-------------------------------------------------------------------------------------------------------------------
2023-12-14 21:18:55 +08:00
void imu660ra_get_gyro(void)
2023-12-11 21:45:06 +08:00
{
uint8 dat[6];
imu660ra_read_registers(IMU660RA_GYRO_ADDRESS, dat, 6);
2023-12-14 21:18:55 +08:00
imu660ra_gyro_x = (int16)(((uint16)dat[1] << 8 | dat[0]));
imu660ra_gyro_y = (int16)(((uint16)dat[3] << 8 | dat[2]));
imu660ra_gyro_z = (int16)(((uint16)dat[5] << 8 | dat[4]));
}
void imu660ra_get_temperature(void)
{
uint8_t dat[2];
imu660ra_read_registers(IMU660RA_TEMP_ADDRESS, dat, 2);
imu660ra_temperature = (int16_t)((uint16_t)dat[1] << 8 | dat[0]);
imu660ra_temperature = imu660ra_temperature / 512.0f + 23.0f;
2023-12-11 21:45:06 +08:00
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 初始化 IMU660RA
// 参数说明 void
// 返回参数 uint8 1-初始化失败 0-初始化成功
// 使用示例 imu660ra_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
2023-12-14 21:18:55 +08:00
uint8 imu660ra_init(void)
2023-12-11 21:45:06 +08:00
{
uint8 return_state = 0;
// 先给 IMU660RA 断电重启
gpio_init(IMU660RA_PE_PIN, GPO, 0, GPO_PUSH_PULL); // 配置 IMU660RA 的 PE 端口
gpio_low(IMU660RA_PE_PIN);
system_delay_ms(100);
gpio_high(IMU660RA_PE_PIN);
2023-12-14 21:18:55 +08:00
system_delay_ms(20); // 等待设备上电成功
2023-12-11 21:45:06 +08:00
#if IMU660RA_USE_SOFT_IIC
2023-12-14 21:18:55 +08:00
soft_iic_init(&imu660ra_iic_struct, IMU660RA_DEV_ADDR, IMU660RA_SOFT_IIC_DELAY, IMU660RA_SCL_PIN, IMU660RA_SDA_PIN); // 配置 IMU660RA 的 IIC 端口
2023-12-11 21:45:06 +08:00
#else
2024-03-02 16:05:24 +08:00
spi_init(IMU660RA_SPI, SPI_MODE0, IMU660RA_SPI_SPEED, IMU660RA_SPC_PIN, IMU660RA_SDI_PIN, IMU660RA_SDO_PIN, IMU660RA_CS_PIN); // 配置 IMU660RA 的 SPI 端口
gpio_init(IMU660RA_CS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL); // 配置 IMU660RA 的 CS 端口
imu660ra_read_register(IMU660RA_CHIP_ID); // 读取一下设备 ID 将设备设置为 SPI 模式
2023-12-11 21:45:06 +08:00
#endif
2023-12-14 21:18:55 +08:00
do {
if (imu660ra_self_check()) // IMU660RA 自检
2023-12-11 21:45:06 +08:00
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是 IMU660RA 自检出错并超时退出了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "imu660ra self check error.");
return_state = 1;
break;
}
2023-12-14 21:18:55 +08:00
imu660ra_write_register(IMU660RA_PWR_CONF, 0x00); // 关闭高级省电模式
2023-12-11 21:45:06 +08:00
system_delay_ms(1);
2023-12-14 21:18:55 +08:00
imu660ra_write_register(IMU660RA_INIT_CTRL, 0x00); // 开始对模块进行初始化配置
imu660ra_write_registers(IMU660RA_INIT_DATA, imu660ra_config_file, sizeof(imu660ra_config_file)); // 输出配置文件
imu660ra_write_register(IMU660RA_INIT_CTRL, 0x01); // 初始化配置结束
2023-12-11 21:45:06 +08:00
system_delay_ms(20);
2023-12-14 21:18:55 +08:00
if (1 != imu660ra_read_register(IMU660RA_INT_STA)) // 检查是否配置完成
2023-12-11 21:45:06 +08:00
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么就是 IMU660RA 配置初始化文件出错了
// 检查一下接线有没有问题 如果没问题可能就是坏了
zf_log(0, "imu660ra init error.");
return_state = 1;
break;
}
2023-12-14 21:18:55 +08:00
imu660ra_write_register(IMU660RA_PWR_CTRL, 0x0E); // 开启性能模式 使能陀螺仪、加速度、温度传感器
imu660ra_write_register(IMU660RA_ACC_CONF, 0xA7); // 加速度采集配置 性能模式 正常采集 50Hz 采样频率
imu660ra_write_register(IMU660RA_GYR_CONF, 0xAC); // 陀螺仪采集配置 性能模式 正常采集 1600Hz 采样频率
2023-12-11 21:45:06 +08:00
// IMU660RA_ACC_SAMPLE 寄存器
// 设置为 0x00 加速度计量程为 ±2 g 获取到的加速度计数据除以 16384 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x01 加速度计量程为 ±4 g 获取到的加速度计数据除以 8192 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x02 加速度计量程为 ±8 g 获取到的加速度计数据除以 4096 可以转化为带物理单位的数据 单位 g(m/s^2)
// 设置为 0x03 加速度计量程为 ±16 g 获取到的加速度计数据除以 2048 可以转化为带物理单位的数据 单位 g(m/s^2)
2023-12-14 21:18:55 +08:00
switch (IMU660RA_ACC_SAMPLE_DEFAULT) {
default: {
2023-12-11 21:45:06 +08:00
zf_log(0, "IMU660RA_ACC_SAMPLE_DEFAULT set error.");
return_state = 1;
2023-12-14 21:18:55 +08:00
} break;
case IMU660RA_ACC_SAMPLE_SGN_2G: {
2023-12-11 21:45:06 +08:00
imu660ra_write_register(IMU660RA_ACC_RANGE, 0x00);
imu660ra_transition_factor[0] = 16384;
2023-12-14 21:18:55 +08:00
} break;
case IMU660RA_ACC_SAMPLE_SGN_4G: {
2023-12-11 21:45:06 +08:00
imu660ra_write_register(IMU660RA_ACC_RANGE, 0x01);
imu660ra_transition_factor[0] = 8192;
2023-12-14 21:18:55 +08:00
} break;
case IMU660RA_ACC_SAMPLE_SGN_8G: {
2023-12-11 21:45:06 +08:00
imu660ra_write_register(IMU660RA_ACC_RANGE, 0x02);
imu660ra_transition_factor[0] = 4096;
2023-12-14 21:18:55 +08:00
} break;
case IMU660RA_ACC_SAMPLE_SGN_16G: {
2023-12-11 21:45:06 +08:00
imu660ra_write_register(IMU660RA_ACC_RANGE, 0x03);
imu660ra_transition_factor[0] = 2048;
2023-12-14 21:18:55 +08:00
} break;
2023-12-11 21:45:06 +08:00
}
2023-12-14 21:18:55 +08:00
if (1 == return_state) {
2023-12-11 21:45:06 +08:00
break;
}
// IMU660RA_GYR_RANGE 寄存器
// 设置为 0x04 陀螺仪量程为 ±125 dps 获取到的陀螺仪数据除以 262.4 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x03 陀螺仪量程为 ±250 dps 获取到的陀螺仪数据除以 131.2 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x02 陀螺仪量程为 ±500 dps 获取到的陀螺仪数据除以 65.6 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x01 陀螺仪量程为 ±1000 dps 获取到的陀螺仪数据除以 32.8 可以转化为带物理单位的数据 单位为 °/s
// 设置为 0x00 陀螺仪量程为 ±2000 dps 获取到的陀螺仪数据除以 16.4 可以转化为带物理单位的数据 单位为 °/s
2023-12-14 21:18:55 +08:00
switch (IMU660RA_GYRO_SAMPLE_DEFAULT) {
default: {
2023-12-11 21:45:06 +08:00
zf_log(0, "IMU660RA_GYRO_SAMPLE_DEFAULT set error.");
return_state = 1;
2023-12-14 21:18:55 +08:00
} break;
case IMU660RA_GYRO_SAMPLE_SGN_125DPS: {
2023-12-11 21:45:06 +08:00
imu660ra_write_register(IMU660RA_GYR_RANGE, 0x04);
imu660ra_transition_factor[1] = 262.4;
2023-12-14 21:18:55 +08:00
} break;
case IMU660RA_GYRO_SAMPLE_SGN_250DPS: {
2023-12-11 21:45:06 +08:00
imu660ra_write_register(IMU660RA_GYR_RANGE, 0x03);
imu660ra_transition_factor[1] = 131.2;
2023-12-14 21:18:55 +08:00
} break;
case IMU660RA_GYRO_SAMPLE_SGN_500DPS: {
2023-12-11 21:45:06 +08:00
imu660ra_write_register(IMU660RA_GYR_RANGE, 0x02);
imu660ra_transition_factor[1] = 65.6;
2023-12-14 21:18:55 +08:00
} break;
case IMU660RA_GYRO_SAMPLE_SGN_1000DPS: {
2023-12-11 21:45:06 +08:00
imu660ra_write_register(IMU660RA_GYR_RANGE, 0x01);
imu660ra_transition_factor[1] = 32.8;
2023-12-14 21:18:55 +08:00
} break;
case IMU660RA_GYRO_SAMPLE_SGN_2000DPS: {
2023-12-11 21:45:06 +08:00
imu660ra_write_register(IMU660RA_GYR_RANGE, 0x00);
imu660ra_transition_factor[1] = 16.4;
2023-12-14 21:18:55 +08:00
} break;
2023-12-11 21:45:06 +08:00
}
2023-12-14 21:18:55 +08:00
if (1 == return_state) {
2023-12-11 21:45:06 +08:00
break;
}
2023-12-14 21:18:55 +08:00
} while (0);
2023-12-11 21:45:06 +08:00
return return_state;
}