nRF SPI 与 TWI 操作相关 (BMI088 与 MLX90614 举例)

SPI0 与 TWI0 的 ID相同,SPI0 与 TWI0 的 ID相同。编译时有报错

nRF SPI 与 TWI 操作相关 (BMI088 与 MLX90614 举例)_第1张图片

若要避免,有两个方法

1、使用不同ID外设

2、使用模拟SPI或模拟IIC

 

nRF SPI 初始化

sdk_config.h 中:

添加:

//  Application

//==========================================================
//  SPI_CONFIGURATION - Spi configuration

//==========================================================
//  SPI_BMI088_SCK_PIN - Pin number

// <0=> 0 (P0.0)
// <1=> 1 (P0.1)
// <2=> 2 (P0.2)
// <3=> 3 (P0.3)
// <4=> 4 (P0.4)
// <5=> 5 (P0.5)
// <6=> 6 (P0.6)
// <7=> 7 (P0.7)
// <8=> 8 (P0.8)
// <9=> 9 (P0.9)
// <10=> 10 (P0.10)
// <11=> 11 (P0.11)
// <12=> 12 (P0.12)
// <13=> 13 (P0.13)
// <14=> 14 (P0.14)
// <15=> 15 (P0.15)
// <16=> 16 (P0.16)
// <17=> 17 (P0.17)
// <18=> 18 (P0.18)
// <19=> 19 (P0.19)
// <20=> 20 (P0.20)
// <21=> 21 (P0.21)
// <22=> 22 (P0.22)
// <23=> 23 (P0.23)
// <24=> 24 (P0.24)
// <25=> 25 (P0.25)
// <26=> 26 (P0.26)
// <27=> 27 (P0.27)
// <28=> 28 (P0.28)
// <29=> 29 (P0.29)
// <30=> 30 (P0.30)
// <31=> 31 (P0.31)
// <32=> 32 (P1.0)
// <33=> 33 (P1.1)
// <34=> 34 (P1.2)
// <35=> 35 (P1.3)
// <36=> 36 (P1.4)
// <37=> 37 (P1.5)
// <38=> 38 (P1.6)
// <39=> 39 (P1.7)
// <40=> 40 (P1.8)
// <41=> 41 (P1.9)
// <42=> 42 (P1.10)
// <43=> 43 (P1.11)
// <44=> 44 (P1.12)
// <45=> 45 (P1.13)
// <46=> 46 (P1.14)
// <47=> 47 (P1.15)
// <4294967295=> Not connected

#ifndef SPI_BMI088_SCK_PIN
#define SPI_BMI088_SCK_PIN 45
#endif

//  SPI_BMI088_MISO_PIN - Pin number

// <0=> 0 (P0.0)
// <1=> 1 (P0.1)
// <2=> 2 (P0.2)
// <3=> 3 (P0.3)
// <4=> 4 (P0.4)
// <5=> 5 (P0.5)
// <6=> 6 (P0.6)
// <7=> 7 (P0.7)
// <8=> 8 (P0.8)
// <9=> 9 (P0.9)
// <10=> 10 (P0.10)
// <11=> 11 (P0.11)
// <12=> 12 (P0.12)
// <13=> 13 (P0.13)
// <14=> 14 (P0.14)
// <15=> 15 (P0.15)
// <16=> 16 (P0.16)
// <17=> 17 (P0.17)
// <18=> 18 (P0.18)
// <19=> 19 (P0.19)
// <20=> 20 (P0.20)
// <21=> 21 (P0.21)
// <22=> 22 (P0.22)
// <23=> 23 (P0.23)
// <24=> 24 (P0.24)
// <25=> 25 (P0.25)
// <26=> 26 (P0.26)
// <27=> 27 (P0.27)
// <28=> 28 (P0.28)
// <29=> 29 (P0.29)
// <30=> 30 (P0.30)
// <31=> 31 (P0.31)
// <32=> 32 (P1.0)
// <33=> 33 (P1.1)
// <34=> 34 (P1.2)
// <35=> 35 (P1.3)
// <36=> 36 (P1.4)
// <37=> 37 (P1.5)
// <38=> 38 (P1.6)
// <39=> 39 (P1.7)
// <40=> 40 (P1.8)
// <41=> 41 (P1.9)
// <42=> 42 (P1.10)
// <43=> 43 (P1.11)
// <44=> 44 (P1.12)
// <45=> 45 (P1.13)
// <46=> 46 (P1.14)
// <47=> 47 (P1.15)
// <4294967295=> Not connected

