TI-MSPM0G3507外设使用,SPI串口连接ICM20602陀螺仪

写在前面

备战2024电赛,使用到了TI开发板,型号MSPM0G3507,该开发板除文档外,网上资料稀少。
现在为大家提供spi连接icm20602陀螺仪的代码,以促共同进步。
该代码由逐飞seekfree仓库移植而来,如有侵权请私信联系我删除,谢谢。
代码亲测成功,如有bug欢迎评论区指正。

头文件

ICM20602.h

#ifndef ICM20602_H
#define ICM20602_H
#include "../COMMON.h"
#define ICM20602_DEV_ADDR           (0x69)
#define ICM20602_SPI_W              (0x00)
#define ICM20602_SPI_R              (0x80)

#define ICM20602_XG_OFFS_TC_H       (0x04)
#define ICM20602_XG_OFFS_TC_L       (0x05)
#define ICM20602_YG_OFFS_TC_H       (0x07)
#define ICM20602_YG_OFFS_TC_L       (0x08)
#define ICM20602_ZG_OFFS_TC_H       (0x0A)
#define ICM20602_ZG_OFFS_TC_L       (0x0B)
#define ICM20602_SELF_TEST_X_ACCEL  (0x0D)
#define ICM20602_SELF_TEST_Y_ACCEL  (0x0E)
#define ICM20602_SELF_TEST_Z_ACCEL  (0x0F)
#define ICM20602_XG_OFFS_USRH       (0x13)
#define ICM20602_XG_OFFS_USRL       (0x14)
#define ICM20602_YG_OFFS_USRH       (0x15)
#define ICM20602_YG_OFFS_USRL       (0x16)
#define ICM20602_ZG_OFFS_USRH       (0x17)
#define ICM20602_ZG_OFFS_USRL       (0x18)
#define ICM20602_SMPLRT_DIV         (0x19)
#define ICM20602_CONFIG             (0x1A)
#define ICM20602_GYRO_CONFIG        (0x1B)
#define ICM20602_ACCEL_CONFIG       (0x1C)
#define ICM20602_ACCEL_CONFIG_2     (0x1D)
#define ICM20602_LP_MODE_CFG        (0x1E)
#define ICM20602_ACCEL_WOM_X_THR    (0x20)
#define ICM20602_ACCEL_WOM_Y_THR    (0x21)
#define ICM20602_ACCEL_WOM_Z_THR    (0x22)
#define ICM20602_FIFO_EN            (0x23)
#define ICM20602_FSYNC_INT          (0x36)
#define ICM20602_INT_PIN_CFG        (0x37)
#define ICM20602_INT_ENABLE         (0x38)
#define ICM20602_FIFO_WM_INT_STATUS (0x39)
#define ICM20602_INT_STATUS         (0x3A)
#define ICM20602_ACCEL_XOUT_H       (0x3B)
#define ICM20602_ACCEL_XOUT_L       (0x3C)
#define ICM20602_ACCEL_YOUT_H       (0x3D)
#define ICM20602_ACCEL_YOUT_L       (0x3E)
#define ICM20602_ACCEL_ZOUT_H       (0x3F)
#define ICM20602_ACCEL_ZOUT_L       (0x40)
#define ICM20602_TEMP_OUT_H         (0x41)
#define ICM20602_TEMP_OUT_L         (0x42)
#define ICM20602_GYRO_XOUT_H        (0x43)
#define ICM20602_GYRO_XOUT_L        (0x44)
#define ICM20602_GYRO_YOUT_H        (0x45)
#define ICM20602_GYRO_YOUT_L        (0x46)
#define ICM20602_GYRO_ZOUT_H        (0x47)
#define ICM20602_GYRO_ZOUT_L        (0x48)
#define ICM20602_SELF_TEST_X_GYRO   (0x50)
#define ICM20602_SELF_TEST_Y_GYRO   (0x51)
#define ICM20602_SELF_TEST_Z_GYRO   (0x52)
#define ICM20602_FIFO_WM_TH1        (0x60)
#define ICM20602_FIFO_WM_TH2        (0x61)
#define ICM20602_SIGNAL_PATH_RESET  (0x68)
#define ICM20602_ACCEL_INTEL_CTRL   (0x69)
#define ICM20602_USER_CTRL          (0x6A)
#define ICM20602_PWR_MGMT_1         (0x6B)
#define ICM20602_PWR_MGMT_2         (0x6C)
#define ICM20602_I2C_IF             (0x70)
#define ICM20602_FIFO_COUNTH        (0x72)
#define ICM20602_FIFO_COUNTL        (0x73)
#define ICM20602_FIFO_R_W           (0x74)
#define ICM20602_WHO_AM_I           (0x75)
#define ICM20602_XA_OFFSET_H        (0x77)
#define ICM20602_XA_OFFSET_L        (0x78)
#define ICM20602_YA_OFFSET_H        (0x7A)
#define ICM20602_YA_OFFSET_L        (0x7B)
#define ICM20602_ZA_OFFSET_H        (0x7D)
#define ICM20602_ZA_OFFSET_L        (0x7E)

