赞
踩
#ifndef _BSP_ICM20608_H #define _BSP_ICM20608_H /*************************************************************** 文件名 : bsp_icm20608.h 描述 : ICM20608驱动文件。 ***************************************************************/ #include "imx6ul.h" #include "bsp_gpio.h" /* 宏定义 */ #define ICM20608_CSN(n) (n ? gpio_pinwrite(GPIO1, 20, 1) : gpio_pinwrite(GPIO1, 20, 0)) /* SPI片选信号 */ //定义ID值,用于确认是否匹配,根据寄存器手册定义 #define ICM20608G_ID 0XAF /* ID值 */ #define ICM20608D_ID 0XAE /* ID值 */ /* ICM20608寄存器 *复位后所有寄存器地址都为0,除了 *Register 107(0X6B) Power Management 1 = 0x40 *Register 117(0X75) WHO_AM_I = 0xAF或0xAE */ /* 陀螺仪和加速度自测(出产时设置,用于与用户的自检输出值比较) */ // 陀螺仪 #define ICM20_SELF_TEST_X_GYRO 0x00 #define ICM20_SELF_TEST_Y_GYRO 0x01 #define ICM20_SELF_TEST_Z_GYRO 0x02 // 加速度 #define ICM20_SELF_TEST_X_ACCEL 0x0D #define ICM20_SELF_TEST_Y_ACCEL 0x0E #define ICM20_SELF_TEST_Z_ACCEL 0x0F /* 陀螺仪静态偏移 */ #define ICM20_XG_OFFS_USRH 0x13 #define ICM20_XG_OFFS_USRL 0x14 #define ICM20_YG_OFFS_USRH 0x15 #define ICM20_YG_OFFS_USRL 0x16 #define ICM20_ZG_OFFS_USRH 0x17 #define ICM20_ZG_OFFS_USRL 0x18 #define ICM20_SMPLRT_DIV 0x19 #define ICM20_CONFIG 0x1A #define ICM20_GYRO_CONFIG 0x1B #define ICM20_ACCEL_CONFIG 0x1C #define ICM20_ACCEL_CONFIG2 0x1D #define ICM20_LP_MODE_CFG 0x1E #define ICM20_ACCEL_WOM_THR 0x1F #define ICM20_FIFO_EN 0x23 #define ICM20_FSYNC_INT 0x36 #define ICM20_INT_PIN_CFG 0x37 #define ICM20_INT_ENABLE 0x38 #define ICM20_INT_STATUS 0x3A /* 加速度输出 */ #define ICM20_ACCEL_XOUT_H 0x3B #define ICM20_ACCEL_XOUT_L 0x3C #define ICM20_ACCEL_YOUT_H 0x3D #define ICM20_ACCEL_YOUT_L 0x3E #define ICM20_ACCEL_ZOUT_H 0x3F #define ICM20_ACCEL_ZOUT_L 0x40 /* 温度输出 */ #define ICM20_TEMP_OUT_H 0x41 #define ICM20_TEMP_OUT_L 0x42 /* 陀螺仪输出 */ #define ICM20_GYRO_XOUT_H 0x43 #define ICM20_GYRO_XOUT_L 0x44 #define ICM20_GYRO_YOUT_H 0x45 #define ICM20_GYRO_YOUT_L 0x46 #define ICM20_GYRO_ZOUT_H 0x47 #define ICM20_GYRO_ZOUT_L 0x48 #define ICM20_SIGNAL_PATH_RESET 0x68 #define ICM20_ACCEL_INTEL_CTRL 0x69 #define ICM20_USER_CTRL 0x6A #define ICM20_PWR_MGMT_1 0x6B #define ICM20_PWR_MGMT_2 0x6C #define ICM20_FIFO_COUNTH 0x72 #define ICM20_FIFO_COUNTL 0x73 #define ICM20_FIFO_R_W 0x74 #define ICM20_WHO_AM_I 0x75 /* 加速度静态偏移 */ #define ICM20_XA_OFFSET_H 0x77 #define ICM20_XA_OFFSET_L 0x78 #define ICM20_YA_OFFSET_H 0x7A #define ICM20_YA_OFFSET_L 0x7B #define ICM20_ZA_OFFSET_H 0x7D #define ICM20_ZA_OFFSET_L 0x7E /* * ICM20608结构体 */ struct icm20608_dev_struc { signed int gyro_x_adc; /* 陀螺仪X轴原始值 */ signed int gyro_y_adc; /* 陀螺仪Y轴原始值 */ signed int gyro_z_adc; /* 陀螺仪Z轴原始值 */ signed int accel_x_adc; /* 加速度计X轴原始值 */ signed int accel_y_adc; /* 加速度计Y轴原始值 */ signed int accel_z_adc; /* 加速度计Z轴原始值 */ signed int temp_adc; /* 温度原始值 */ /* 下面是计算得到的实际值,扩大100倍 */ signed int gyro_x_act; /* 陀螺仪X轴实际值 */ signed int gyro_y_act; /* 陀螺仪Y轴实际值 */ signed int gyro_z_act; /* 陀螺仪Z轴实际值 */ signed int accel_x_act; /* 加速度计X轴实际值 */ signed int accel_y_act; /* 加速度计Y轴实际值 */ signed int accel_z_act; /* 加速度计Z轴实际值 */ signed int temp_act; /* 温度实际值 */ }; struct icm20608_dev_struc icm20608_dev; /* icm20608设备 */ /* 函数声明 */ unsigned char icm20608_init(void); void icm20608_write_reg(unsigned char reg, unsigned char value); unsigned char icm20608_read_reg(unsigned char reg); void icm20608_read_len(unsigned char reg, unsigned char *buf, unsigned char len); void icm20608_getdata(void); #endif
#include "bsp_icm20608.h"
#include "bsp_delay.h"
#include "bsp_spi.h"
#include "stdio.h"
struct icm20608_dev_struc icm20608_dev; /* icm20608设备 */
/* * @description : 初始化ICM20608 * @param : 无 * @return : 0 初始化成功,其他值 初始化失败 */ unsigned char icm20608_init(void) { unsigned char regvalue; gpio_pin_config_t cs_config; /* 1、ESPI3 IO初始化 ALPHA开发板上通过ECSPI13接口连接了一个六轴传感器 * ECSPI3_SCLK -> UART2_RXD * ECSPI3_MISO -> UART2_RTS * ECSPI3_MOSI -> UART2_CTS * ECSPI3_SSO -> UART2_TXD */ IOMUXC_SetPinMux(IOMUXC_UART2_RX_DATA_ECSPI3_SCLK, 0); IOMUXC_SetPinMux(IOMUXC_UART2_CTS_B_ECSPI3_MOSI, 0); IOMUXC_SetPinMux(IOMUXC_UART2_RTS_B_ECSPI3_MISO, 0); /* 配置SPI SCLK MISO MOSI IO属性 *bit 16: 0 HYS关闭 *bit [15:14]: 00 默认100K下拉 *bit [13]: 0 keeper功能 *bit [12]: 1 pull/keeper使能 *bit [11]: 0 关闭开路输出 *bit [7:6]: 10 速度100Mhz *bit [5:3]: 110 驱动能力为R0/6 *bit [0]: 1 高转换率 */ IOMUXC_SetPinConfig(IOMUXC_UART2_RX_DATA_ECSPI3_SCLK, 0x10B1); IOMUXC_SetPinConfig(IOMUXC_UART2_CTS_B_ECSPI3_MOSI, 0x10B1); IOMUXC_SetPinConfig(IOMUXC_UART2_RTS_B_ECSPI3_MISO, 0x10B1); /*初始化片选引脚*/ IOMUXC_SetPinMux(IOMUXC_UART2_TX_DATA_GPIO1_IO20, 0); IOMUXC_SetPinConfig(IOMUXC_UART2_TX_DATA_GPIO1_IO20, 0X10B0); cs_config.direction = kGPIO_DigitalOutput; cs_config.outputLogic = 0; gpio_init(GPIO1, 20, &cs_config); /* 2、初始化SPI */ spi_init(ECSPI3); /* 3、初始化IMC20608 */ //icm20608默认在睡眠模式下,读就出问题了,必须先复位,复位以后,关闭睡眠模式 icm20608_write_reg(ICM20_PWR_MGMT_1, 0x80); /* 复位,复位后为0x40,睡眠模式 */ delayms(50); icm20608_write_reg(ICM20_PWR_MGMT_1, 0x01); /* 关闭睡眠,自动选择时钟 */ delayms(50); /* 4、ID匹配 */ regvalue = icm20608_read_reg(ICM20_WHO_AM_I); printf("icm20608 id = %#X\r\n", regvalue); if(regvalue != ICM20608G_ID && regvalue != ICM20608D_ID) return 1; /* 3、IMC20608初始化代码,查看寄存器手册 */ icm20608_write_reg(ICM20_SMPLRT_DIV, 0x00); /* 输出速率是内部采样率 */ icm20608_write_reg(ICM20_GYRO_CONFIG, 0x18); /* 陀螺仪±2000dps量程 */ icm20608_write_reg(ICM20_ACCEL_CONFIG, 0x18); /* 加速度计±16G量程 */ icm20608_write_reg(ICM20_CONFIG, 0x04); /* 陀螺仪低通滤波BW=20Hz */ icm20608_write_reg(ICM20_ACCEL_CONFIG2, 0x04); /* 加速度计低通滤波BW=21.2Hz */ icm20608_write_reg(ICM20_PWR_MGMT_2, 0x00); /* 打开加速度计和陀螺仪所有轴 */ icm20608_write_reg(ICM20_LP_MODE_CFG, 0x00); /* 关闭低功耗 */ icm20608_write_reg(ICM20_FIFO_EN, 0x00); /* 关闭FIFO */ return 0; }
/* * @description : 读取ICM20608寄存器值,SPI接口写数据 * @param - reg : 要读取的寄存器地址 * @return : 读取到的寄存器值 */ unsigned char icm20608_read_reg(unsigned char reg) { unsigned char reg_val; /* ICM20608在使用SPI接口的时候寄存器地址 * 只有低7位有效,寄存器地址最高位是读/写标志位 * 读的时候要为1,写的时候要为0。 */ reg |= 0x80; //查看数据手册 ICM20608_CSN(0); /* 片选拉低,选中芯片,使能SPI传输*/ spich0_readwrite_byte(ECSPI3, reg); /* 发送寄存器地址,使用SPI接口*/ reg_val = spich0_readwrite_byte(ECSPI3, 0XFF); /* 读取寄存器的值(从机返回的数据) ,0XFF无效值,使能时钟*/ ICM20608_CSN(1); /*片选拉高,禁止SPI传输 */ return(reg_val); /* 返回读取到的寄存器值 */ }
/* * @description : 写ICM20608指定寄存器,SPI接口读数据 * @param - reg : 要读取的寄存器地址 * @param - value: 要写入的值 * @return : 无 */ void icm20608_write_reg(unsigned char reg, unsigned char value) { /* ICM20608在使用SPI接口的时候寄存器地址 * 只有低7位有效,寄存器地址最高位是读/写标志位 * 读的时候要为1,写的时候要为0。 */ reg &= ~0X80;//根据数据手册编写,地址的bit7置0,表示写数据 ICM20608_CSN(0); /* 片选拉低,使能SPI传输 */ spich0_readwrite_byte(ECSPI3, reg); /* 发送寄存器地址 */ spich0_readwrite_byte(ECSPI3, value); /* 发送要写入的值 */ ICM20608_CSN(1); /* 片选拉高,禁止SPI传输 */ }
/* * @description : 读取ICM20608连续多个寄存器 * @param - reg : 要读取的寄存器地址 * @return : 读取到的寄存器值 */ void icm20608_read_len(unsigned char reg, unsigned char *buf, unsigned char len) { unsigned char i; /* ICM20608在使用SPI接口的时候寄存器地址,只有低7位有效, * 寄存器地址最高位是读/写标志位读的时候要为1,写的时候要为0。 */ reg |= 0x80; ICM20608_CSN(0); /* 使能SPI传输 */ spich0_readwrite_byte(ECSPI3, reg); /* 发送寄存器地址 */ for(i = 0; i < len; i++) /* 顺序读取寄存器的值 */ { buf[i] = spich0_readwrite_byte(ECSPI3, 0XFF); } ICM20608_CSN(1); /* 片选拉高,禁止SPI传输 */ }
/* * @description : 读取ICM20608的加速度、陀螺仪和温度原始值 * @param : 无 * @return : 无 */ void icm20608_getdata(void) { //定义陀螺仪、加速度计分辨率变量 float gyroscale; unsigned short accescale; unsigned char data[14]; icm20608_read_len(ICM20_ACCEL_XOUT_H, data, 14);//起始地址、保存数据单元、长度 gyroscale = icm20608_gyro_scaleget(); accescale = icm20608_accel_scaleget(); // ADC传感器数据 icm20608_dev.accel_x_adc = (signed short)((data[0] << 8) | data[1]); icm20608_dev.accel_y_adc = (signed short)((data[2] << 8) | data[3]); icm20608_dev.accel_z_adc = (signed short)((data[4] << 8) | data[5]); icm20608_dev.temp_adc = (signed short)((data[6] << 8) | data[7]); icm20608_dev.gyro_x_adc = (signed short)((data[8] << 8) | data[9]); icm20608_dev.gyro_y_adc = (signed short)((data[10] << 8) | data[11]); icm20608_dev.gyro_z_adc = (signed short)((data[12] << 8) | data[13]); // 计算实际值(实际数据扩大100倍,0.01扩大100=1) // 原因:串口不支持浮点数输出、扩大100倍,相当于将小数点后两位变为整型。 icm20608_dev.gyro_x_act = ((float)(icm20608_dev.gyro_x_adc) / gyroscale) * 100; icm20608_dev.gyro_y_act = ((float)(icm20608_dev.gyro_y_adc) / gyroscale) * 100; icm20608_dev.gyro_z_act = ((float)(icm20608_dev.gyro_z_adc) / gyroscale) * 100; icm20608_dev.accel_x_act = ((float)(icm20608_dev.accel_x_adc) / accescale) * 100; icm20608_dev.accel_y_act = ((float)(icm20608_dev.accel_y_adc) / accescale) * 100; icm20608_dev.accel_z_act = ((float)(icm20608_dev.accel_z_adc) / accescale) * 100; //用到温度的计算表达式:寄存器手册,搜索TEMP_degC icm20608_dev.temp_act = (((float)(icm20608_dev.temp_adc) - 25 ) / 326.8 + 25) * 100; }
/* * @description : 获取陀螺仪的分辨率 * @param : 无 * @return : 获取到的分辨率 */ float icm20608_gyro_scaleget(void) { unsigned char data; float gyroscale; data = (icm20608_read_reg(ICM20_GYRO_CONFIG) >> 3) & 0X3; switch(data) { case 0: gyroscale = 131; break; case 1: gyroscale = 65.5; break; case 2: gyroscale = 32.8; break; case 3: gyroscale = 16.4; break; } return gyroscale; } /* * @description : 获取加速度计的分辨率 * @param : 无 * @return : 获取到的分辨率 */ unsigned short icm20608_accel_scaleget(void) { unsigned char data; unsigned short accelscale; data = (icm20608_read_reg(ICM20_ACCEL_CONFIG) >> 3) & 0X3; switch(data) { case 0: accelscale = 16384; break; case 1: accelscale = 8192; break; case 2: accelscale = 4096; break; case 3: accelscale = 2048; break; } return accelscale; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。