#ifndef SPI_BMI088_MISO_PIN
#define SPI_BMI088_MISO_PIN 47
#endif

//  SPI_BMI088_MOSI_PIN - Pin number

// <0=> 0 (P0.0)
// <1=> 1 (P0.1)
// <2=> 2 (P0.2)
// <3=> 3 (P0.3)
// <4=> 4 (P0.4)
// <5=> 5 (P0.5)
// <6=> 6 (P0.6)
// <7=> 7 (P0.7)
// <8=> 8 (P0.8)
// <9=> 9 (P0.9)
// <10=> 10 (P0.10)
// <11=> 11 (P0.11)
// <12=> 12 (P0.12)
// <13=> 13 (P0.13)
// <14=> 14 (P0.14)
// <15=> 15 (P0.15)
// <16=> 16 (P0.16)
// <17=> 17 (P0.17)
// <18=> 18 (P0.18)
// <19=> 19 (P0.19)
// <20=> 20 (P0.20)
// <21=> 21 (P0.21)
// <22=> 22 (P0.22)
// <23=> 23 (P0.23)
// <24=> 24 (P0.24)
// <25=> 25 (P0.25)
// <26=> 26 (P0.26)
// <27=> 27 (P0.27)
// <28=> 28 (P0.28)
// <29=> 29 (P0.29)
// <30=> 30 (P0.30)
// <31=> 31 (P0.31)
// <32=> 32 (P1.0)
// <33=> 33 (P1.1)
// <34=> 34 (P1.2)
// <35=> 35 (P1.3)
// <36=> 36 (P1.4)
// <37=> 37 (P1.5)
// <38=> 38 (P1.6)
// <39=> 39 (P1.7)
// <40=> 40 (P1.8)
// <41=> 41 (P1.9)
// <42=> 42 (P1.10)
// <43=> 43 (P1.11)
// <44=> 44 (P1.12)
// <45=> 45 (P1.13)
// <46=> 46 (P1.14)
// <47=> 47 (P1.15)
// <4294967295=> Not connected

#ifndef SPI_BMI088_MOSI_PIN
#define SPI_BMI088_MOSI_PIN 46
#endif


//  SPI_BMI088_SS_PIN - Pin number

// <0=> 0 (P0.0)
// <1=> 1 (P0.1)
// <2=> 2 (P0.2)
// <3=> 3 (P0.3)
// <4=> 4 (P0.4)
// <5=> 5 (P0.5)
// <6=> 6 (P0.6)
// <7=> 7 (P0.7)
// <8=> 8 (P0.8)
// <9=> 9 (P0.9)
// <10=> 10 (P0.10)
// <11=> 11 (P0.11)
// <12=> 12 (P0.12)
// <13=> 13 (P0.13)
// <14=> 14 (P0.14)
// <15=> 15 (P0.15)
// <16=> 16 (P0.16)
// <17=> 17 (P0.17)
// <18=> 18 (P0.18)
// <19=> 19 (P0.19)
// <20=> 20 (P0.20)
// <21=> 21 (P0.21)
// <22=> 22 (P0.22)
// <23=> 23 (P0.23)
// <24=> 24 (P0.24)
// <25=> 25 (P0.25)
// <26=> 26 (P0.26)
// <27=> 27 (P0.27)
// <28=> 28 (P0.28)
// <29=> 29 (P0.29)
// <30=> 30 (P0.30)
// <31=> 31 (P0.31)
// <32=> 32 (P1.0)
// <33=> 33 (P1.1)
// <34=> 34 (P1.2)
// <35=> 35 (P1.3)
// <36=> 36 (P1.4)
// <37=> 37 (P1.5)
// <38=> 38 (P1.6)
// <39=> 39 (P1.7)
// <40=> 40 (P1.8)
// <41=> 41 (P1.9)
// <42=> 42 (P1.10)
// <43=> 43 (P1.11)
// <44=> 44 (P1.12)
// <45=> 45 (P1.13)
// <46=> 46 (P1.14)
// <47=> 47 (P1.15)
// <4294967295=> Not connected