#define ICM20602_TIMEOUT_COUNT      (0x00FF)     

void    icm20602_get_acc            (void);                               
void    icm20602_get_gyro           (void);                    
uint8_t   icm20602_init               (void);       

extern int16_t icm20602_gyro_x, icm20602_gyro_y, icm20602_gyro_z; 
extern int16_t icm20602_acc_x,  icm20602_acc_y,  icm20602_acc_z;
extern float icm20602_transition_factor[2];         

#define icm20602_acc_transition(acc_value)      ((float)(acc_value) / icm20602_transition_factor[0])
#define icm20602_gyro_transition(gyro_value)    ((float)(gyro_value) / icm20602_transition_factor[1])

#endif

源文件

1.ICM20602.c

#include "ICM20602.h"
int16_t icm20602_gyro_x = 0, icm20602_gyro_y = 0, icm20602_gyro_z = 0;   
int16_t icm20602_acc_x = 0, icm20602_acc_y = 0, icm20602_acc_z = 0;   
float icm20602_transition_factor[2] = {4096, 16.4};   
#define ICM20602_CS(x)              ((x) ? (DL_GPIO_setPins(OTHER_PORT,OTHER_ICM_CS_PIN)) : (DL_GPIO_clearPins(OTHER_PORT,OTHER_ICM_CS_PIN)))

void spi_write_8bit_register(uint8_t reg, uint8_t data){
    DL_SPI_transmitData8(ICM_SPI_INST, reg); 
    while (DL_SPI_isBusy(ICM_SPI_INST));
    DL_SPI_transmitData8(ICM_SPI_INST, data); 
    while (DL_SPI_isBusy(ICM_SPI_INST));
}
void spi_read_8bit_registers(uint8_t reg, uint8_t *data, uint32_t len){
    DL_SPI_transmitData8(ICM_SPI_INST,reg);
    while (DL_SPI_isBusy(ICM_SPI_INST));
    for (int i = 0; i< len; i++) {
        DL_SPI_transmitData8(ICM_SPI_INST,0);
        while (DL_SPI_isBusy(ICM_SPI_INST));
        while (!DL_SPI_isRXFIFOEmpty(ICM_SPI_INST)) 
            data[i] = DL_SPI_receiveData8(ICM_SPI_INST);
    }
}
uint8_t spi_read_8bit_register(uint8_t reg){
    DL_SPI_transmitData8(ICM_SPI_INST,reg);
    while (DL_SPI_isBusy(ICM_SPI_INST));
    DL_SPI_transmitData8(ICM_SPI_INST,0);
    while (DL_SPI_isBusy(ICM_SPI_INST));
    uint8_t data = 0;
    while (!DL_SPI_isRXFIFOEmpty(ICM_SPI_INST)) 
        data = DL_SPI_receiveData8(ICM_SPI_INST);
    return data;
}
static void icm20602_write_register(uint8_t reg, uint8_t data)
{
    ICM20602_CS(0);
    spi_write_8bit_register(reg | ICM20602_SPI_W, data);
    ICM20602_CS(1);
}
static uint8_t icm20602_read_register(uint8_t reg)
{
    uint8_t data = 0;
    ICM20602_CS(0);
    data = spi_read_8bit_register(reg | ICM20602_SPI_R);
    ICM20602_CS(1);
    return data;
}
static void icm20602_read_registers(uint8_t reg, uint8_t *data, uint32_t len)
{
    ICM20602_CS(0);
    spi_read_8bit_registers(reg | ICM20602_SPI_R, data, len);
    ICM20602_CS(1);
}
uint8_t icm20602_self_check (void)
{
    uint8_t dat = 0, return_state = 0;
    uint16_t timeout_count = 0;

    while(0x12 != dat)                                                   
    {
        if(ICM20602_TIMEOUT_COUNT < timeout_count ++)
        {
            return_state =  1;
            break;
        }
        dat = icm20602_read_register(ICM20602_WHO_AM_I);
    }
    return return_state;
}

