工具/软件:
目前、我有 5 个 SPI 器件连接到 MCU:
- 2xADS8900B ADC
- AD5293 数字电位计
- FM25V02A FRAM 存储
- 连接到 CM SSI 的基于 BT815 的显示模块。
所有这些都有相同的问题:
根据数据表、所有器件都在 SPI 模式 0 (CPOL=0、CPHA=0) 下运行、但 AD5293 除外、它是模式 1 (CPOL=0、CPHA=1) 器件。
因此、当我将 SPI 端口配置为这些设置时、除 BT815 之外、什么都不起作用、至少它接受发送的数据。
因此、我将 SPI 端口的设置更改为相反的设置、AD5293 的模式 0 和其他端口的模式 1。 此后、所有器件都接受命令。 但是:
当我从器件读回数据时、它会移位 1 位! AD5293 正常、因为不需要读取它。
因此对于 BT815、我在读取前将 SSI 端口更改为模式 1、之后将更改为模式 0。
对于 SPI 端口上的其他 3 个器件、我在读取前将 SPI 端口更改为模式 0、然后重新更改为模式 1。
因此、除 AD5293 外、所有 SPI 器件的常见工作流程是:
(无论器件是模式 0、端口都初始配置为模式 1)
- 发送命令
- 更改为 MODE 0
- 读取响应
- 更改为模式 1
现在一切都正常。 但这是奇怪的!
适用于 FRAM 的代码为:
static void SPI_setReadMode(bool read)
{
SPI_disableModule(FRAM_SPI_BASE);
SPI_setConfig(FRAM_SPI_BASE, DEVICE_LSPCLK_FREQ, read ? SPI_PROT_POL0PHA0 : SPI_PROT_POL0PHA1,
SPI_MODE_CONTROLLER, FRAM_SPI_BITRATE, FRAM_SPI_DATAWIDTH);
SPI_setPTESignalPolarity(FRAM_SPI_BASE, SPI_PTE_ACTIVE_LOW);
SPI_enableModule(FRAM_SPI_BASE);
}
void FRAM_Read(uint32_t addr, void *buf, uint32_t len) {
FRAM_CS_LOW();
SPI_WriteByte(FRAM_SPI_HANDLE, 0x03); // READ
SPI_WriteByte(FRAM_SPI_HANDLE, (addr >> 8) & 0xFF);
SPI_WriteByte(FRAM_SPI_HANDLE, addr & 0xFF);
uint8_t *p = (uint8_t*)buf;
uint32_t i;
SPI_setReadMode(true);
for (i = 0; i < len; i += 2)
{
uint8_t w = SPI_ReadByte(FRAM_SPI_HANDLE);
p[i / 2] = w << 8;
w = SPI_ReadByte(FRAM_SPI_HANDLE);
p[i / 2] |= w;
}
while (SPI_isBusy(FRAM_SPI_HANDLE));
FRAM_CS_HIGH();
SPI_setReadMode(false);
}
对于 CM 上的 BT815:
void HAL_SPI_ReadBuffer(uint8_t *Buffer, uint32_t Length)
{
HAL_SPI_Write(0);
SSI_disableModule(SSI0_BASE);
SSI_setConfig(SSI0_BASE, CM_CLK_FREQ, SSI_FRF_MOTO_MODE_1, SSI_MODE_MASTER, 12000000, 8);
SSI_enableModule(SSI0_BASE);
for(; Length; Buffer++, Length--)
{
*Buffer = HAL_SPI_Write(0);
}
SSI_disableModule(SSI0_BASE);
SSI_setConfig(SSI0_BASE, CM_CLK_FREQ, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 12000000, 8);
SSI_enableModule(SSI0_BASE);
}
使用此代码时、示波器显示 SPI 线路上的覆盖正常、但没有移动 1 位。
更改端口的比特率不会影响此行为。 (数据表中 FRAM 芯片的比特率为 40MHz、我尝试将其降低到 400kHz,结果相同)。
我之前在 F2837x 器件上注意到了相同的问题。
重要声明
我稍后会附加示波器截图、因为现在我不在设备上、但示波器在所有设备的模式 0 和 AD5293 的模式 1 中都显示了正确的数据。
因此、这个问题在 MCU 的 SPI/SSI 硬件中是有限的。