#ifndef SPI_BMI088_SS_PIN
#define SPI_BMI088_SS_PIN 8
#endif


//  SPI_IRQ_PRIORITY - Interrupt priority

//  Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest)
// <1=> 1
// <2=> 2
// <3=> 3
// <4=> 4
// <5=> 5
// <6=> 6
// <7=> 7

#ifndef SPI_IRQ_PRIORITY
#define SPI_IRQ_PRIORITY 2
#endif

// 
//==========================================================

 

勾选:

nRF_Drivers --> NRFX_SPIM_ENABLED

nRF_Drivers --> NRFX_SPI_ENABLED

nRF_Drivers --> SPI_ENABLED

nRF_Drivers --> SPI_ENABLED --> SPI0_ENABLED

nRF_Drivers --> SPI_ENABLED --> SPI0_ENABLED --> SPI0_USE_EASY_DMA

 

注:

记得打开 SPI0_USE_EASY_DMA,SPI 读写不占用MCU资源,大大提高效率,

 

nrf_drv_spi.h 中:

#define NRF_DRV_SPI_DEFAULT_CONFIG \
{ \
    .sck_pin = NRF_DRV_SPI_PIN_NOT_USED, \
    .mosi_pin = NRF_DRV_SPI_PIN_NOT_USED, \
    .miso_pin = NRF_DRV_SPI_PIN_NOT_USED, \
    .ss_pin = NRF_DRV_SPI_PIN_NOT_USED, \
    .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY, \
    .orc = 0xFF, \
    .frequency = NRF_DRV_SPI_FREQ_8M, \
    .mode = NRF_DRV_SPI_MODE_0, \
    .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST, \
}

注:

1、设定的 spi 模式,要与传感器对应

nRF SPI 与 TWI 操作相关 (BMI088 与 MLX90614 举例)_第2张图片

2、设定的 spi 的频率要在传感器支持的频率范围内

3、设定的 bit_order 要与传感器的数据排序一致,MSB_FIRST or LSB_FIRST

 

main.c 中:

#define SPI_INSTANCE_0                  0                                           /**< SPI instance index. */

static const nrf_drv_spi_t spi_0_bmi088 = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE_0);            /**< SPI instance. */

static void spi_bmi088_event_handler(nrf_drv_spi_evt_t const * p_event,
                              					void *                    p_context)
{
    spi_bmi088_xfer_done = true;
//    NRF_LOG_INFO("Spi bmi088 transfer completed.");
}

static void spi_bmi088_init(void)
{
    nrf_drv_spi_config_t spi_bmi088_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_bmi088_config.ss_pin   = NRF_DRV_SPI_PIN_NOT_USED;
    spi_bmi088_config.miso_pin = SPI_BMI088_MISO_PIN;
    spi_bmi088_config.mosi_pin = SPI_BMI088_MOSI_PIN;
    spi_bmi088_config.sck_pin  = SPI_BMI088_SCK_PIN;
    APP_ERROR_CHECK(nrf_drv_spi_init(&spi_0_bmi088, &spi_bmi088_config, spi_bmi088_event_handler, NULL));
}

注:

1、若 cs 片选引脚信号为高使能,或需要操控多个 cs 片选脚时,需在设置时将 .ss_pin 参数留空,另外将其设为输出脚并将其拉高(拉低),在发送或接收时拉低(拉高)。(因为nRF SPI 底层驱动库仅支持 cs 片选引脚低使能)

///< Slave Select pin number (optional).

/**< Set to @ref NRF_DRV_SPI_PIN_NOT_USED

* if this signal is not needed. The driver

* supports only active low for this signal.

* If the signal should be active high,

* it must be controlled externally. */

 

2、nrf_drv_spi_init 初始化参数中,若回调函数留空则将以阻塞模式执行传输。 Event handler provided by the user. If NULL, transfers will be performed in blocking mode.

 

nRF 的 SPI 发送与接收做成了一体,收发都需要调用 nrf_drv_spi_transfer:

1、做发送时

nrf_drv_spi_transfer(&spi_0_bmi088, m_tx_buf, m_tx_length, NULL, 0)

