NXP S32K146 FLEXI2C底层驱动+IAM-20680(二)

NXP S32K146 FLEXI2C底层驱动+IAM-20680(一)
在上一篇文章的基础上,写IAM-20680的接口层,与上一篇差不多,os任务中分为初始化与正常运行,下面根据IAM-30680寄存器写一下初始化相关的代码。

  1. REGISTER 117 – WHO AM I
    在这里插入图片描述
    WHO AM I寄存器 只读地址位是0x75,此寄存器用于验证设备的身份。WHOAMI的内容是一个8位的设备ID。该寄存器的默认值为0xA9。这与应用程序处理器在从属I2C控制器上看到的设备的I2C地址不同。IAM-20680的I2C地址是0x68或0x69,这取决于由AD0引脚驱动的值。我们是low即0x68在这里插入图片描述
BOOLEAN hw_IAM_20680_check(void)
{
    i2c_data_t IMU_data;
	INT8U buf[1] = {0};
    IMU_data.regaddr = IMU_Reg_WHO_AM_I;
    IMU_data.len = 1;
    IMU_data.devaddr = IMU_Reg_DEV_ADDR;
    IMU_data.data = buf;
	if(TRUE == hal_flexio_i2c_read(&IMU_data))
	{
		if (IMU_20680_ID==IMU_data.data)
		{
		  return APL_OK;
		}
	}
    return APL_FAIL;
}
  1. REGISTER 107 – POWER MANAGEMENT 1在这里插入图片描述
    传感器的初始化和基本配置
    IAM-20680的基本配置包括以下步骤:
    ①要初始化传感器,请执行复位,并让IAM-20680通过将寄存器PWR_MGMT1(地址0x6B)设置为0x81来选择最佳时钟源(参见第9.27节)该寄存器地址0x6B,可读可写。
    在这里插入图片描述

第7位:设置为1时所有寄存器为缺省值。写1
第6位:设置为1时进入睡眠模式,默认是1,咱给写个0.
第5位:设置为1时开启循环,咱给写个0
第4位:设置为1时开启待机模式,咱给写个0
第3位:设置为1时关闭温度传感器,咱给写个0
CLKSEL[2:0]的默认值为000。需要将CLKSEL[2:0]设置为001,才能实现完整的陀螺仪性能。这个寄存器写0x81。

连续写三个寄存器。106-108

BOOLEAN hw_IAM_20680_Config(void)
{
    i2c_data_t IMU_data;
	INT8U buf[3] = {0};
	
    IMU_data.regaddr = IMU_Reg_Config;//0x6A-0x6C
    IMU_data.len = 3;
    IMU_data.devaddr = IMU_Reg_DEV_ADDR;
    buf[2]=0x80;//REGISTER 108 – POWER MANAGEMENT 2
	buf[1]=0x81;//REGISTER 107 – POWER MANAGEMENT 1
	buf[0]=0x45;//REGISTER 106 – USER CONTROL
    IMU_data.data = buf;
	if(TRUE == hal_flexio_i2c_write(&IMU_data))
	{	
		  return APL_OK;
	}
    return APL_FAIL;
}
  1. REGISTER 25 – SAMPLE RATE DIVIDER
  2. REGISTER 26 – CONFIGURATION
  3. REGISTER 27 – GYROSCOPE CONFIGURATION
  4. REGISTER 28 – ACCELEROMETER CONFIGURATION
  5. REGISTER 29 – ACCELEROMETER CONFIGURATION 2
    在这里插入图片描述
    我愚蠢了兄弟们,官网上边有软件例程,解读一下例程吧,我还一个个小函数敲呢,愚蠢了。
    官网例程eMD-SmartMotion-IAM20680-1.5.0
    在这里插入图片描述
    1.doc文档:Software User Guide 软件指南
    2.EMD-APP:这个应用项目演示如何使用低级驱动程序控制和检索IAM设备的数据。它通过UART接口发送数据,并在主机控制台上显示。该应用程序使用核心库来生成一个可加载的二进制文件。目录包含平台依赖的功能和示例代码,以接口驱动程序配置传感器和流式数据等。
    2.1 ASF 用的ATSAMG55,这个文件夹是系统文件底层的,interrupt之类的。
    2.2 config 底层配置的头文件。
    2.3 IAM-20680 就正常使用IAM的接口
    2.3.1 example -raw
    一个演示原始加速度计和原始陀螺仪数据流的例子。默认配置为低噪声模式,ODR配置为50Hz。
    2.3.2 example -selftest
    一个执行accel和gyro自我测试的例子,并提供PASS/失败结果以及陀螺仪/accel低噪声/低功率偏差的例子。
    2.3.3 example -wom
    一个示例演示了WOM(动态唤醒)特性的配置和使用,以及在接收到WOM中断时完整的FIFO读取。默认配置为低功耗,ODR配置为500Hz。IAM20680HP/IAM20680HT的默认FIFO大小设置为4KB。对于IAM20680HT,本示例还展示了如何启用INT2引脚
    剩下的基本上都是如何实现IAM通讯的接口文件。它是以PIC芯片为基础写的,可以把接口层直接拿过来用,具体每个人的平台不同底层文件不同。

