我有一个我正在使用的 LCD 屏幕,它要求发送的第一个 spi 数据包长度为 10 位,所有后续数据包长度为 8 位。commands
10位也是如此,位也是如此data
。向设备发送数据必须在同一事务中的命令之后发生。
我尝试了一些利用 的实现,HAL
但它们似乎都在 MOSI 和 CLK 线上引起了一些奇怪的行为。
方法 1:使用 HAL
void set_spi_size_10(SPI_HandleTypeDef *hspi)
{
HAL_SPI_DeInit(hspi);
hspi->Init.DataSize = SPI_DATASIZE_10BIT;
HAL_SPI_Init(hspi);
}
void set_spi_size_8(SPI_HandleTypeDef *hspi)
{
HAL_SPI_DeInit(hspi);
hspi->Init.DataSize = SPI_DATASIZE_8BIT;
HAL_SPI_Init(hspi);
}
void send_data()
{
set_spi_size_10(&hspi2);
HAL_SPI_Transmit(&hspi2, some_buffer, HAL_MAX_DELAY);
set_spi_size_8(&hspi2);
}
方法2:寄存器操作
void set_spi_size_10(SPI_HandleTypeDef *hspi)
{
__HAL_SPI_DISABLE(hspi);
hspi->Init.DataSize = SPI_DATASIZE_10BIT;
uint32_t frxth = SPI_RXFIFO_THRESHOLD_HF;
WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) |
(hspi->Init.TIMode & SPI_CR2_FRF) |
(hspi->Init.NSSPMode & SPI_CR2_NSSP) |
(SPI_DATASIZE_10BIT & SPI_CR2_DS_Msk) |
(frxth & SPI_CR2_FRXTH)));
__HAL_SPI_ENABLE(hspi);
}
void set_spi_size_8(SPI_HandleTypeDef *hspi)
{
__HAL_SPI_DISABLE(hspi);
hspi->Init.DataSize = SPI_DATASIZE_8BIT;
uint32_t frxth = SPI_RXFIFO_THRESHOLD_QF;
WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) |
(hspi->Init.TIMode & SPI_CR2_FRF) |
(hspi->Init.NSSPMode & SPI_CR2_NSSP) |
(SPI_DATASIZE_8BIT & SPI_CR2_DS_Msk) |
(frxth & SPI_CR2_FRXTH)));
__HAL_SPI_ENABLE(hspi);
}
单独使用这些功能时,它们可以正常工作,但是当一个接一个地使用这些功能时,事务不能正常工作。
使用逻辑分析仪,我可以看到初始化/取消初始化时间似乎相当长,并且在重新初始化时会导致 CLK 和 MOSI 线发生意外变化。
如果可能的话,我宁愿不要把数据搞砸,但这是另一种选择。(查看设备制造商的示例,这是他们采用的方法)。
https://www.newhavendisplay.com/specs/NHD-0420DZW-AB5.pdf https://github.com/NewhavenDisplay/NHD-0420DZW_Example/blob/main/NHD-0420DZW_Serial/NHD-0420DZW_Serial.ino