SSD1803 是一个用于控制 LCD 显示器的控制器。我使用 SPI 与控制器通信,这对于正常指令来说效果很好:我可以在显示屏上打印文本、清除显示屏、在 RAM 中存储自定义字符、设置光标等。
但现在我想读取忙碌标志(
BF
),它无法正常工作->包含BF
的字节总是返回0
。
使用说明 | 重新 | RS | 右/右 | DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 | 执行时间 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
清晰显示 | X | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1.53ms |
就绪繁忙标志和地址/部件 ID | X | 0 | 1 | BF | AC6/ID6 | AC5/ID5 | AC4/ID4 | AC3/ID3 | AC2/ID2 | AC1/ID1 | AC0/ID0 | 0us |
BF = 1
:忙碌状态BF = 0
:就绪状态
SSD1803 数据表 第 12 页29
SSD1803 数据表 第 12 页27
时钟频率为
312.5kHz
,在控制器的外部时钟范围内:
SSD1803 数据表 第 12 页57
int LCDInstrHandler(void)
{
// Clear Display
• HAL_GPIO_WritePin(SPI_LCD_NSS_GPIO_Port, SPI_LCD_NSS_Pin, GPIO_PIN_RESET);
uint8_t tDataClear[3] = {0b11111000, 0b10000000, 0b00000000};
HAL_StatusTypeDef tClearState = HAL_SPI_Transmit(&SPI_LCD, tDataClear, 3, 1000);
HAL_GPIO_WritePin(SPI_LCD_NSS_GPIO_Port, SPI_LCD_NSS_Pin, GPIO_PIN_SET);
// Read Busy Flag
uint8_t tDataBF[2] = {0b11111100, 0x00};
uint8_t tRecBuf[2];
HAL_GPIO_WritePin(SPI_LCD_NSS_GPIO_Port, SPI_LCD_NSS_Pin, GPIO_PIN_RESET);
HAL_StatusTypeDef tBFState = HAL_SPI_TransmitReceive(&SPI_LCD, tDataBF, tRecBuf, 2, 1000);
HAL_GPIO_WritePin(SPI_LCD_NSS_GPIO_Port, SPI_LCD_NSS_Pin, GPIO_PIN_SET);
• return 0;
}
•
=断点
默认情况下,显示屏上有文字,初始化后会打印该文字。之后函数
LCDInstrHandler
被调用。 MSB First
。意味着左边的位先发送,当我收到一个字节时,左边的位是从机发送的第一个位。
为了测试繁忙标志是否有效,我发送了清除显示指令,该指令需要1.53ms。这有效:我的显示被清除。之后,我发送带有
RS = 0
和 R/W = 1
的起始字节,这告诉 SSD1803 控制器返回一个包含 BF
中的 DB7
的字节(请参阅命令表)。
第一个断点和第二个断点之间的时间为150us(用示波器测量)。表示
BF
指令及时执行,因此BF
应该是1
,因为SSD1803控制器仍在执行清除显示指令。
我得到了什么:
tRecBuf
:{0, 0}
tClearState
,tBFState
:HAL_OK
我所期待的
tRecBuf
:{0, 0bxxxxxxx1}
1
:BF
(DB7
) 作为 LSBxxxxxxx
:AC0-AC6
LCD控制器的SOD线可能没有连接到您的MCU。事实上,您读取到的全是 0,这可能意味着它在分线板上连接得很低。大多数出售的显示器分线 PCB 都不需要连接 MISO/SOD 线,因为显示器实际上是只写设备。老实说,很少有人费心从这些小显示器上阅读任何内容,因为这是没有必要的。如果您担心发送清除命令后显示屏正忙,请在代码中添加 1.53 毫秒的延迟,以确保您不会尝试太快写入。如果您绝对需要读取状态标志,请制作自己的 LCD 分线 PCB,正确连接所有信号线(如今使用 KiCad 和 JLCPCB 等制造商并不是很困难)。