linux spidev 读取IMU数据
icm42xxx.h
#ifndef __IMU4265XXX_DEFS_H__
#define __IMU4265XXX_DEFS_H__
#include <stdint.h>
/* List whoami values for all ixm42xxx variants*/
#define IIM42652_WHOAMI 0x6F
#define IIM42653_WHOAMI 0x56
#define IIM42686_WHOAMI 0x44
#define IIM42351_WHOAMI 0x6C
#define SPI_W 0x7f//spi write bit7 = 0
#define SPI_R 0x80//spi read bit7 = 1
/* ----------------------------------------------------------------------------
* Device Register map
*
* Next macros defines address for all ixm42xxx registers as listed by device
* datasheet.
* Macros name is MPUREG_<REGISTER_NAME> with REGISTER_NAME being the name of
* the corresponding register in datasheet.
* Note that macro name is MPUREG_<REGISTER_NAME>_Bx with x being the bank
* number for registers that are in bank 1 and 2 (suffix is ommitted for
* bank0 registers)
* ---------------------------------------------------------------------------- */
/* Bank 0 */
#define MPUREG_DEVICE_CONFIG 0x11
#define MPUREG_CHIP_CONFIG MPUREG_DEVICE_CONFIG // Retro-compatibility
#define MPUREG_DRIVE_CONFIG 0x13
#define MPUREG_INT_CONFIG 0x14
#define MPUREG_FIFO_CONFIG 0x16
#define MPUREG_TEMP_DATA1_UI 0x1D
#define MPUREG_ACCEL_DATA_X1_UI 0x1F
#define MPUREG_GYRO_DATA_X1_UI 0x25
#define MPUREG_TMST_FSYNCH 0x2B
#define MPUREG_TMST_FSYNCL 0x2C
#define MPUREG_INT_STATUS 0x2D
#define MPUREG_FIFO_COUNTH 0x2E
#define MPUREG_FIFO_BYTE_COUNT1 MPUREG_FIFO_COUNTH // Retro-compatibility
#define MPUREG_FIFO_COUNTL 0x2F
#define MPUREG_FIFO_BYTE_COUNT2 MPUREG_FIFO_COUNTL // Retro-compatibility
#define MPUREG_FIFO_DATA 0x30
#define MPUREG_APEX_DATA0 0x31
#define MPUREG_APEX_DATA1 0x32
#define MPUREG_APEX_DATA2 0x33
#define MPUREG_APEX_DATA3 0x34
#define MPUREG_APEX_DATA4 0x35
#define MPUREG_APEX_DATA5 0x36
#define MPUREG_INT_STATUS2 0x37
#define MPUREG_INT_STATUS3 0x38
#define MPUREG_SIGNAL_PATH_RESET 0x4B
#define MPUREG_INTF_CONFIG0 0x4C
#define MPUREG_INTF_CONFIG1 0x4D
#define MPUREG_PWR_MGMT_0 0x4E
#define MPUREG_GYRO_CONFIG0 0x4F
#define MPUREG_ACCEL_CONFIG0 0x50
#define MPUREG_GYRO_CONFIG1 0x51
#define MPUREG_GYRO_ACCEL_CONFIG0 0x52
#define MPUREG_ACCEL_CONFIG1 0x53
#define MPUREG_TMST_CONFIG 0x54
#define MPUREG_APEX_CONFIG0 0x56
#define MPUREG_SMD_CONFIG 0x57
#define MPUREG_FIFO_CONFIG1 0x5F
#define MPUREG_FIFO_CONFIG2 0x60
#define MPUREG_FIFO_CONFIG3 0x61
#define MPUREG_FSYNC_CONFIG 0x62
#define MPUREG_INT_CONFIG0 0x63
#define MPUREG_INT_CONFIG1 0x64
#define MPUREG_INT_SOURCE0 0x65
#define MPUREG_INT_SOURCE1 0x66
#define MPUREG_INT_SOURCE3 0x68
#define MPUREG_INT_SOURCE4 0x69
#define MPUREG_FIFO_LOST_PKT0 0x6C
#define MPUREG_FIFO_LOST_PKT1 0x6D
#define MPUREG_SELF_TEST_CONFIG 0x70
#define MPUREG_WHO_AM_I 0x75
#define MPUREG_REG_BANK_SEL 0x76
/* Bank 1 */
#define MPUREG_SENSOR_CONFIG 0x03
#define MPUREG_GYRO_CONFIG_STATIC2_B1 0x0B
#define MPUREG_GYRO_CONFIG_STATIC3_B1 0x0C
#define MPUREG_GYRO_CONFIG_STATIC4_B1 0x0D
#define MPUREG_GYRO_CONFIG_STATIC5_B1 0x0E
#define MPUREG_GYRO_CONFIG_STATIC6_B1 0x0F
#define MPUREG_GYRO_CONFIG_STATIC7_B1 0x10
#define MPUREG_GYRO_CONFIG_STATIC8_B1 0x11
#define MPUREG_GYRO_CONFIG_STATIC9_B1 0x12
#define MPUREG_GYRO_CONFIG_STATIC10_B1 0x13
#define MPUREG_XG_ST_DATA_B1 0x5F
#define MPUREG_YG_ST_DATA_B1 0x60
#define MPUREG_ZG_ST_DATA_B1 0x61
#define MPUREG_TMST_VAL0_B1 0x62
#define MPUREG_TMST_VAL1_B1 0x63
#define MPUREG_TMST_VAL2_B1 0x64
#define MPUREG_INTF_CONFIG4_B1 0x7A
#define MPUREG_INTF_CONFIG5_B1 0x7B
#define MPUREG_INTF_CONFIG6_B1 0x7C
/* Bank 2 */
#define MPUREG_ACCEL_CONFIG_STATIC2_B2 0x03
#define MPUREG_ACCEL_CONFIG_STATIC3_B2 0x04
#define MPUREG_ACCEL_CONFIG_STATIC4_B2 0x05
#define MPUREG_XA_ST_DATA_B2 0x3B
#define MPUREG_YA_ST_DATA_B2 0x3C
#define MPUREG_ZA_ST_DATA_B2 0x3D
/* Bank 3 */
#define MPUREG_PU_PD_CONFIG1_B3 0x06
#define MPUREG_PU_PD_CONFIG2_B3 0x0E
/* Bank 4 */
#define MPUREG_FDR_CONFIG_B4 0x09
#define MPUREG_APEX_CONFIG1_B4 0x40
#define MPUREG_APEX_CONFIG2_B4 0x41
#define MPUREG_APEX_CONFIG3_B4 0x42
#define MPUREG_APEX_CONFIG4_B4 0x43
#define MPUREG_APEX_CONFIG5_B4 0x44
#define MPUREG_APEX_CONFIG6_B4 0x45
#define MPUREG_APEX_CONFIG7_B4 0x46
#define MPUREG_APEX_CONFIG8_B4 0x47
#define MPUREG_APEX_CONFIG9_B4 0x48
#define MPUREG_APEX_CONFIG10_B4 0x49
#define MPUREG_ACCEL_WOM_X_THR_B4 0x4A
#define MPUREG_ACCEL_WOM_Y_THR_B4 0x4B
#define MPUREG_ACCEL_WOM_Z_THR_B4 0x4C
#define MPUREG_INT_SOURCE6_B4 0x4D
#define MPUREG_INT_SOURCE7_B4 0x4E
#define MPUREG_INT_SOURCE8_B4 0x4F
#define MPUREG_INT_SOURCE9_B4 0x50
#define MPUREG_INT_SOURCE10_B4 0x51
#define MPUREG_OFFSET_USER_0_B4 0x77
#define MPUREG_OFFSET_USER_1_B4 0x78
#define MPUREG_OFFSET_USER_2_B4 0x79
#define MPUREG_OFFSET_USER_3_B4 0x7A
#define MPUREG_OFFSET_USER_4_B4 0x7B
#define MPUREG_OFFSET_USER_5_B4 0x7C
#define MPUREG_OFFSET_USER_6_B4 0x7D
#define MPUREG_OFFSET_USER_7_B4 0x7E
#define MPUREG_OFFSET_USER_8_B4 0x7F
typedef struct {
uint8_t init;
uint64_t utc;
floatACCEL_X_RAW;
floatACCEL_Y_RAW;
floatACCEL_Z_RAW;
floatGYRO_X_RAW;
floatGYRO_Y_RAW;
floatGYRO_Z_RAW;
int16_tTEMP_RAW;
} __attribute__((packed)) IIM42xxx_SENSOR_t;
extern IIM42xxx_SENSOR_t _iim42653;
extern uint8_t USING_IMU_42XXX;
/* ----------------------------------------------------------------------------
* Device registers description
*
* Next section defines some of the registers bitfield and declare corresponding
* accessors.
* Note that descriptors and accessors are not provided for all the registers
* but only for the most useful ones.
* For all details on registers and bitfields functionalities please refer to
* the device datasheet.
* ---------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
* register bank 0
* ---------------------------------------------------------------------------- */
enum
{
kDEVICE_CONFIG_SPI_MODE_1_2 = (0x1 << 4),
kDEVICE_CONFIG_SPI_MODE_0_3 = (0x0 << 4),
kDEVICE_CONFIG_SOFT_RESET_CONFIG = (0x1 << 0),
};
enum
{
kDRIVE_CONFIG_I2C_SLEW_RATE_20_60ns = 0x00,
kDRIVE_CONFIG_I2C_SLEW_RATE_12_36ns = 0x08,
kDRIVE_CONFIG_I2C_SLEW_RATE_6_18ns= 0x10,
kDRIVE_CONFIG_I2C_SLEW_RATE_4_12ns= 0x18,
kDRIVE_CONFIG_I2C_SLEW_RATE_2_6ns= 0x20,
kDRIVE_CONFIG_I2C_SLEW_RATE_2ns= 0x28,
} ;
enum
{
kINT_CONFIG_INT1_POLARITY = (0x1 << 0),
kINT_CONFIG_INT1_DRIVE_CIRCUIT = (0x1 << 1),
kINT_CONFIG_INT1_MODE= (0x1 << 2),
kINT_CONFIG_INT2_POLARITY= (0x1 << 3),
kINT_CONFIG_INT2_DRIVE_CIRCUIT= (0x1 << 4),
kINT_CONFIG_INT2_MODE= (0x1 << 5),
} ;
enum
{
kFIFO_CONFIG_FIFO_MODE_BYPASS = (0x0 << 5),
kFIFO_CONFIG_FIFO_MODE_STREAM_TO_FIFO = (0x1 << 5),
kFIFO_CONFIG_FIFO_MODE_STOP_ON_FULL = (0x2 << 5),
} ;
enum
{
kINT_STATUS_AGC_RDY_INT = (0x1 << 0),
kINT_STATUS_FIFO_FULL_INT = (0x1 << 1),
kINT_STATUS_FIFO_THS_INT = (0x1 << 2),
kINT_STATUS_DATA_RDY_INT = (0x1 << 3),
kINT_STATUS_RESET_DONE_INT = (0x1 << 4),
kINT_STATUS_PLL_RDY_INT = (0x1 << 5),
kINT_STATUS_UI_FSYNC_INT = (0x1 << 6),
} ;
enum
{
kINT_STATUS2_WOM_X_INT = (0x1 << 0),
kINT_STATUS2_WOM_Y_INT = (0x1 << 1),
kINT_STATUS2_WOM_Z_INT = (0x1 << 2),
kINT_STATUS2_SMD_INT = (0x1 << 3),
} ;
enum
{
kINT_STATUS3_TAP_DET_INT = (0x1 << 0),
kINT_STATUS3_FF_DET_INT = (0x1 << 1),
kINT_STATUS3_TILT_DET_INT = (0x1 << 3),
kINT_STATUS_STEP_CNT_OVF_INT = (0x1 << 4),
kINT_STATUS_STEP_DET_INT = (0x1 << 5),
};
enum
{
kINTF_CONFIG1_CLKSEL_RC = (0x0 << 0),
kINTF_CONFIG1_CLKSEL_AUTO = (0x1 << 0),
kINTF_CONFIG1_CLKSEL_DISABLE = (0x3 << 0),
kINTF_CONFIG1_RTC_MODE = (0x1 << 2),
kINTF_CONFIG1_ACCEL_LP_CLK_SEL_OC = (0x0 << 3),
kINTF_CONFIG1_ACCEL_LP_CLK_SEL_RC = (0x1 << 3),
};
enum
{
kPWR_MGMT0_ACCEL_MODE_OFF = (0x0 << 0),
kPWR_MGMT0_ACCEL_MODE_LP = (0x2 << 0),
kPWR_MGMT0_ACCEL_MODE_LN = (0x3 << 0),
kPWR_MGMT0_GYRO_MODE_OFF = (0x0 << 2),
kPWR_MGMT0_GYRO_MODE_LP = (0x2 << 2),
kPWR_MGMT0_GYRO_MODE_LN = (0x3 << 2),
kPWR_MGMT0_IDLE = (0x1 << 4),
kPWR_MGMT0_TEMP_DIS = (0x1 << 5),
};
enum
{
kGYRO_CONFIG0_GYRO_ODR_32KHZ = (0x1 << 0),
kGYRO_CONFIG0_GYRO_ODR_16KHZ= (0x2 << 0),
kGYRO_CONFIG0_GYRO_ODR_8KHZ = (0x3 << 0),
kGYRO_CONFIG0_GYRO_ODR_4KHZ= (0x4 << 0),
kGYRO_CONFIG0_GYRO_ODR_2KHZ= (0x5 << 0),
kGYRO_CONFIG0_GYRO_ODR_1KHZ= (0x6 << 0),
kGYRO_CONFIG0_GYRO_ODR_200HZ= (0x7 << 0),
kGYRO_CONFIG0_GYRO_ODR_100HZ= (0x8 << 0),
kGYRO_CONFIG0_GYRO_ODR_50HZ= (0x9 << 0),
kGYRO_CONFIG0_GYRO_ODR_12_5HZ = (0xA << 0),
kGYRO_CONFIG0_GYRO_ODR_500KHZ= (0xF << 0),
kGYRO_CONFIG0_GYRO_FS_SEL_2000dps = (0x0 << 5),
kGYRO_CONFIG0_GYRO_FS_SEL_1000dps = (0x1 << 5),
kGYRO_CONFIG0_GYRO_FS_SEL_500dps = (0x2 << 5),
kGYRO_CONFIG0_GYRO_FS_SEL_250dps = (0x3 << 5),
kGYRO_CONFIG0_GYRO_FS_SEL_125dps = (0x4 << 5),
kGYRO_CONFIG0_GYRO_FS_SEL_62_5dps= (0x5 << 5),
kGYRO_CONFIG0_GYRO_FS_SEL_31_25dps= (0x6 << 5),
kGYRO_CONFIG0_GYRO_FS_SEL_12_625dps= (0x7 << 5),
};
enum
{
kACCEL_CONFIG0_ACCEL_ODR_32KHZ = (0x1 << 0),
kACCEL_CONFIG0_ACCEL_ODR_16KHZ= (0x2 << 0),
kACCEL_CONFIG0_ACCEL_ODR_8KHZ = (0x3 << 0),
kACCEL_CONFIG0_ACCEL_ODR_4KHZ= (0x4 << 0),
kACCEL_CONFIG0_ACCEL_ODR_2KHZ= (0x5 << 0),
kACCEL_CONFIG0_ACCEL_ODR_1KHZ= (0x6 << 0),
kACCEL_CONFIG0_ACCEL_ODR_200HZ= (0x7 << 0),
kACCEL_CONFIG0_ACCEL_ODR_100HZ= (0x8 << 0),
kACCEL_CONFIG0_ACCEL_ODR_50HZ= (0x9 << 0),
kACCEL_CONFIG0_ACCEL_ODR_25HZ= (0xA << 0),
kACCEL_CONFIG0_ACCEL_ODR_12_5HZ = (0xB << 0),
kACCEL_CONFIG0_ACCEL_ODR_6_25HZ = (0xC << 0),
kACCEL_CONFIG0_ACCEL_ODR_3_125HZ = (0xD << 0),
kACCEL_CONFIG0_ACCEL_ODR_1_5625HZ = (0xE << 0),
kACCEL_CONFIG0_ACCEL_ODR_500KHZ= (0xF << 0),
kACCEL_CONFIG0_ACCEL_FS_SEL_16g = (0x0 << 5),
kACCEL_CONFIG0_ACCEL_FS_SEL_8g = (0x1 << 5),
kACCEL_CONFIG0_ACCEL_FS_SEL_4g = (0x2 << 5),
kACCEL_CONFIG0_ACCEL_FS_SEL_2g= (0x3 << 5),
};
enum
{
kGYRO_CONFIG1_DEC2_M2_ORD_3rd = (0x2 << 0),
kGYRO_CONFIG1_UI_FILT_ORD_1st= (0x0 << 2),
kGYRO_CONFIG1_UI_FILT_ORD_2st = (0x1 << 2),
kGYRO_CONFIG_UI_FILT_ORD_3st= (0x2 << 2),
kGYRO_CONFIG1_TEMP_FILT_BW_4000hz= (0x0 << 5),
kGYRO_CONFIG1_TEMP_FILT_BW_170hz= (0x1 << 5),
kGYRO_CONFIG1_TEMP_FILT_BW_82hz= (0x2 << 5),
kGYRO_CONFIG1_TEMP_FILT_BW_40hz= (0x3 << 5),
kGYRO_CONFIG1_TEMP_FILT_BW_20hz= (0x4 << 5),
kGYRO_CONFIG1_TEMP_FILT_BW_10hz = (0x5 << 5),
kGYRO_CONFIG1_TEMP_FILT_BW_5hz = (0x6 << 5),
};
enum
{
kGYRO_ACCEL_CONFIG0_GYRO_UI_FILT_BW_0 = (0x0 << 0),
kGYRO_ACCEL_CONFIG0_GYRO_UI_FILT_BW_1= (0x1 << 0),
kGYRO_ACCEL_CONFIG0_GYRO_UI_FILT_BW_2= (0x2 << 0),
kGYRO_ACCEL_CONFIG0_GYRO_UI_FILT_BW_3= (0x3 << 0),
kGYRO_ACCEL_CONFIG0_GYRO_UI_FILT_BW_4= (0x4 << 0),
kGYRO_ACCEL_CONFIG0_GYRO_UI_FILT_BW_5= (0x5 << 0),
kGYRO_ACCEL_CONFIG0_GYRO_UI_FILT_BW_6= (0x6 << 0),
kGYRO_ACCEL_CONFIG0_GYRO_UI_FILT_BW_7= (0x7 << 0),
kGYRO_ACCEL_CONFIG0_GYRO_UI_FILT_BW_14= (0xe << 0),
kGYRO_ACCEL_CONFIG0_GYRO_UI_FILT_BW_15 = (0xf << 0),
kGYRO_ACCEL_CONFIG0_ACCEL_UI_FILT_BW_0= (0x0 << 4),
kGYRO_ACCEL_CONFIG0_ACCEL_UI_FILT_BW_1= (0x1 << 4),
kGYRO_ACCEL_CONFIG0_ACCEL_UI_FILT_BW_2= (0x2 << 4),
kGYRO_ACCEL_CONFIG0_ACCEL_UI_FILT_BW_3= (0x3 << 4),
kGYRO_ACCEL_CONFIG0_ACCEL_UI_FILT_BW_4= (0x4 << 4),
kGYRO_ACCEL_CONFIG0_ACCEL_UI_FILT_BW_5= (0x5 << 4),
kGYRO_ACCEL_CONFIG0_ACCEL_UI_FILT_BW_6= (0x6 << 4),
kGYRO_ACCEL_CONFIG0_ACCEL_UI_FILT_BW_7= (0x7 << 4),
kGYRO_ACCEL_CONFIG0_ACCEL_UI_FILT_BW_14= (0xe << 4),
kGYRO_ACCEL_CONFIG0_ACCEL_UI_FILT_BW_15= (0xf << 4),
};
enum
{
kACCEL_CONFIG1_ACCEL_DEC2_M2_ORD_3rd = (0x2 << 1),
kACCEL_CONFIG1_ACCEL_UI_FILT_ORD_1st= (0x0 << 3),
kACCEL_CONFIG1_ACCEL_UI_FILT_ORD_2st= (0x1 << 3),
kACCEL_CONFIG1_ACCEL_UI_FILT_ORD_3st= (0x2 << 3),
};
enum
{
kSELF_TEST_CONFIG_EN_GX_ST= (0x1 << 0),
kSELF_TEST_CONFIG_EN_GY_ST= (0x1 << 1),
kSELF_TEST_CONFIG_EN_GZ_ST= (0x1 << 2),
kSELF_TEST_CONFIG_EN_AX_ST= (0x1 << 3),
kSELF_TEST_CONFIG_EN_AY_ST= (0x1 << 4),
kSELF_TEST_CONFIG_EN_AZ_ST= (0x1 << 5),
kSELF_TEST_CONFIG_ACCEL_ST_POWER= (0x1 << 6),
};
enum
{
kREG_BANK_SEL_BANK_0= (0x0 << 0),
kREG_BANK_SEL_BANK_1= (0x1 << 1),
kREG_BANK_SEL_BANK_2= (0x2 << 2),
kREG_BANK_SEL_BANK_3= (0x3 << 3),
kREG_BANK_SEL_BANK_4= (0x4 << 4),
};
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* __IMU4265XXX_H__ */
/******************************************************************************************
*Copyright(c)2021,Shanghai huida Tech. Co.,Ltd
*All rights reserved.
********************************************************************************************
*End of this File(EOF):
*!!!!!!Do not put anything after this part!!!!!!!
******************************************************************************************/
icm42xxx.c
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include "imu42xxx_defs.h"
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
uint8_t who =0;
#define IIM42653_WHOAMI 0x56
#define CONCAT_BYTE_UINT(a,b)(((uint16_t)a << 8)|b)
#define CONCAT_BYTES_INT(a,b) ((int16_t)(a << 8)|b)
static void pabort(const char *s)
{
perror(s);
abort();
}
static const char *device = "/dev/spidev1.0";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 500000;
static uint16_t delay;
const float ICM_ACC_SCALE = 32.0/32768;
const float ICM_GYRO_SCALE = 2000.0/32768;
IIM42xxx_SENSOR_t _iim42653 ={0};
int readRegister(int fd,uint8_t register_add){
struct spi_ioc_transfer xfer[1] = {0};
// Write message for register address
uint8_t reg_addr = register_add | 0x80;
uint8_t data[2];
data[0] = reg_addr;
data[1] = 0x00;
xfer[0].tx_buf = (__u64)data; // output buffer
xfer[0].rx_buf = (__u64)data; // input buffer
xfer[0].len = (__u32)sizeof(data); // length of data to read
int retv = ioctl(fd, SPI_IOC_MESSAGE(1), &xfer);
if (retv < 0)
{
printf("error in spi_read_reg8(): ioctl(SPI_IOC_MESSAGE(2))");
}
printf("data[0]=%x,data[1]=%x\n",data[0],data[1]);
return data[1];
}
int writeRegister(int fd,uint8_t register_addr, uint8_t value) {
struct spi_ioc_transfer xfer[1] = {0};
// Write message for register address
uint8_t data[2];
data[0] = register_addr;
data[1] = value;
xfer[0].tx_buf = (__u64)data; // output buffer
xfer[0].rx_buf = (__u64)data; // input buffer
xfer[0].len = (__u32)sizeof(data); // length of data to write
int retv = ioctl(fd, SPI_IOC_MESSAGE(1), &xfer);
if (retv < 0)
{
printf("error in spi_write_reg8(): ioctl(SPI_IOC_MESSAGE(2)) return");
}
return retv;
}
static void transfer(int fd)
{
int ret;
uint8_t tx[] = { //要发送的数据数组
0xf5, 0x00,
};
uint8_t rx[ARRAY_SIZE(tx)] = {0, }; //接收的数据数据
struct spi_ioc_transfer tr = { //声明并初始化spi_ioc_transfer结构体
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
//SPI_IOC_MESSAGE(1)的1表示spi_ioc_transfer的数量
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); //ioctl默认操作,传输数据
if (ret < 1)
pabort("can't send spi message");
for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { //打印接收缓冲区
if (!(ret % 6)) //6个数据为一簇打印
puts("");
printf("%.2X ", rx[ret]);
}
puts("");
}
static void imu_data_brust(int fd)
{
int ret;
int16_t value=0;
uint8_t tx[] = { //要发送的数据数组
MPUREG_TEMP_DATA1_UI|SPI_R, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
};
uint8_t rx[ARRAY_SIZE(tx)] = {0, }; //接收的数据数据
struct spi_ioc_transfer tr = { //声明并初始化spi_ioc_transfer结构体
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
//SPI_IOC_MESSAGE(1)的1表示spi_ioc_transfer的数量
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); //ioctl默认操作,传输数据
if (ret < 1)
pabort("can't send spi message");
/* for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { //打印接收缓冲区
if (!(ret % 6)) //6个数据为一簇打印
puts("");
printf("%.2X ", rx[ret]);
}
puts(""); */
value = CONCAT_BYTES_INT(rx[1],rx[2]);
_iim42653.TEMP_RAW = value;
value = CONCAT_BYTES_INT(rx[3],rx[4]);
_iim42653.ACCEL_X_RAW = (float)value*ICM_ACC_SCALE;
value = CONCAT_BYTES_INT(rx[5],rx[6]);
_iim42653.ACCEL_Y_RAW = (float)value*ICM_ACC_SCALE;
value = CONCAT_BYTES_INT(rx[7],rx[8]);
_iim42653.ACCEL_Z_RAW = (float)value*ICM_ACC_SCALE;
value = CONCAT_BYTES_INT(rx[9],rx[10]);
_iim42653.GYRO_X_RAW = (float)value*ICM_GYRO_SCALE;
value = CONCAT_BYTES_INT(rx[11],rx[12]);
_iim42653.GYRO_Y_RAW = (float)value*ICM_GYRO_SCALE;
value = CONCAT_BYTES_INT(rx[13],rx[14]);
_iim42653.GYRO_Z_RAW = (float)value*ICM_GYRO_SCALE;
printf("TEMP_RAW:%x,ACCEL_X_RAW:%f,ACCEL_Y_RAW:%f,ACCEL_Z_RAW:%f,GYRO_X_RAW:%f,GYRO_Y_RAW:%f,GYRO_Z_RAW:%f\n",
_iim42653.TEMP_RAW,_iim42653.ACCEL_X_RAW,_iim42653.ACCEL_Y_RAW,_iim42653.ACCEL_Z_RAW,
_iim42653.GYRO_X_RAW,_iim42653.GYRO_Y_RAW,_iim42653.GYRO_Z_RAW);
}
/*
static void imu_data_brust(void)
{
uint8_t i=0;
int16_t value=0;
uint8_t _txbuf[15] = {0};
uint8_t _rxbuf[15] = {0};
if(_iim42653.init != 1)
return;
_txbuf[0] = MPUREG_TEMP_DATA1_UI|SPI_R;//read form register addr 0x1D TEMP_DATA1_UI TO GYRO _DATA_Z0_UI
for( i= 0;i<14;i++)
{
_txbuf[i+1] = 0X00;
}
SPI_ReadWriteBytes(_txbuf,15,_rxbuf,15);
value = CONCAT_BYTES_INT(_rxbuf[1],_rxbuf[2]);
_iim42653.TEMP_RAW = value;
value = CONCAT_BYTES_INT(_rxbuf[3],_rxbuf[4]);
_iim42653.ACCEL_X_RAW = (float)value*ICM_ACC_SCALE;
value = CONCAT_BYTES_INT(_rxbuf[5],_rxbuf[6]);
_iim42653.ACCEL_Y_RAW = (float)value*ICM_ACC_SCALE;
value = CONCAT_BYTES_INT(_rxbuf[7],_rxbuf[8]);
_iim42653.ACCEL_Z_RAW = (float)value*ICM_ACC_SCALE;
value = CONCAT_BYTES_INT(_rxbuf[9],_rxbuf[10]);
_iim42653.GYRO_X_RAW = (float)value*ICM_GYRO_SCALE;
value = CONCAT_BYTES_INT(_rxbuf[11],_rxbuf[12]);
_iim42653.GYRO_Y_RAW = (float)value*ICM_GYRO_SCALE;
value = CONCAT_BYTES_INT(_rxbuf[13],_rxbuf[14]);
_iim42653.GYRO_Z_RAW = (float)value*ICM_GYRO_SCALE;
_iim42653.utc = get_utc_time();
WriteBuffData(&msgringbuff,&_iim42653);
}
*/
int main(int argc, char *argv[])
{
int ret = 0;
int fd;
uint8_t _txbuf[2] = {0};
uint8_t _rxbuf[2] = {0};
// parse_opts(argc, argv); //解析传递进来的参数
uint8_t mode = SPI_MODE_3; // SPI模式,0, 1, 2, 3等
speed = 1000000;
fd = open(device, O_RDWR); //打开设备文件
if (fd < 0)
pabort("can't open device");
/*
* spi mode //设置spi设备模式
*/
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); //写模式
if (ret == -1)
pabort("can't set spi mode");
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode); //读模式
if (ret == -1)
pabort("can't get spi mode");
/*
* bits per word //设置每个字含多少位
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); //写 每个字含多少位
if (ret == -1)
pabort("can't set bits per word");
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); //读 每个字含多少位
if (ret == -1)
pabort("can't get bits per word");
/*
* max speed hz //设置速率
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); //写速率
if (ret == -1)
pabort("can't set max speed hz");
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); //读速率
if (ret == -1)
pabort("can't get max speed hz");
//打印模式,每字多少位和速率信息
printf("spi mode: %d\n", mode);
printf("bits per word: %d\n", bits);
printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
who =readRegister(fd, 0x75);
printf("AAA WHO_AM_I:", who);
//printf("readRegister(fd,0x75);: %x\n", readRegister(fd,0x75));
//transfer(fd); //传输测试
if(who == IIM42653_WHOAMI)
{
// _txbuf[0] = MPUREG_PWR_MGMT_0&SPI_W;//register addr 0x4E PWR_MGMT0
// _txbuf[1] = kPWR_MGMT0_ACCEL_MODE_LN|kPWR_MGMT0_GYRO_MODE_LN;//1:0 accel_mode 11:low nosize 3:2 GYRO_mode 11:low nosize 0X0F
// SPI_WriteBytes(_txbuf,2);
_txbuf[0] = MPUREG_FIFO_CONFIG&SPI_W;//register addr 0x16 FIFO_CONFIG
_txbuf[1] = kFIFO_CONFIG_FIFO_MODE_BYPASS;//0X0 BYPASS MODE (DEFAULT)
writeRegister(fd,_txbuf[0],_txbuf[1]);
_txbuf[0] = MPUREG_GYRO_CONFIG0&SPI_W;//register addr 0x4F GYRO_CONFIG0
_txbuf[1] = (0x1 << 5)|kGYRO_CONFIG0_GYRO_ODR_32KHZ;//2000dps 32khz
writeRegister(fd,_txbuf[0],_txbuf[1]);
_txbuf[0] = MPUREG_ACCEL_CONFIG0&SPI_W;//register addr 0x50 ACCEL_CONFIG0
_txbuf[1] = (0x0 << 5)|kACCEL_CONFIG0_ACCEL_ODR_32KHZ;//32g 32khz
writeRegister(fd,_txbuf[0],_txbuf[1]);
_txbuf[0] = 0x52&SPI_W;
_txbuf[1] = 0x77;
writeRegister(fd,_txbuf[0],_txbuf[1]);
///42hz Anti-aliasing filter ACCEL
// SPI1_Write_Reg(channel,0x76, 2);//BANK 2
_txbuf[0] = 0x76&SPI_W;
_txbuf[1] = 2;
writeRegister(fd,_txbuf[0],_txbuf[1]);
// SPI1_Write_Reg(channel,0x03, 0x02);
_txbuf[0] = 0x03&SPI_W;
_txbuf[1] = 0x02;
writeRegister(fd,_txbuf[0],_txbuf[1]);
// SPI1_Write_Reg(channel,0x04, 0x01);
_txbuf[0] = 0x04&SPI_W;
_txbuf[1] = 0x01;
writeRegister(fd,_txbuf[0],_txbuf[1]);
// SPI1_Write_Reg(channel,0x05, 0xf0);
_txbuf[0] = 0x05&SPI_W;
_txbuf[1] = 0xf0;
writeRegister(fd,_txbuf[0],_txbuf[1]);
///42hz Anti-aliasing filter GYRO
// SPI1_Write_Reg(channel,0x76, 1);//BANK 1
_txbuf[0] = 0x76&SPI_W;
_txbuf[1] = 1;
writeRegister(fd,_txbuf[0],_txbuf[1]);
// SPI1_Write_Reg(channel,0x03, 0x80);//
_txbuf[0] = 0x03&SPI_W;
_txbuf[1] = 0x80;
writeRegister(fd,_txbuf[0],_txbuf[1]);
// SPI1_Write_Reg(channel,0x0B, 0);//bit1-GYRO_AAF_DIS bit0-GYRO_NF_DIS 0-on 1-off
_txbuf[0] = 0x0B&SPI_W;
_txbuf[1] = 0;
writeRegister(fd,_txbuf[0],_txbuf[1]);
// SPI1_Write_Reg(channel,0x0c, 1);
_txbuf[0] = 0x0c&SPI_W;
_txbuf[1] = 1;
writeRegister(fd,_txbuf[0],_txbuf[1]);
// SPI1_Write_Reg(channel,0x0d, 1);
_txbuf[0] = 0x0d&SPI_W;
_txbuf[1] = 1;
writeRegister(fd,_txbuf[0],_txbuf[1]);
// SPI1_Write_Reg(channel,0x0e, 0xf0);
_txbuf[0] = 0x0e&SPI_W;
_txbuf[1] = 0xf0;
writeRegister(fd,_txbuf[0],_txbuf[1]);
// SPI1_Write_Reg(channel,0x76, 0);
_txbuf[0] = 0x76&SPI_W;
_txbuf[1] = 0;
writeRegister(fd,_txbuf[0],_txbuf[1]);
// SPI1_Write_Reg(channel,0x76, 0);BANK 0
_txbuf[0] = 0x76&SPI_W;
_txbuf[1] = 0;
writeRegister(fd,_txbuf[0],_txbuf[1]);
_txbuf[0] = MPUREG_PWR_MGMT_0&SPI_W;//register addr 0x4E PWR_MGMT0
_txbuf[1] = kPWR_MGMT0_ACCEL_MODE_LN|kPWR_MGMT0_GYRO_MODE_LN;//1:0 accel_mode 11:low nosize 3:2 GYRO_mode 11:low nosize 0X0F
writeRegister(fd,_txbuf[0],_txbuf[1]);
sleep(1);
_txbuf[0] = MPUREG_PWR_MGMT_0|SPI_R;//register addr 0x75 WHO_AM_I
_txbuf[1] = kPWR_MGMT0_ACCEL_MODE_LN|kPWR_MGMT0_GYRO_MODE_LN;
_rxbuf[0]=0;
_rxbuf[1]=0;
//readRegister(fd, 0x75);
//SPI_ReadWriteBytes(_txbuf,2,_rxbuf,2);
//printf("end readRegister(fd,0x75);: %x\n", readRegister(fd,_txbuf));
if((_rxbuf[1]&0x0f) == (kPWR_MGMT0_ACCEL_MODE_LN|kPWR_MGMT0_GYRO_MODE_LN))
{
//_iim42653.init = 1;
}
printf("AAAA=%x\n",(kPWR_MGMT0_ACCEL_MODE_LN|kPWR_MGMT0_GYRO_MODE_LN));
{
int ret;
uint8_t tx[] = { //要发送的数据数组
MPUREG_PWR_MGMT_0|SPI_R, kPWR_MGMT0_ACCEL_MODE_LN|kPWR_MGMT0_GYRO_MODE_LN,
};
uint8_t rx[ARRAY_SIZE(tx)] = {0, }; //接收的数据数据
struct spi_ioc_transfer tr = { //声明并初始化spi_ioc_transfer结构体
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
//SPI_IOC_MESSAGE(1)的1表示spi_ioc_transfer的数量
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); //ioctl默认操作,传输数据
if (ret < 1)
pabort("can't send spi message");
for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { //打印接收缓冲区
if (!(ret % 6)) //6个数据为一簇打印
puts("");
printf("%.2X ", rx[ret]);
}
puts("");
}
imu_data_brust(fd);
}
for(int i=0;i< 100; i++)
{
imu_data_brust(fd);
sleep(0.5);
}
close(fd); //关闭设备
return ret;
}
https://leibton.medium.com/c-code-for-spi-communication-between-imu-and-raspberry-pi-203afe4784e0
原文地址:https://blog.csdn.net/ldinvicible/article/details/144347359
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!