inv_iam20680_init


int inv_iam20680_init(struct inv_iam20680 * dev)
{
	int status = 0;

	/* Reset device */
	status |= inv_iam20680_device_reset(dev);
	/* Wake up device */
	status |= inv_iam20680_wr_pwr_mgmt_1_sleep(dev,IAM20680_PWR_MGMT_1_SLEEP_awake);
	//status |= iam20680_reg_readandwrite(dev,MPUREG_PWR_MGMT_1,BIT_SLEEP_MASK,IAM20680_PWR_MGMT_1_SLEEP_awake,1);
	/* Setup CLKSEL */
	status |= inv_iam20680_wr_pwr_mgmt_1_clksel(CLK_SEL);
	/* Disable Accel and Gyro all axes */
	status |= inv_iam20680_wr_pwr_mgmt_2_accel_stby((uint8_t)IAM20680_PWR_MGMT_2_XA_disable | (uint8_t)IAM20680_PWR_MGMT_2_YA_disable | (uint8_t)IAM20680_PWR_MGMT_2_ZA_disable);
	status |= inv_iam20680_wr_pwr_mgmt_2_gyro_stby((uint8_t)IAM20680_PWR_MGMT_2_XG_disable | (uint8_t)IAM20680_PWR_MGMT_2_YG_disable | (uint8_t)IAM20680_PWR_MGMT_2_ZG_disable);
	/* Set default full scale range */
	status |= inv_iam20680_wr_accel_config_accel_fs_sel((uint8_t)IAM20680_ACCEL_CONFIG_FS_SEL_4g);
	status |= inv_iam20680_wr_gyro_config_fs_sel((uint8_t)IAM20680_GYRO_CONFIG_FS_SEL_2000dps);
	/* Set default bandwidth */
	status |= inv_iam20680_wr_accel_config2_a_dlpf_cfg((uint8_t) IAM20680_ACCEL_CONFIG2_A_DLPF_CFG_420);
	status |= inv_iam20680_wr_config_dlpf_cfg((uint8_t)IAM20680_CONFIG_DLPF_CFG_176);
	/* Set default averaging filter */
	status |= inv_iam20680_wr_accel_config2_dec2_cfg((uint8_t)IAM20680_ACCEL_CONFIG2_DEC2_CFG_4x);
	status |= inv_iam20680_wr_lp_mode_cfg_g_avgcfg((uint8_t)IAM20680_LP_MODE_CFG_G_AVGCFG_1x);
	/* Initial sampling rate to 100Hz*/
	status |= inv_iam20680_wr_smplrt_div((uint8_t)SAMPLE_RATE_DIVIDER);
	/* make sure FIFO is disabled */
	status |= inv_iam20680_wr_user_ctrl_fifo_en((uint8_t)IAM20680_USER_CTRL_FIFO_EN_disable);
	status |= inv_iam20680_wr_fifo_en_gyro_fifo_en((uint8_t)IAM20680_FIFO_EN_GYRO_FIFO_EN_disable);
	status |= inv_iam20680_wr_fifo_en_accel_fifo_en((uint8_t)IAM20680_FIFO_EN_ACCEL_FIFO_EN_disable);
   	status |= inv_iam20680_wr_fifo_en_temp_fifo_en((uint8_t)IAM20680_FIFO_EN_TEMP_FIFO_EN_disable);
	/* Configure FIFO:
	  - FIFO stream mode i.e over write the data when the FIFO overflows
	*/
	status |= inv_iam20680_wr_config_fifo_mode((uint8_t)IAM20680_CONFIG_FIFO_MODE_STREAM);
	/* Enable Data Ready Interrupt */
	status |= inv_iam20680_wr_int_enable_data_rdy_int_en((uint8_t)IAM20680_INT_ENABLE_DATA_RDY_INT_EN_enable);
	return status;
}

SetupInvDevice

