读取ICM20602(三)GD32F470读取ICM20602代码开源

前文链接:读取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, &regValue);
		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, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x07);
			break;
		case GYRO_5HZ_TEMPERATURE_5HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x06);
			break;
		case GYRO_10HZ_TEMPERATURE_10HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x05);
			break;
		case GYRO_20HZ_TEMPERATURE_20HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x04);
			break;
		case GYRO_41HZ_TEMPERATURE_42HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x03);
			break;
		case GYRO_92HZ_TEMPERATURE_98HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x02);
			break;
		case GYRO_176HZ_TEMPERATURE_188HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x01);
			break;
		case GYRO_250HZ_TEMPERATURE_4000HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x00);
			break;
		case GYRO_3281HZ_TEMPERATURE_4000HZ_RATE_32KHZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			regValue = regValue | 0x02;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			break;
		case GYRO_8173HZ_TEMPERATURE_4000HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			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, &regValue);
			regValue = regValue & 0xe7;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			break;
		case GYRO_500DPS_FULLSCALE:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xe7;
			regValue = regValue | 0x08;
			icm20602_writeReg(GYRO_CONFIG, regValue);			
			break;
		case GYRO_1000DPS_FULLSCALE:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xe7;
			regValue = regValue | 0x10;
			icm20602_writeReg(GYRO_CONFIG, regValue);			
			break;
		case GYRO_2000DPS_FULLSCALE:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			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, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x07);
			break;
		case GYRO_5HZ_TEMPERATURE_5HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x06);
			break;
		case GYRO_10HZ_TEMPERATURE_10HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x05);
			break;
		case GYRO_20HZ_TEMPERATURE_20HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x04);
			break;
		case GYRO_41HZ_TEMPERATURE_42HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x03);
			break;
		case GYRO_92HZ_TEMPERATURE_98HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x02);
			break;
		case GYRO_176HZ_TEMPERATURE_188HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x01);
			break;
		case GYRO_250HZ_TEMPERATURE_4000HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			icm20602_writeReg(CONFIG, 0x00);
			break;
		case GYRO_3281HZ_TEMPERATURE_4000HZ_RATE_32KHZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xf8;
			regValue = regValue | 0x02;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			break;
		case GYRO_8173HZ_TEMPERATURE_4000HZ:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			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, &regValue);
			regValue = regValue & 0xe7;
			icm20602_writeReg(GYRO_CONFIG, regValue);
			break;
		case GYRO_500DPS_FULLSCALE:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xe7;
			regValue = regValue | 0x08;
			icm20602_writeReg(GYRO_CONFIG, regValue);			
			break;
		case GYRO_1000DPS_FULLSCALE:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			regValue = regValue & 0xe7;
			regValue = regValue | 0x10;
			icm20602_writeReg(GYRO_CONFIG, regValue);			
			break;
		case GYRO_2000DPS_FULLSCALE:
			icm20602_readReg(GYRO_CONFIG, &regValue);
			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
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值