我有两个型号为BMI160和BMP388的Bosch传感器。我正在尝试将这些传感器与基于STM32的NUCLEO板一起使用。我正在使用CubeIDE和C对STM32进行编码。
博世的传感器有API,而且非常详细。然而,据我所知,为了提供I2C或SPI连接,需要编写一个包装器。
https://github.com/BoschSensortec/BMP3-Sensor-API
让我举一个BMP388的例子。除了API的主要.c和.h文件外,还有公共.c和公共.h文件。据我所知,接口通信是通过这些文件进行的。在标准版本中;硬币";使用了协议,但我需要将其转换为两个传感器的STM32HALI2C通信。
对于BMP388,我创建了这样的东西:
BMP3_INTF_RET_TYPE bmp3_i2c_read(uint8_t reg_addr, uint8_t * reg_data, uint32_t len, void * intf_ptr);
BMP3_INTF_RET_TYPE bmp3_i2c_write(uint8_t reg_addr,
const uint8_t * reg_data, uint32_t len, void * intf_ptr);
uint8_t GTXBuffer[512], GRXBuffer[2048];
int8_t SensorAPI_I2Cx_Read(uint8_t subaddress, uint8_t * pBuffer, uint32_t ReadNumbr, void * intf_ptr) {
uint8_t dev_addr = * (uint8_t * ) intf_ptr;
uint16_t DevAddress = dev_addr << 1;
// send register address
HAL_I2C_Master_Transmit( & I2C_HANDLE, DevAddress, & subaddress, 1, BUS_TIMEOUT);
HAL_I2C_Master_Receive( & I2C_HANDLE, DevAddress, pBuffer, ReadNumbr, BUS_TIMEOUT);
return 0;
}
int8_t SensorAPI_I2Cx_Write(uint8_t subaddress, uint8_t * pBuffer, uint32_t WriteNumbr, void * intf_ptr) {
uint8_t dev_addr = * (uint8_t * ) intf_ptr;
uint16_t DevAddress = dev_addr << 1;
GTXBuffer[0] = subaddress;
memcpy( & GTXBuffer[1], pBuffer, WriteNumbr);
// send register address
HAL_I2C_Master_Transmit( & I2C_HANDLE, DevAddress, GTXBuffer, WriteNumbr + 1, BUS_TIMEOUT);
return 0;
}
但我不知道如何编辑common.c和common.h才能运行这个函数。
BMP388的Standart common.c文件,它使用COINES。
/**
* Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "bmp3.h"
#include "coines.h"
#include "common.h"
/*! BMP3 shuttle board ID */
#define BMP3_SHUTTLE_ID 0xD3
/* Variable to store the device address */
static uint8_t dev_addr;
/*!
* I2C read function map to COINES platform
*/
BMP3_INTF_RET_TYPE bmp3_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_addr = *(uint8_t*)intf_ptr;
return coines_read_i2c(dev_addr, reg_addr, reg_data, (uint16_t)len);
}
/*!
* I2C write function map to COINES platform
*/
BMP3_INTF_RET_TYPE bmp3_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_addr = *(uint8_t*)intf_ptr;
return coines_write_i2c(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
}
/*!
* SPI read function map to COINES platform
*/
BMP3_INTF_RET_TYPE bmp3_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_addr = *(uint8_t*)intf_ptr;
return coines_read_spi(dev_addr, reg_addr, reg_data, (uint16_t)len);
}
/*!
* SPI write function map to COINES platform
*/
BMP3_INTF_RET_TYPE bmp3_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_addr = *(uint8_t*)intf_ptr;
return coines_write_spi(dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
}
/*!
* Delay function map to COINES platform
*/
void bmp3_delay_us(uint32_t period, void *intf_ptr)
{
coines_delay_usec(period);
}
void bmp3_check_rslt(const char api_name[], int8_t rslt)
{
switch (rslt)
{
case BMP3_OK:
/* Do nothing */
break;
case BMP3_E_NULL_PTR:
printf("API [%s] Error [%d] : Null pointerrn", api_name, rslt);
break;
case BMP3_E_COMM_FAIL:
printf("API [%s] Error [%d] : Communication failurern", api_name, rslt);
break;
case BMP3_E_INVALID_LEN:
printf("API [%s] Error [%d] : Incorrect length parameterrn", api_name, rslt);
break;
case BMP3_E_DEV_NOT_FOUND:
printf("API [%s] Error [%d] : Device not foundrn", api_name, rslt);
break;
case BMP3_E_CONFIGURATION_ERR:
printf("API [%s] Error [%d] : Configuration Errorrn", api_name, rslt);
break;
case BMP3_W_SENSOR_NOT_ENABLED:
printf("API [%s] Error [%d] : Warning when Sensor not enabledrn", api_name, rslt);
break;
case BMP3_W_INVALID_FIFO_REQ_FRAME_CNT:
printf("API [%s] Error [%d] : Warning when Fifo watermark level is not in limitrn", api_name, rslt);
break;
default:
printf("API [%s] Error [%d] : Unknown error codern", api_name, rslt);
break;
}
}
BMP3_INTF_RET_TYPE bmp3_interface_init(struct bmp3_dev *bmp3, uint8_t intf)
{
int8_t rslt = BMP3_OK;
struct coines_board_info board_info;
if (bmp3 != NULL)
{
int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB);
if (result < COINES_SUCCESS)
{
printf(
"n Unable to connect with Application Board ! n" " 1. Check if the board is connected and powered on. n" " 2. Check if Application Board USB driver is installed. n"
" 3. Check if board is in use by another application. (Insufficient permissions to access USB) n");
exit(result);
}
result = coines_get_board_info(&board_info);
#if defined(PC)
setbuf(stdout, NULL);
#endif
if (result == COINES_SUCCESS)
{
if ((board_info.shuttle_id != BMP3_SHUTTLE_ID))
{
printf("! Warning invalid sensor shuttle n ," "This application will not support this sensor n");
exit(COINES_E_FAILURE);
}
}
coines_set_shuttleboard_vdd_vddio_config(0, 0);
coines_delay_msec(1000);
/* Bus configuration : I2C */
if (intf == BMP3_I2C_INTF)
{
printf("I2C Interfacen");
dev_addr = BMP3_ADDR_I2C_PRIM;
bmp3->read = bmp3_i2c_read;
bmp3->write = bmp3_i2c_write;
bmp3->intf = BMP3_I2C_INTF;
coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE);
}
/* Bus configuration : SPI */
else if (intf == BMP3_SPI_INTF)
{
printf("SPI Interfacen");
dev_addr = COINES_SHUTTLE_PIN_7;
bmp3->read = bmp3_spi_read;
bmp3->write = bmp3_spi_write;
bmp3->intf = BMP3_SPI_INTF;
coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0);
}
coines_delay_msec(1000);
coines_set_shuttleboard_vdd_vddio_config(3300, 3300);
coines_delay_msec(1000);
bmp3->delay_us = bmp3_delay_us;
bmp3->intf_ptr = &dev_addr;
}
else
{
rslt = BMP3_E_NULL_PTR;
}
return rslt;
}
void bmp3_coines_deinit(void)
{
fflush(stdout);
coines_set_shuttleboard_vdd_vddio_config(0, 0);
coines_delay_msec(1000);
/* Coines interface reset */
coines_soft_reset();
coines_delay_msec(1000);
coines_close_comm_intf(COINES_COMM_INTF_USB);
}
用您编写的函数替换coin函数就足够了。
例如:
替代品:
return coines_read_i2c(dev_addr, reg_addr, reg_data, (uint16_t)len);
带有:
SensorAPI_I2Cx_Read(dev_addr, reg_addr, reg_data, (uint16_t)len)
然后你只需要检查这些呼叫是否是兼容类型的