发送的数据 m_tx_buf 内容为 :

m_tx_buf[0] = reg_addr

memcpy(&m_tx_buf[1], data, len);

首字节为寄存器地址,(注:需要做偏移,例如,最高位读写位为0时为写,则需 & 0x7F

从第二个字节开始为要写入的数据)

发送的数据长度 m_tx_length

必须是写入数据的长度 + 1(寄存器地址)

接收BUF及接收数据长度留空

 

2、做接收时

nrf_drv_spi_transfer(&spi_0_bmi088, m_tx_buf, m_tx_length, data, m_rx_length)

发送的数据 m_tx_buf 内容为 :

uint8_t m_tx_buf[1] = {reg_addr};

首字节为寄存器地址,(注:需要做偏移,例如,最高位读写位为1时为读,则需 | 0x80

从第二个字节开始为要写入的数据)

发送的数据长度 m_tx_length = 1;

接收数据长度根据数据而定

 

注:特别注意冗余数据处理,(具体参考2_Vibration_measurer-Github 项目)=

例:

/*!
 *  @brief Function for reading the sensor's registers through SPI bus.
 *
 *  @param[in] cs_pin   : Chip selection pin.
 *  @param[in] reg_addr : Register address.
 *  @param[in] data     : Pointer to the data buffer to store the read data.
 *  @param[in] len      : No of bytes to read.
 *
 *  @return Status of execution
 *  @retval 0 -> Success
 *  @retval >0 -> Failure Info
 *
 */
int8_t user_bmi088_spi_write(uint8_t cs_pin, uint8_t reg_addr, uint8_t *data, uint16_t len)
{
    if (cs_pin == MCU_GPIO_BMI088_CSB1)
    {
        nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB2);
        nrf_gpio_pin_clear(MCU_GPIO_BMI088_CSB1);
    }
    else if (cs_pin == MCU_GPIO_BMI088_CSB2)
    {
        nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB1);
        nrf_gpio_pin_clear(MCU_GPIO_BMI088_CSB2);
    }
    else
    {
        return -2;
    }

    nrf_delay_us(1);

    if (len <= 32)
    {
        uint8_t m_tx_buf[33] = {0};
        m_tx_buf[0] = reg_addr;
        uint8_t m_tx_length = ((uint8_t)len) + 1;
        memcpy(&m_tx_buf[1], data, len);

        spi_bmi088_xfer_done = false;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi_0_bmi088, m_tx_buf, m_tx_length, NULL, 0));
        while(spi_bmi088_xfer_done == false)
        {
            __WFE();
        }
    }
    else
    {
        NRF_LOG_INFO("Spi write over length.");
    }

    nrf_delay_us(1);
    nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB1);
    nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB2);

    return 0;
}


/*!
 *  @brief Function for writing the sensor's registers through SPI bus.
 *
 *  @param[in] cs_pin   : Chip selection pin.
 *  @param[in] reg_addr : Register address.
 *  @param[out]data     : Pointer to the data buffer whose value is to be written.
 *  @param[in] len      : No of bytes to write.
 *
 *  @return Status of execution
 *  @retval 0 -> Success
 *  @retval >0 -> Failure Info
 *
 */
int8_t user_bmi088_spi_read(uint8_t cs_pin, uint8_t reg_addr, uint8_t *data, uint16_t len)
{
    if (cs_pin == MCU_GPIO_BMI088_CSB1)
    {
        nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB2);
        nrf_gpio_pin_clear(MCU_GPIO_BMI088_CSB1);
    }
    else if (cs_pin == MCU_GPIO_BMI088_CSB2)
    {
        nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB1);
        nrf_gpio_pin_clear(MCU_GPIO_BMI088_CSB2);
    }
    else
    {
        return -2;
    }

    nrf_delay_us(1);

    if (len <= 32)
    {
        uint8_t m_tx_buf[1] = {reg_addr};
        uint8_t m_tx_length = 1;
        uint8_t m_rx_length = (uint8_t)len + 1; // Add the byte sent
        uint8_t m_rx_buf[33] = {0};

        spi_bmi088_xfer_done = false;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi_0_bmi088, m_tx_buf, m_tx_length, m_rx_buf, m_rx_length));
        while(spi_bmi088_xfer_done == false)
        {
            __WFE();
        }

        memcpy(data, &m_rx_buf[1], (m_rx_length - 1));
    }
    else
    {
        NRF_LOG_INFO("Spi read over length.");
    }

    nrf_delay_us(1);
    nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB1);
    nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB2);

    return 0;
}

 