int SetupInvDevice(BOOLEAN (*read_reg)(i2c_data_t *data),BOOLEAN (*write_reg)(i2c_data_t *data))
{
	int rc = 0;
	uint8_t who_am_i;
	struct hal_iam20680_i2c iam20680_config;
	iam20680_config.read_reg  = (*read_reg);
	iam20680_config.write_reg = (*write_reg);
	iam20680_config.max_read  = 64;
	iam20680_config.max_write = 64; 
	memset(&icm_device, 0, sizeof(icm_device));
	icm_device.config = iam20680_config;
	rc = hw_IAM_20680_check();
	if(rc!= TRUE )
		rc = hw_IAM_20680_check();
	if(rc != TRUE)
		return rc;
	rc = inv_iam20680_init(&icm_device);
	return rc;
}

iam20680_init
实现了IAM模块的初始化


int iam20680_init(void)
{
	SetupInvDevice(hal_flexio_i2c_read,hal_flexio_i2c_write);
	dev_config.enable_accel = (uint8_t)ENABLE_ACCEL;
	dev_config.enable_gyro = (uint8_t)ENABLE_GYRO;
	dev_config.set_low_noise_mode = (uint8_t)LOW_NOISE_MODE;
	dev_config.acc_fsr_g = FSR_ACC_G;
	dev_config.gyr_fsr_dps = FSR_GYR_DPS;
	dev_config.odr_us = ODR_US;
	ConfigureInvDevice(&dev_config);
	eGyro_State=GYRO_WORKING;
}

iam20680_GetDataFromFIFO
实现了从FIFO中读取数据


int iam20680_GetDataFromFIFO(inv_dev_config_t* device_config)
{
	int rc = 0;
	uint8_t int_status = 0;
	int16_t raw_acc[3], raw_gyro[3];
	uint16_t packet_count = 0, packet_count_i = 0;
	uint16_t packet_size = 0;
	uint32_t timestamp = 0;
	if(device_config->enable_accel) 
		packet_size += ACCEL_DATA_SIZE;
	if(device_config->enable_gyro)
		packet_size += GYRO_DATA_SIZE;
	rc = inv_iam20680_rd_int_status( &int_status);
	if(!rc)
		return rc;
	if(int_status & BIT_DATA_RDY_INT_MASK) 
	{
		uint8_t fifo_count[2];
		inv_iam20680_rd_fifo_count( fifo_count);
		packet_count = (fifo_count[0] << 8) | fifo_count[1];
		packet_count /= packet_size; 	/* FIFO byte mode */
		if(int_status & BIT_FIFO_OVERFLOW_MASK) 
		{
			inv_iam20680_wr_user_ctrl_fifo_rst();
			//clear_irq();在这里清中断吗?!!!!
			return false;
		}
		else if(packet_count>0) 
		{
			for (packet_count_i=0; packet_count_i<packet_count; packet_count_i++) 
			{		
				uint8_t data[ACCEL_DATA_SIZE + GYRO_DATA_SIZE];
				if(!(rc = inv_iam20680_rd_fifo(packet_size, data))) //读取失败
				{
					inv_iam20680_wr_user_ctrl_fifo_rst();
				}
				//timestamp = timer_get_irq_timestamp_us(); 读时间戳不读不行?
				if(device_config->enable_accel && device_config->enable_gyro) {
                    raw_acc[0] = (data[0] << 8) | data[1];
					raw_acc[1] = (data[2] << 8) | data[3];
					raw_acc[2] = (data[4] << 8) | data[5];
					raw_gyro[0] = (data[6] << 8) | data[7];
					raw_gyro[1] = (data[8] << 8) | data[9];
					raw_gyro[2] = (data[10] << 8)| data[11];
				}
				else if(device_config->enable_accel && !device_config->enable_gyro) {
					raw_acc[0] = (data[0] << 8) | data[1];
					raw_acc[1] = (data[2] << 8) | data[3];
					raw_acc[2] = (data[4] << 8) | data[5];
				}
				else if(!device_config->enable_accel && device_config->enable_gyro) {
					raw_gyro[0] = (data[0] << 8) | data[1];
					raw_gyro[1] = (data[2] << 8) | data[3];
					raw_gyro[2] = (data[4] << 8) | data[5];
				} 
			} 
		} 
	} 
	return TRUE;
}

以上代码未经验证,到目前为主是以S32K146为平台实现了FIFO读取IMU的数据,下一步则是使用卡尔曼滤波及MATLAB仿真IMU的姿态!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值