自学内容网 自学内容网

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)!