void icm20602_get_acc (void)
{
    uint8_t dat[6];

    icm20602_read_registers(ICM20602_ACCEL_XOUT_H, dat, 6);
    icm20602_acc_x = (int16_t)(((uint16_t)dat[0] << 8 | dat[1]));
    icm20602_acc_y = (int16_t)(((uint16_t)dat[2] << 8 | dat[3]));
    icm20602_acc_z = (int16_t)(((uint16_t)dat[4] << 8 | dat[5]));
}

void icm20602_get_gyro (void)
{
    uint8_t dat[6];

    icm20602_read_registers(ICM20602_GYRO_XOUT_H, dat, 6);
    icm20602_gyro_x = (int16_t)(((uint16_t)dat[0] << 8 | dat[1]));
    icm20602_gyro_y = (int16_t)(((uint16_t)dat[2] << 8 | dat[3]));
    icm20602_gyro_z = (int16_t)(((uint16_t)dat[4] << 8 | dat[5]));
}

uint8_t icm20602_init (void)
{
    uint8_t val = 0x0, return_state = 0;
    uint16_t timeout_count = 0;

    system_delay_ms(10);  

    do
    {
        if(icm20602_self_check())
        {
            return_state = 1;
            break;
        }
        icm20602_write_register(ICM20602_PWR_MGMT_1, 0x80);                     // 复位设备
        system_delay_ms(2);

        do
        {                                                                       // 等待复位成功
            val = icm20602_read_register(ICM20602_PWR_MGMT_1);
            if(ICM20602_TIMEOUT_COUNT < timeout_count ++)
            {
                return_state = 2;
                break;
            }
        }while(0x41 != val);
        if(2 == return_state)
        {
            break;
        }

        icm20602_write_register(ICM20602_PWR_MGMT_1,     0x01);             
        icm20602_write_register(ICM20602_PWR_MGMT_2,     0x00);        
        icm20602_write_register(ICM20602_CONFIG,         0x01);                 
        icm20602_write_register(ICM20602_SMPLRT_DIV,     0x07);      

        icm20602_write_register(ICM20602_ACCEL_CONFIG, 0x10);
        icm20602_transition_factor[0] = 4096;


        icm20602_write_register(ICM20602_GYRO_CONFIG, 0x18);
        icm20602_transition_factor[1] = 16.4;

        icm20602_write_register(ICM20602_ACCEL_CONFIG_2, 0x03); 
    }while(0);
    return return_state;
}

2.测试代码
通过自行查看icm20602_init()的返回值
以及icm20602_gyro_x,icm20602_acc_x等值的大小来观察测试结果

#include "Library/COMMON.h"
int main(void)
{
    SYSCFG_DL_init();
    icm20602_init();
    while (1) {
        icm20602_get_gyro();
        icm20602_get_acc();
        system_delay_ms(1);
    }
}

配置

一个SPI,命名为ICM_SPI
一个GPIO,端口命名为OTHER
一个PIN命名为ICM_CS,设置为Output,默认高电平

后话

还请大家鼓励支持
欢迎访问个人网址
项目开源地址

  • 18
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值