SPI 上的 BMI088 不连接到 RPi4B [C]
BMI088 over SPI does not connect to RPi4B [C]
在我写下我的问题之前,让我先说一下,我确实访问了互联网上所有关于 RPi4B、SPI、BMI088、bcm2835 库和 C 的相关页面,但没有运气和很多挫折。
我有 6 个 BMI088 传感器,我想通过 SPI 连接到 RPi4B。在 Arduino 上,它与 Bolder Flight 库完美配合(一个或全部 6 个)。问题是当我将传感器连接到 RPi 时,我没有从传感器获得任何信息。连接正常(3.3 V、GND、MISO、MOSI、SCK、CS、PS 接地(仅 BMI088))。我还有一个开关可以打开传感器电源 ON/OFF。我发送的消息与 Arduino 库发送的消息完全相同,但我没有从传感器中得到任何信息,MISO 是无声的。如数据表中所述,我为 CSB1 引脚提供了一个上升沿。如果我连接 MISO 和 MOSI RPi 接收数据。
如何让 BMI088 通过 SPI 与 RPi 通信?
代码(不是全部,只是相关部分):
#include <bcm2835.h>
#include <stdio.h>
#define CS_PIN 25
unsigned char buffer[7] = {0};
int main(int argc, char *argv[])
{
int x1, x2, y1, y2, z1, z2;
if (!bcm2835_init())
{
printf("bcm2835_init failed.\n");
return 1;
}
if (bcm2835_init())
{
printf("bcm2835_init successful.\n");
}
if (!bcm2835_spi_begin())
{
printf("bcm2835_spi_begin failed.\n");
return 1;
}
if (bcm2835_spi_begin())
{
printf("bcm2835_spi_begin successful.\n");
}
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); // The default
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); // The default
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_1); // The default
bcm2835_spi_chipSelect(BCM2835_SPI_CS_NONE); // The default
//bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); // the default
bcm2835_gpio_fsel(CS_PIN, BCM2835_GPIO_FSEL_OUTP); //CS is an output
bcm2835_gpio_clr(CS_PIN);
delayms(100);
while(1)
{
// chip ID
buffer[0] = 0x00; //ACC_CHIP_ID;
//buffer[1] = 30;
bcm2835_spi_transfer(0x00);
bcm2835_delayMicroseconds(100);
bcm2835_gpio_set(CS_PIN);
bcm2835_delayMicroseconds(100);
bcm2835_gpio_clr(CS_PIN);
bcm2835_spi_transfern(buffer, 1);
bcm2835_delayMicroseconds(100);
bcm2835_gpio_set(CS_PIN);
printf("\n\nID:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
delayms(100);
// soft reset
buffer[0] = 0x7E;
buffer[1] = 0xB6;
bcm2835_spi_transfern(buffer, 2);
delayms(100);
printf("RESET:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
delayms(100);
// set power
buffer[0] = 0x7D;
buffer[1] = 0x04;
bcm2835_spi_transfern(buffer, 2);
printf("POWER:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
delayms(100);
// set mode
buffer[0] = 0x7C;
buffer[1] = 0x03;
bcm2835_spi_transfern(buffer, 2);
printf("MODE:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
delayms(100);
// set range
buffer[0] = 0x41;
buffer[1] = 0x03;
bcm2835_spi_transfern(buffer, 2);
printf("RANGE:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
delayms(100);
// set ODR
buffer[0] = 0x40;
buffer[1] = 0xAC;
bcm2835_spi_transfern(buffer, 2);
printf("RANGE:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
delayms(100);
buffer[0] = 0x12;
buffer[1] = 0x13;
buffer[2] = 0x14;
buffer[3] = 0x15;
buffer[4] = 0x16;
buffer[5] = 0x17;
bcm2835_spi_transfern(buffer, 7);
x1 = buffer[1];
x2 = buffer[2];
y1 = buffer[3];
y2 = buffer[4];
z1 = buffer[5];
z2 = buffer[6];
printf("X:%d %d\tY:%d %d\tZ:%d %d\n", x1, x2, y1, y2, z1, z2);
delayms(500);
}
}
我知道问题出在哪里了。显然,为了向传感器发送正确的字节(使用 SPI),您必须对某些地址使用位掩码。这在 BMI088 数据表中未指定。我在用逻辑分析仪检查了 Arduino 发送给传感器的内容后发现了这一点,我还查看了 BMI088 Arduino 库。现在我得到了正确的数据。
在我写下我的问题之前,让我先说一下,我确实访问了互联网上所有关于 RPi4B、SPI、BMI088、bcm2835 库和 C 的相关页面,但没有运气和很多挫折。
我有 6 个 BMI088 传感器,我想通过 SPI 连接到 RPi4B。在 Arduino 上,它与 Bolder Flight 库完美配合(一个或全部 6 个)。问题是当我将传感器连接到 RPi 时,我没有从传感器获得任何信息。连接正常(3.3 V、GND、MISO、MOSI、SCK、CS、PS 接地(仅 BMI088))。我还有一个开关可以打开传感器电源 ON/OFF。我发送的消息与 Arduino 库发送的消息完全相同,但我没有从传感器中得到任何信息,MISO 是无声的。如数据表中所述,我为 CSB1 引脚提供了一个上升沿。如果我连接 MISO 和 MOSI RPi 接收数据。
如何让 BMI088 通过 SPI 与 RPi 通信?
代码(不是全部,只是相关部分):
#include <bcm2835.h>
#include <stdio.h>
#define CS_PIN 25
unsigned char buffer[7] = {0};
int main(int argc, char *argv[])
{
int x1, x2, y1, y2, z1, z2;
if (!bcm2835_init())
{
printf("bcm2835_init failed.\n");
return 1;
}
if (bcm2835_init())
{
printf("bcm2835_init successful.\n");
}
if (!bcm2835_spi_begin())
{
printf("bcm2835_spi_begin failed.\n");
return 1;
}
if (bcm2835_spi_begin())
{
printf("bcm2835_spi_begin successful.\n");
}
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); // The default
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); // The default
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_1); // The default
bcm2835_spi_chipSelect(BCM2835_SPI_CS_NONE); // The default
//bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); // the default
bcm2835_gpio_fsel(CS_PIN, BCM2835_GPIO_FSEL_OUTP); //CS is an output
bcm2835_gpio_clr(CS_PIN);
delayms(100);
while(1)
{
// chip ID
buffer[0] = 0x00; //ACC_CHIP_ID;
//buffer[1] = 30;
bcm2835_spi_transfer(0x00);
bcm2835_delayMicroseconds(100);
bcm2835_gpio_set(CS_PIN);
bcm2835_delayMicroseconds(100);
bcm2835_gpio_clr(CS_PIN);
bcm2835_spi_transfern(buffer, 1);
bcm2835_delayMicroseconds(100);
bcm2835_gpio_set(CS_PIN);
printf("\n\nID:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
delayms(100);
// soft reset
buffer[0] = 0x7E;
buffer[1] = 0xB6;
bcm2835_spi_transfern(buffer, 2);
delayms(100);
printf("RESET:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
delayms(100);
// set power
buffer[0] = 0x7D;
buffer[1] = 0x04;
bcm2835_spi_transfern(buffer, 2);
printf("POWER:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
delayms(100);
// set mode
buffer[0] = 0x7C;
buffer[1] = 0x03;
bcm2835_spi_transfern(buffer, 2);
printf("MODE:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
delayms(100);
// set range
buffer[0] = 0x41;
buffer[1] = 0x03;
bcm2835_spi_transfern(buffer, 2);
printf("RANGE:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
delayms(100);
// set ODR
buffer[0] = 0x40;
buffer[1] = 0xAC;
bcm2835_spi_transfern(buffer, 2);
printf("RANGE:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
delayms(100);
buffer[0] = 0x12;
buffer[1] = 0x13;
buffer[2] = 0x14;
buffer[3] = 0x15;
buffer[4] = 0x16;
buffer[5] = 0x17;
bcm2835_spi_transfern(buffer, 7);
x1 = buffer[1];
x2 = buffer[2];
y1 = buffer[3];
y2 = buffer[4];
z1 = buffer[5];
z2 = buffer[6];
printf("X:%d %d\tY:%d %d\tZ:%d %d\n", x1, x2, y1, y2, z1, z2);
delayms(500);
}
}
我知道问题出在哪里了。显然,为了向传感器发送正确的字节(使用 SPI),您必须对某些地址使用位掩码。这在 BMI088 数据表中未指定。我在用逻辑分析仪检查了 Arduino 发送给传感器的内容后发现了这一点,我还查看了 BMI088 Arduino 库。现在我得到了正确的数据。