nRF TWI 初始化

sdk_config.h 中:

勾选:

NRFX_TWIM_ENABLED --> NRFX_TWIM_ENABLED

NRFX_TWIM_ENABLED --> NRFX_TWI_ENABLED

NRFX_TWIM_ENABLED --> NRFX_TWI_ENABLED --> TWI1_ENABLED

NRFX_TWIM_ENABLED --> NRFX_TWI_ENABLED --> TWI1_ENABLED -->TWI1_USE_EASY_DMA

 

修改:

TWI_DEFAULT_CONFIG_FREQUENCY 26738688

TWI_DEFAULT_CONFIG_CLR_BUS_INIT 0

TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0

TWI_DEFAULT_CONFIG_IRQ_PRIORITY 2

 

nrf_drv_twi.h 中:

#define NRF_DRV_TWI_DEFAULT_CONFIG                                               \
{                                                                                \
    .frequency          = (nrf_drv_twi_frequency_t)TWI_DEFAULT_CONFIG_FREQUENCY, \
    .scl                = 0xFF,                                                  \
    .sda                = 0xFF,                                                  \
    .interrupt_priority = TWI_DEFAULT_CONFIG_IRQ_PRIORITY,                       \
    .clear_bus_init     = TWI_DEFAULT_CONFIG_CLR_BUS_INIT,                       \
    .hold_bus_uninit    = TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT,                    \
}

main.c 中:

static void twi_mlx90614_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
    switch (p_event->type)
    {
        case NRF_DRV_TWI_EVT_DONE:
        {
            if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX)
            {
                NRF_LOG_INFO("Twi mlx90614 tx evt done.");
            }
            else if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
            {
                NRF_LOG_INFO("Twi mlx90614 rx evt done.");
            }
            else if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TXRX)
            {
                NRF_LOG_INFO("Twi mlx90614 txrx evt done.");
            }
            else if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TXTX)
            {
                NRF_LOG_INFO("Twi mlx90614 txtx evt done.");
            }
            twi_mlx90614_xfer_done = true;
        } break;

        case NRF_DRV_TWI_EVT_ADDRESS_NACK:
            NRF_LOG_ERROR("Error event: NACK received after sending the address.");
            break;

        case NRF_DRV_TWI_EVT_DATA_NACK:
            NRF_LOG_ERROR("Error event: NACK received after sending a data byte.");
        break;

        default:
            break;
    }
}


static void twi_mlx90614_init(void)
{
    ret_code_t err_code;

    nrf_drv_twi_config_t twi_mlx90614_config = NRF_DRV_TWI_DEFAULT_CONFIG;
    twi_mlx90614_config.scl                  = TWI_MLX90614_SCL_PIN,
    twi_mlx90614_config.sda                  = TWI_MLX90614_SDA_PIN,

    err_code = nrf_drv_twi_init(&twi_1_mlx90614, &twi_mlx90614_config, twi_mlx90614_handler, NULL);
APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&twi_1_mlx90614);
}

nRF 的 TWI 发送调用 nrf_drv_twi_tx,接收调用 nrf_drv_twi_rx。具体时序依照传感器数据手册

例如 mlx90614:

uint8_t PEC_Calculation(uint8_t pec[])
{
    uint8_t crc[6];
    uint8_t BitPosition = 47;
    uint8_t shift;
    uint8_t i;
    uint8_t j;
    uint8_t temp;

    do
    {
        /*Load pattern value 0x000000000107*/
        crc[5] = 0;
        crc[4] = 0;
        crc[3] = 0;
        crc[2] = 0;
        crc[1] = 0x01;
        crc[0] = 0x07;

        /*Set maximum bit position at 47 ( six bytes byte5...byte0,MSbit=47)*/
        BitPosition = 47;

        /*Set shift position at 0*/
        shift = 0;

        /*Find first "1" in the transmited message beginning from the MSByte byte5*/
        i = 5;
        j = 0;
        while (((pec[i] & (0x80 >> j)) == 0) && (i > 0))
        {
            BitPosition--;
            if (j < 7)
            {
                j++;
            }
            else
            {
                j = 0x00;
                i--;
            }
        }/*End of while */

        /*Get shift value for pattern value*/
        shift = BitPosition - 8;

        /*Shift pattern value */
        while(shift)
        {
            for(i = 5; i < 0xFF; i--)
            {
                if((crc[i-1] & 0x80) && (i > 0))
                {
                    temp = 1;
                }
                else
                {
                    temp = 0;
                }
                crc[i] <<= 1;
                crc[i] += temp;
            }/*End of for*/
            shift--;
        }/*End of while*/

        /*Exclusive OR between pec and crc*/
        for(i = 0; i <= 5; i++)
        {
            pec[i] ^= crc[i];
        }/*End of for*/
    } while(BitPosition > 8); /*End of do-while*/

    return pec[0];
}


uint16_t SMBus_Read_Memory(uint8_t slave_Address, uint8_t command)
{
    ret_code_t err_code;
    uint16_t data;			// Data storage (DataH:DataL)
    uint8_t Pec;			// PEC byte storage
    uint8_t PecReg;			// Calculated PEC byte storage
    uint8_t arr[6];			// Buffer for the sent bytes
    uint8_t DataL = 0;			// Low data byte storage
    uint8_t DataH = 0;			// High data byte storage
    uint8_t Error_Counter;              // Defines the number of the attempts for communication with MLX90614
    uint8_t rx_data[3] = {0};           // Data received from twi
    uint8_t tx_data[1] = {command};     // Data sent from twi
    
    Error_Counter = 0x00;               // Initialising of Error_Counter
    slave_Address <<= 1;                // 2-7 bits indicate the slave address
	
    do
    {
        err_code = nrf_drv_twi_tx(&twi_1_mlx90614, slave_Address, tx_data, 1, true);
        APP_ERROR_CHECK(err_code);
        twi_mlx90614_xfer_done = false;
        while(twi_mlx90614_xfer_done == false);
        {
            __WFE();
        }

        err_code = nrf_drv_twi_rx(&twi_1_mlx90614, slave_Address, rx_data, 3);
        APP_ERROR_CHECK(err_code);
        twi_mlx90614_xfer_done = false;
        while(twi_mlx90614_xfer_done == false);
        {
            __WFE();
        }

        DataL = rx_data[0];
        DataH = rx_data[1];
        Pec = rx_data[2];

        arr[5] = slave_Address;
        arr[4] = command;
        arr[3] = slave_Address + 1;	
        arr[2] = DataL;
        arr[1] = DataH;
        arr[0] = 0;
        PecReg = PEC_Calculation(arr);  // Calculate CRC
    } while(PecReg != Pec);             // If received and calculated CRC are equal go out from do-while{}

    data = (DataH << 8) | DataL;        // data = DataH:DataL

    return data;
}


static float SMBus_Read_Ambient_Temp(void)
{   
    return SMBus_Read_Memory(SA, (RAM_ACCESS | RAM_TA)) * 0.02 - 273.15;
}


static float SMBus_Read_Object_Temp(void)
{   
    return SMBus_Read_Memory(SA, (RAM_ACCESS | RAM_TOBJ1)) * 0.02 - 273.15;
}

 

注:

1、nrf_drv_twi_tx 第五个参数是 是否不发送停止位

nRF SPI 与 TWI 操作相关 (BMI088 与 MLX90614 举例)_第3张图片

2、如果需要访问EEPROM中的地址,则实际的地址值是需要访问的地址值与 Opcode 的组合

如EEPROM的0x0E地址,实际中输入的应该是0x2E

nRF SPI 与 TWI 操作相关 (BMI088 与 MLX90614 举例)_第4张图片

3、写的数据末尾一个字节要加上PEC

 

4、如果是写数据,先要把寄存器数据清零。比如命令为0x24,也就是修改发射频率,第一次先对高低八位分别写一遍0x00,第二次再重新用这个命令写入你要改的数据。

 

参考 2_Vibration_measurer-Github 项目

你可能感兴趣的:(nRF SPI 与 TWI 操作相关 (BMI088 与 MLX90614 举例))