前文链接:读取ICM20602(二)GD32F470通过SPI读取ICM20602
代码和示例工程也已同步开源至梁山派官网资料页模块移植章节,欢迎各位前去下载。
梁山派资料页链接:https://lceda001.feishu.cn/wiki/JNvYwEU5SiGldFkNcxncYXhZnZc
在页面内ctrl+F搜索“ICM”即可跳转
测试工程链接:传感器_梁山派: 梁山派移植各个传感器模块的测试工程 - Gitee.com
icm20602.c
#include "icm20602.h"
#include "gd32f4xx.h"
#include "systick.h"
/* 此处定义了与ICM20602有关的宏 */
#define ICM_SPI SPI1
#define ICM_SPI_RCU RCU_SPI1
/* ICM20602使用的SPI总线及相关宏 */
#define ICM_SCK_RCU RCU_GPIOB
#define ICM_SCK_GPIO_PORT GPIOB
#define ICM_SCK_GPIO_PIN GPIO_PIN_10
#define ICM_SCK_GPIO_AF GPIO_AF_5
/* SCK对应的引脚及相关宏 */
#define ICM_MISO_RCU RCU_GPIOB
#define ICM_MISO_GPIO_PORT GPIOB
#define ICM_MISO_GPIO_PIN GPIO_PIN_14
#define ICM_MISO_GPIO_AF GPIO_AF_5
/* MISO对应的引脚及相关宏 */
#define ICM_MOSI_RCU RCU_GPIOC
#define ICM_MOSI_GPIO_PORT GPIOC
#define ICM_MOSI_GPIO_PIN GPIO_PIN_3
#define ICM_MOSI_GPIO_AF GPIO_AF_5
/* MOSI对应的引脚及相关宏 */
#define ICM_NSS_RCU RCU_GPIOB
#define ICM_NSS_GPIO_PORT GPIOB
#define ICM_NSS_GPIO_PIN GPIO_PIN_12
/* NSS对应的引脚及相关宏 */
/* 此处使用软件NSS,因此NSS引脚无需复用 */
#define ICM_NSS_SELECT gpio_bit_reset(ICM_NSS_GPIO_PORT, ICM_NSS_GPIO_PIN)
#define ICM_NSS_RELEASE gpio_bit_set(ICM_NSS_GPIO_PORT, ICM_NSS_GPIO_PIN)
/* 片选函数 */
/* ICM20602地址帧格式如下
* MSB LSB
* R/W A6 A5 A4 A3 A2 A1 A0
*
* 数据帧格式如下
* MSB LSB
* D7 D6 D5 D4 D3 D2 D1 D0
*/
#define REGISTER_READ 0x80
#define REGISTER_WRITE 0x00
/* 定义地址帧的首位,1为读,0为写 */
/* 此处定义了ICM20602的寄存器地址 */
#define XG_OFFS_TC_H 0x04
#define XG_OFFS_TC_L 0x05
#define YG_OFFS_TC_H 0x07
#define YG_OFFS_TC_L 0x08
#define ZG_OFFS_TC_H 0x0a
#define ZG_OFFS_TC_L 0x0b
/* 陀螺仪低噪声至低功耗偏移误差和陀螺仪失调温度补偿(TC)寄存器 */
#define SELF_TEST_X_ACCEL 0x0d
#define SELF_TEST_Y_ACCEL 0x0e
#define SELF_TEST_Z_ACCEL 0x0f
/* 自检寄存器,此寄存器中的值表示制造测试期间生成的自检输出。此值用于检查最终用户执行的后续自检输出。 */
#define XG_OFFS_USRH 0x13
#define XG_OFFS_USRL 0x14
#define YG_OFFS_USRH 0x15
#define YG_OFFS_USRL 0x16
#define ZG_OFFS_USRH 0x17
#define ZG_OFFS_USRL 0x18
/* 陀螺仪偏移校正寄存器 */
#define SMPLRT_DIV 0x19
/* 采样率分频器 */
#define CONFIG 0x1a
/* 配置寄存器 */
#define GYRO_CONFIG 0x1b
/* 陀螺仪配置寄存器 */
#define ACCEL_CONFIG_1 0x1c
/* 加速度计配置寄存器1 */
#define ACCEL_CONFIG_2 0x1d
/* 加速度配置寄存器2 */
#define LP_MODE_CFG 0x1e
/* 低功耗模式配置寄存器 */
#define ACCEL_WOM_X_THR 0x20
#define ACCEL_WOM_Y_THR 0x21
#define ACCEL_WOM_Z_THR 0x22
/* 运动中断唤醒阈值寄存器 */
#define FIFO_EN 0x23
/* 队列使能寄存器 */
#define FSYNC_INT 0x36
/* FSYNC中断标志寄存器,生成 FSYNC 中断后,此位会自动设置为 1。读取寄存器后,位清除为 0。 */
#define INT_PIN_CFG 0x37
/* FSYNC中断配置寄存器 */
#define FIFO_WM_INT_STATUS 0x39
/* 先进先出水印中断状态。读取时清除 */
#define INT_STATUS 0x3a
/* 中断状态寄存器 */
#define ACCEL_XOUT_H 0x3b
#define ACCEL_XOUT_L 0x3c
#define ACCEL_YOUT_H 0x3d
#define ACCEL_YOUT_L 0x3e
#define ACCEL_ZOUT_H 0x3f
#define ACCEL_ZOUT_L 0x40
/* 加速度计数据寄存器 */
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
/* 温度传感器数据寄存器 */
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48
/* 陀螺仪数据寄存器 */
#define SELF_TEST_X_GYRO 0x50
#define SELF_TEST_Y_GYRO 0x51
#define SELF_TEST_Z_GYRO 0x52
/* 陀螺仪自检输出寄存器,此寄存器中的值表示制造测试期间生成的自检输出。此值用于检查最终用户执行的后续自检输出。 */
#define FIFO_WM_TH1 0x60
#define FIFO_WM_TH2 0x61
/* 水印中断阈值寄存器 */
#define SIGNAL_PATH_RESET 0x68
/* 加速度数字信号路径复位寄存器 */
#define ACCEL_INTEL_CTRL 0x69
/* 加速度计控制寄存器 */
#define USER_CTRL 0x6a
/* 用户控制寄存器 */
#define PWR_MGMT_1 0x6b
/* 电源管理寄存器1 */
#define PWR_MGMT_2 0x6c
/* 电源管理寄存器2 */
#define I2C_IF 0x70
/* IIC接口寄存器 */
#define FIFO_COUNTH 0x72
#define FIFO_COUNTL 0x73
/* 队列写入数寄存器 */
#define FIFO_R_W 0x74
/* 队列读/写操作寄存器 */
#define WHO_AM_I 0x75
/* 设备身份验证寄存器 */
#define XA_OFFSET_H 0x77
#define XA_OFFSET_L 0x78
#define YA_OFFSET_H 0x7a
#define YA_OFFSET_L 0x7b
#define ZA_OFFSET_H 0x7d
#define ZA_OFFSET_L 0x7e
/* 加速度计偏移寄存器 */
/* 使能外设时钟 */
static void rcu_config(void)
{
rcu_periph_clock_enable(ICM_SPI_RCU);
rcu_periph_clock_enable(ICM_SCK_RCU);
rcu_periph_clock_enable(ICM_MISO_RCU);
rcu_periph_clock_enable(ICM_MOSI_RCU);
rcu_periph_clock_enable(ICM_NSS_RCU);
}
/* 配置外设引脚 */
static void gpio_config(void)
{
/* 配置SPI SCK引脚 */
gpio_output_options_set(ICM_SCK_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ICM_SCK_GPIO_PIN);
gpio_mode_set(ICM_SCK_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, ICM_SCK_GPIO_PIN);
gpio_af_set(ICM_SCK_GPIO_PORT, ICM_SCK_GPIO_AF, ICM_SCK_GPIO_PIN);
/* 配置SPI MISO引脚 */
gpio_output_options_set(ICM_MISO_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ICM_MISO_GPIO_PIN);
gpio_mode_set(ICM_MISO_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, ICM_MISO_GPIO_PIN);
gpio_af_set(ICM_MISO_GPIO_PORT, ICM_MISO_GPIO_AF, ICM_MISO_GPIO_PIN);
/* 配置SPI MOSI引脚 */
gpio_output_options_set(ICM_MOSI_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ICM_MOSI_GPIO_PIN);
gpio_mode_set(ICM_MOSI_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, ICM_MOSI_GPIO_PIN);
gpio_af_set(ICM_MOSI_GPIO_PORT, ICM_MOSI_GPIO_AF, ICM_MOSI_GPIO_PIN);
/* 配置SPI NSS引脚 */
gpio_mode_set(ICM_NSS_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ICM_NSS_GPIO_PIN);
gpio_output_options_set(ICM_NSS_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ICM_NSS_GPIO_PIN);
}
/* 配置SPI总线 */
static void spi_config(void)
{
spi_parameter_struct spi_init_struct;
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; /* 全双工模式 */
spi_init_struct.device_mode = SPI_MASTER; /* 主机模式 */
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; /* 帧长为8位 */
spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE; /* 上升沿采样,下降沿传输 */
spi_init_struct.nss = SPI_NSS_SOFT; /* 软件NSS */
spi_init_struct.prescale = SPI_PSC_32; /* 通讯频率为主频32分频,即3.75Mbit/s */
spi_init_struct.endian = SPI_ENDIAN_MSB; /* MSB优先传输 */
spi_init(ICM_SPI, &spi_init_struct);
}
/*
* 功能 ICM20602写寄存器
* 参数 addr 寄存器地址
* dat 需要写入的数据
* 返回 无
*/
static void icm20602_writeReg(uint8_t addr, uint8_t dat)
{
uint8_t cmd;
ICM_NSS_SELECT;
cmd = addr | REGISTER_WRITE; /* 注:此处的运算实质上起到了NSS引脚拉低后的2ns延时作用,因此不可移除 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_RBNE))
spi_i2s_data_receive(ICM_SPI);/* 读取读SPI_DATA寄存器中的数据以复位RBNE标志位 */
while(RESET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE));/* 等待发送缓冲区清空 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE))
spi_i2s_data_transmit(ICM_SPI, cmd);/* 发送地址与写指令 */
while(RESET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE));/* 等待发送缓冲区清空 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE))
spi_i2s_data_transmit(ICM_SPI, dat);/* 发送需要写入寄存器的值 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TRANS))/* 等待数据传输完毕 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_RBNE))
spi_i2s_data_receive(ICM_SPI);/* 读取读SPI_DATA寄存器中的数据以复位RBNE标志位 */
while(RESET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE));/* 等待发送缓冲区清空 */
ICM_NSS_RELEASE;
}
/*
* 功能 ICM20602读寄存器
* 参数 addr 寄存器地址
* dat 读取得到的数据
* 返回 无
*/
static void icm20602_readReg(uint8_t addr, uint8_t *dat)
{
uint8_t cmd;
uint8_t res;
ICM_NSS_SELECT;
cmd = addr | REGISTER_READ; /* 注:此处的运算实质上起到了NSS引脚拉低后的2ns延时作用,因此不可移除 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_RBNE))
res = spi_i2s_data_receive(ICM_SPI);/* 读取读SPI_DATA寄存器中的数据以复位RBNE标志位 */
while(RESET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE));/* 等待发送缓冲区清空 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE))
spi_i2s_data_transmit(ICM_SPI, cmd);/* 发送地址与读指令 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TRANS));/* 等待数据传输完毕 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_RBNE))
spi_i2s_data_receive(ICM_SPI);/* 本周期(以缓冲区内数据发送完成为结束)内收到的数据不能使用 */
while(RESET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE));/* 等待发送缓冲区清空 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE))
spi_i2s_data_transmit(ICM_SPI, 0x00);/* 传输数据以进行接收 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TRANS));/* 等待数据传输完毕 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_RBNE))
res = spi_i2s_data_receive(ICM_SPI);/* 这个周期收到的才是传感器返回的数据 */
while(RESET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE));/* 等待发送缓冲区清空 */
ICM_NSS_RELEASE;
*dat = res;
}
/*
* 功能 ICM20602读取多字节数据
* 参数 addr 寄存器地址
* dat 读取得到的数据
* len 需要读取的数据长度
* 返回 无
*/
static void icm20602_readBytes(uint8_t addr, uint8_t *dat_array, uint8_t len)
{
uint8_t cmd;
uint8_t *dat_ptr = dat_array;
uint8_t i;
ICM_NSS_SELECT;
cmd = addr | REGISTER_READ; /* 注:此处的运算实质上起到了NSS引脚拉低后的2ns延时作用,因此不可移除 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_RBNE))
spi_i2s_data_receive(ICM_SPI);/* 读取读SPI_DATA寄存器中的数据以复位RBNE标志位 */
while(RESET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE));/* 等待发送缓冲区清空 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE))
spi_i2s_data_transmit(ICM_SPI, cmd);/* 发送地址与读指令 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TRANS));/* 等待数据传输完毕 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_RBNE))
spi_i2s_data_receive(ICM_SPI);/* 本周期(以缓冲区内数据发送完成为结束)内收到的数据不能使用 */
while(RESET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE));/* 等待发送缓冲区清空 */
for(i = 0; i < len; i++)
{
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE))
spi_i2s_data_transmit(ICM_SPI, *dat_ptr);/* 传输数据以进行接收 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TRANS));/* 等待数据传输完毕 */
while(SET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_RBNE))
*dat_ptr = spi_i2s_data_receive(ICM_SPI);/* 这个周期收到的才是传感器返回的数据 */
while(RESET == spi_i2s_flag_get(ICM_SPI, SPI_FLAG_TBE));/* 等待发送缓冲区清空 */
dat_ptr++;
}
ICM_NSS_RELEASE;
}
/*
* 功能 ICM20602自检
* 参数 无
* 返回 无
*/
void icm20602_selfTest(void)
{
uint8_t deviceID = 0x00;
while(deviceID != 0x12)
{
icm20602_readReg(WHO_AM_I, &deviceID);
delay_1ms(10);
//卡在这里原因有以下几点
//1 传感器坏了,如果是新的这样的概率极低
//2 接线错误或者没有接好
//3 可能你需要外接上拉电阻,上拉到3.3V
//(转自逐飞库)
}
}
/*
* 功能 ICM20602初始化
* 参数 icm_struct icm20602_parameter_struct类型指针,指向一个icm20602配置结构体
* 返回 无
*/
void icm20602_init(icm20602_parameter_struct *icm_struct)
{
uint8_t regValue = 0x00;
icm20602_parameter_struct icm_temp_param = *icm_struct;
rcu_config();
gpio_config();
spi_config();
ICM_NSS_RELEASE;
spi_enable(ICM_SPI);
/* 初始化SPI并释放片选引脚 */
delay_1ms(10);
icm20602_selfTest();
/* 上电自检 */
icm20602_writeReg(PWR_MGMT_1, 0x80);
/* 复位全部寄存器 */
delay_1ms(2);
while(0x41 != regValue)
{
icm20602_readReg(PWR_MGMT_1, ®Value);
delay_1ms(5);
}/* 等待复位完成 */
icm20602_writeReg(I2C_IF, 0x00);/* 禁用I2C接口,使模块工作于SPI模式 */
icm20602_writeReg(PWR_MGMT_1, 0x01);/* 设置时钟源 */
switch(icm_temp_param.gyro_tempture_band)/* 配置陀螺仪滤波器与温度计滤波器带宽 */
{
case GYRO_3281HZ_TEMPERATURE_4000HZ_RATE_8KHZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x07);
break;
case GYRO_5HZ_TEMPERATURE_5HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x06);
break;
case GYRO_10HZ_TEMPERATURE_10HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x05);
break;
case GYRO_20HZ_TEMPERATURE_20HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x04);
break;
case GYRO_41HZ_TEMPERATURE_42HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x03);
break;
case GYRO_92HZ_TEMPERATURE_98HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x02);
break;
case GYRO_176HZ_TEMPERATURE_188HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x01);
break;
case GYRO_250HZ_TEMPERATURE_4000HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x00);
break;
case GYRO_3281HZ_TEMPERATURE_4000HZ_RATE_32KHZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
regValue = regValue | 0x02;
icm20602_writeReg(GYRO_CONFIG, regValue);
break;
case GYRO_8173HZ_TEMPERATURE_4000HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
regValue = regValue | 0x01;
icm20602_writeReg(GYRO_CONFIG,regValue);
break;
}
icm20602_writeReg(SMPLRT_DIV, icm_temp_param.div);
/* 配置采样率分频器,注:仅gyro_tempture_band介于
GYRO_5HZ_TEMPERATURE_5HZ与GYRO_176HZ_TEMPERATURE_188HZ之间时该寄存器有效 */
switch(icm_temp_param.gyro_scale)/* 设置陀螺仪满量程 */
{
case GYRO_250DPS_FULLSCALE:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xe7;
icm20602_writeReg(GYRO_CONFIG, regValue);
break;
case GYRO_500DPS_FULLSCALE:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xe7;
regValue = regValue | 0x08;
icm20602_writeReg(GYRO_CONFIG, regValue);
break;
case GYRO_1000DPS_FULLSCALE:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xe7;
regValue = regValue | 0x10;
icm20602_writeReg(GYRO_CONFIG, regValue);
break;
case GYRO_2000DPS_FULLSCALE:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xe7;
regValue = regValue | 0x18;
icm20602_writeReg(GYRO_CONFIG, regValue);
break;
}
switch(icm_temp_param.accel_scale)/* 设置加速度计满量程 */
{
case ACCEL_2G_FULLSCALE:
icm20602_writeReg(ACCEL_CONFIG_1, 0x00);
break;
case ACCEL_4G_FULLSCALE:
icm20602_writeReg(ACCEL_CONFIG_1, 0x08);
break;
case ACCEL_8G_FULLSCALE:
icm20602_writeReg(ACCEL_CONFIG_1, 0x10);
break;
case ACCEL_16G_FULLSCALE:
icm20602_writeReg(ACCEL_CONFIG_1, 0x18);
break;
}
switch(icm_temp_param.accel_band)/* 配置加速度计低通滤波器带宽 */
{
case ACCEL_5HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x06);
break;
case ACCEL_10HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x05);
break;
case ACCEL_21HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x04);
break;
case ACCEL_45HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x03);
break;
case ACCEL_99HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x02);
break;
case ACCEL_218HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x01);
break;
case ACCEL_420HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x07);
break;
case ACCEL_1046HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x10);
break;
}
icm20602_writeReg(PWR_MGMT_2, 0x00);/* 设置加速度计与陀螺仪使能 */
}
/*
* 功能 设置ICM20602陀螺仪-温度计低通滤波器带宽
* 参数 band:gyro_temperature_3dB_bandWidth枚举类型,需要设置的陀螺仪-温度计低通滤波器带宽
* 返回 无
*/
void icm20602_GyroTempBand_config(gyro_temperature_3dB_bandWidth band)
{
uint8_t regValue;
switch(band)
{
case GYRO_3281HZ_TEMPERATURE_4000HZ_RATE_8KHZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x07);
break;
case GYRO_5HZ_TEMPERATURE_5HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x06);
break;
case GYRO_10HZ_TEMPERATURE_10HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x05);
break;
case GYRO_20HZ_TEMPERATURE_20HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x04);
break;
case GYRO_41HZ_TEMPERATURE_42HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x03);
break;
case GYRO_92HZ_TEMPERATURE_98HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x02);
break;
case GYRO_176HZ_TEMPERATURE_188HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x01);
break;
case GYRO_250HZ_TEMPERATURE_4000HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
icm20602_writeReg(GYRO_CONFIG, regValue);
icm20602_writeReg(CONFIG, 0x00);
break;
case GYRO_3281HZ_TEMPERATURE_4000HZ_RATE_32KHZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
regValue = regValue | 0x02;
icm20602_writeReg(GYRO_CONFIG, regValue);
break;
case GYRO_8173HZ_TEMPERATURE_4000HZ:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xf8;
regValue = regValue | 0x01;
icm20602_writeReg(GYRO_CONFIG,regValue);
break;
}
}
/*
* 功能 设置ICM20602加速度计低通滤波器带宽
* 参数 band:accel_3dB_bandWidth枚举类型,需要设置的加速度计低通滤波器带宽
* 返回 无
*/
void icm20602_AccelBand_config(accel_3dB_bandWidth band)
{
switch(band)
{
case ACCEL_5HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x06);
break;
case ACCEL_10HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x05);
break;
case ACCEL_21HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x04);
break;
case ACCEL_45HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x03);
break;
case ACCEL_99HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x02);
break;
case ACCEL_218HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x01);
break;
case ACCEL_420HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x07);
break;
case ACCEL_1046HZ:
icm20602_writeReg(ACCEL_CONFIG_2, 0x10);
break;
}
}
/*
* 功能 设置ICM20602陀螺仪与加速度计满量程
* 参数 gyro_scale:gyro_fullScale枚举类型,需要设置的陀螺仪满量程
* accel_scale:accel_fullScale枚举类型,需要设置的加速度计满量程
* 返回 无
*/
void icm20602_FullScale_config(gyro_fullScale gyro_scale, accel_fullScale accel_scale)
{
uint8_t regValue;
switch(gyro_scale)/* 设置陀螺仪满量程 */
{
case GYRO_250DPS_FULLSCALE:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xe7;
icm20602_writeReg(GYRO_CONFIG, regValue);
break;
case GYRO_500DPS_FULLSCALE:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xe7;
regValue = regValue | 0x08;
icm20602_writeReg(GYRO_CONFIG, regValue);
break;
case GYRO_1000DPS_FULLSCALE:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xe7;
regValue = regValue | 0x10;
icm20602_writeReg(GYRO_CONFIG, regValue);
break;
case GYRO_2000DPS_FULLSCALE:
icm20602_readReg(GYRO_CONFIG, ®Value);
regValue = regValue & 0xe7;
regValue = regValue | 0x18;
icm20602_writeReg(GYRO_CONFIG, regValue);
break;
}
switch(accel_scale)/* 设置加速度计满量程 */
{
case ACCEL_2G_FULLSCALE:
icm20602_writeReg(ACCEL_CONFIG_1, 0x00);
break;
case ACCEL_4G_FULLSCALE:
icm20602_writeReg(ACCEL_CONFIG_1, 0x08);
break;
case ACCEL_8G_FULLSCALE:
icm20602_writeReg(ACCEL_CONFIG_1, 0x10);
break;
case ACCEL_16G_FULLSCALE:
icm20602_writeReg(ACCEL_CONFIG_1, 0x18);
break;
}
}
/*
* 功能 获取ICM20602加速度数据
* 参数 accelList:uint16_t类型的数组指针,用于存储返回的加速度值,按顺序依次存储X、Y、Z轴加速度
* 返回 无
*/
void icm20602_ReadAccel(int16_t *accelList)
{
uint8_t addr = ACCEL_XOUT_H;
uint8_t dat[6];
icm20602_readBytes(addr, dat, 6);
accelList[0] = (int16_t)((uint16_t)dat[0] << 8 | dat[1]);
accelList[1] = (int16_t)((uint16_t)dat[2] << 8 | dat[3]);
accelList[2] = (int16_t)((uint16_t)dat[4] << 8 | dat[5]);
}
/*
* 功能 获取ICM20602角速度数据
* 参数 gyroList:uint16_t类型的数组指针,用于存储返回的角速度值,按顺序依次存储绕X、Y、Z轴角速度
* 返回 无
*/
void icm20602_ReadGyro(int16_t *gyroList)
{
uint8_t addr = GYRO_XOUT_H;
uint8_t dat[6];
icm20602_readBytes(addr, dat, 6);
gyroList[0] = (int16_t)((uint16_t)dat[0] << 8 | dat[1]);
gyroList[1] = (int16_t)((uint16_t)dat[2] << 8 | dat[3]);
gyroList[2] = (int16_t)((uint16_t)dat[4] << 8 | dat[5]);
}
/*
* 功能 获取ICM20602温度传感器数据
* 参数 gyroList:uint16_t类型的数组指针,用于存储返回的角速度值,按顺序依次存储绕X、Y、Z轴角速度
* 返回 无
*/
void icm20602_ReadTempture(float *temp)
{
uint8_t addr = TEMP_OUT_H;
uint8_t dat[2];
icm20602_readBytes(addr, dat, 2);
*temp = (double)((int16_t)((uint16_t)dat[0] << 8 |dat[1])/326.8) + 25.0;
}
icm20602.h
#ifndef __ICM20602_H__
#define __ICM20602_H__
#include "gd32f4xx.h"
/* 用于描述陀螺仪满量程的枚举类型,详见芯片的Datasheet */
typedef enum
{
GYRO_250DPS_FULLSCALE = 0,
GYRO_500DPS_FULLSCALE,
GYRO_1000DPS_FULLSCALE,
GYRO_2000DPS_FULLSCALE
}gyro_fullScale;
/* 用于描述加速度计满量程的枚举类型,详见芯片的Datasheet */
typedef enum
{
ACCEL_2G_FULLSCALE = 0,
ACCEL_4G_FULLSCALE,
ACCEL_8G_FULLSCALE,
ACCEL_16G_FULLSCALE,
}accel_fullScale;
/* 用于描述陀螺仪-温度计低通滤波器3dB带宽的枚举类型,详见芯片的Datasheet */
typedef enum
{
GYRO_3281HZ_TEMPERATURE_4000HZ_RATE_8KHZ = 0,
GYRO_5HZ_TEMPERATURE_5HZ,
GYRO_10HZ_TEMPERATURE_10HZ,
GYRO_20HZ_TEMPERATURE_20HZ,
GYRO_41HZ_TEMPERATURE_42HZ,
GYRO_92HZ_TEMPERATURE_98HZ,
GYRO_176HZ_TEMPERATURE_188HZ,
GYRO_250HZ_TEMPERATURE_4000HZ,
GYRO_3281HZ_TEMPERATURE_4000HZ_RATE_32KHZ,
GYRO_8173HZ_TEMPERATURE_4000HZ,
}gyro_temperature_3dB_bandWidth;
/* 用于描述加速度计低通滤波器3dB带宽的枚举类型,详见芯片的Datasheet */
typedef enum
{
ACCEL_420HZ = 0,
ACCEL_5HZ,
ACCEL_10HZ,
ACCEL_21HZ,
ACCEL_45HZ,
ACCEL_99HZ,
ACCEL_218HZ,
ACCEL_1046HZ,
}accel_3dB_bandWidth;
/* icm20602初始化结构体,用于配置icm20602 */
typedef struct
{
gyro_fullScale gyro_scale; /* 陀螺仪满量程 */
accel_fullScale accel_scale; /* 加速度计满量程 */
gyro_temperature_3dB_bandWidth gyro_tempture_band; /* 陀螺仪-温度计低通滤波器带宽 */
accel_3dB_bandWidth accel_band; /* 加速度计低通滤波器带宽 */
uint8_t div; /* 采样率分频器,仅仅gyro_tempture_band介于
GYRO_5HZ_TEMPERATURE_5HZ与GYRO_176HZ_TEMPERATURE_188HZ之间
时该寄存器有效 */
}icm20602_parameter_struct;
void icm20602_selfTest(void);/* icm20602自检 */
void icm20602_init(icm20602_parameter_struct *icm_struct);/* icm20602初始化 */
void icm20602_GyroTempBand_config(gyro_temperature_3dB_bandWidth band);/* 设置icm20602陀螺仪-温度传感器低通滤波器带宽 */
void icm20602_AccelBand_config(accel_3dB_bandWidth band);/* 设置icm20602加速度计低通滤波器带宽 */
void icm20602_FullScale_config(gyro_fullScale gyro_scale, accel_fullScale accel_scale);/* 设置icm20602陀螺仪与加速度计满量程 */
void icm20602_ReadAccel(int16_t *accelList);/* 读取icm20602三轴加速度 */
void icm20602_ReadGyro(int16_t *gyroList);/* 读取icm20602三轴角速度 */
void icm20602_ReadTempture(float *temp);/* 读取icm20602温度传感器数值 */
#endif