我试图与BlueNRG芯片(在X-NUCLEO-IDB04A1扩展板上)通过SPI协议与STM32L1 (在原子核-L152RE板上)进行通信。
根据BlueNRG 手册,我可以发送一个5字节的空SPI数据包:(0x0B, 0, 0, 0, 0)来获取读/写缓冲区大小以及设备状态。状态应该是0x02 (就绪),或者0x00或0xFF,如果设备处于休眠状态并正在醒来。
下面是我得到的信息:
Send (0x0B, 0, 0, 0, 0)
Receive (0x00, 0x00) // why 2 bytes?
Send (0x0B, 0, 0, 0, 0) // assuming device is waking up, re-trying
Receive (0x06, 0x00) // what is code 6?我的测试应用程序是用锌用Rust编写的。单片机正在运行默认时钟(2048 MHz来自MSI)。下面是负责SPI初始化的代码:
// PB.3 = CLCK
let _spi_clock = pin::Pin::new(pin::PortB, 3,
pin::AltFunction(pin::AfSpi1_Spi2, pin::OutPushPull, pin::Medium),
pin::PullDown);
// PA.6 = MISO
let _spi_in = pin::Pin::new(pin::PortA, 6,
pin::AltFunction(pin::AfSpi1_Spi2, pin::OutPushPull, pin::Medium),
pin::PullNone);
// PA.7 = MOSI
let _spi_out = pin::Pin::new(pin::PortA, 7,
pin::AltFunction(pin::AfSpi1_Spi2, pin::OutPushPull, pin::Medium),
pin::PullNone);
// PA.1 = CS
let spi_csn = pin::Pin::new(pin::PortA, 1,
pin::GpioOut(pin::OutPushPull, pin::Medium),
pin::PullUp);
spi_csn.set_high();
let spi = spi::Spi::new(spi::Spi1, spi::DirFullDuplex, spi::RoleMaster,
spi::Data8b, spi::DataMsbFirst, 1); // baud pre-scaler = 2
let bnrg_reset = pin::Pin::new(pin::PortA, 8,
pin::GpioOut(pin::OutPushPull, pin::VeryLow),
pin::PullUp);
bnrg_reset.set_low();
// do something
bnrg_reset.set_high();SPI内部部件从锌母料中略为修改。发送/接收代码组织如下:
loop {
spi_csn.set_low();
// send a dummy read request
spi.write(SpiRead as u8); // = 0x0B
spi.write(0);
spi.write(0);
spi.write(0);
spi.write(0);
let status = spi.read();
// debug print status
while spi.has_more_data() {
let data = spi.read();
// debug print data
}
spi_csn.set_high();
}问题是-如何解释或处理这些BlueNRG反应?我无法找到它使用的低级协议的任何正式描述(这里不是谈论HCI/ACI,而是0x02 =ready之外的状态代码)。很可能我只是不正确地初始化硬件,甚至遗漏了一些显而易见的东西。如果能提供任何指导的话。
发布于 2014-11-21 09:05:54
SPI驱动程序似乎有一些根本问题。它是否在硬件或软件中有一个缓冲区来存储输入的字节,或者它是如何工作的?通常,您不发送或接收与SPI,您接受全双工。SPI驱动程序本身不可能判断传入的数据是有效的还是垃圾的,因此不存在“当发送5时我只接收2个字节”之类的东西。发送5个字节时总是接收5个字节。
这个应用程序中的MCU将是SPI的主处理器,外部的芯片将是从芯片。对于发送的每一个字节,您也会收到一个字节。这个字节是否有意义取决于外部芯片的工作方式。遗憾的是,目前还没有SPI标准,因此外部芯片可以声明各种延迟要求,例如“在SCK & MOSI启动前必须将从选择拉低x时间单元”。您必须详细阅读外部芯片的手册。
然后,当所有的混乱都解决了,当然,当SPI不能正常工作时,人们通常会怀疑:时钟因为不正确的时钟极性或时钟相位设置而倾斜。
发布于 2018-02-12 08:28:45
请参考ST UM1865,第5章: SPI接口。它适用于BlueNRG(不是BlueNRG),但HCI/ACI接口是相同的。
正如您已经注意到的,第一个字节是SPI就绪指示,0x02表示从SPI接口已经就绪。如果它是0x02以外的任何值,主服务器必须忽略以下4个字节并中止SPI事务。
如果BlueNRG (或-MS) SPI已经准备好(0x02),下面的4个字节为写入和读取提供了2个缓冲区大小:
在您的示例中,{0xb、0、0、0、0}仅用于检查BlueNRG读取缓冲区的大小。类似地,{0xa,0,0,0,0}用于检查写缓冲区的大小。
如果返回的大小不是0,就像在您的示例{0x6,0}中一样,我假设它应该是{0x6,0,0,0},这意味着BlueNRG已经准备好读取6 (0 << 8,0)字节的数据。然后,您将尽快从BlueNRG读取6个字节。
请参考C:\Program (x86)\STMicroelectronics\BlueNRG 2.0.2\Projects\Drivers\BSP\STM32L1xx_BlueNRG\SDK_EVAL_Spi_Driver.c函数BlueNRG_SPI_Read_All()。
https://stackoverflow.com/questions/27053902
复制相似问题