首页 > 解决方案 > f3discovery:尝试使用带有 I2C 模块的 lcd 屏幕 1602

问题描述

我正在尝试在我的 stm32F3discovery 上使用液晶屏。屏幕由 2 行 16 个字符的 lcd 和一个 I2C 模块组成。

这是产品的链接: https ://www.aliexpress.com/item/32763867041.html?spm=a2g0s.9042311.0.0.27424c4dsV7dLS

在屏幕背面我可以看到写着:QAPASS 1602A 在 I2C 模块的芯片上我可以看到写着:PCF8574T

这是芯片的数据表: https ://www.nxp.com/docs/en/data-sheet/PCF8574_PCF8574A.pdf

我试图按照这个教程(最接近我想要做的事情): https ://www.youtube.com/watch?v=1COFk1M2tak

我使用 HAL 库,发送数据的主要函数是“HAL_I2C_Master_Transmit”。

以下是“HAL_I2C_Master_Transmit”中函数的说明:

HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)

//I initialise a buffer
//I use a for loop to find the address of my slave: 0x3D (even tho on the //datasheet it's 0x3F, looks like A1 is bridged :O )
//I use the HAL_I2C_Master_Transmit function
//I move the address one bit to the left
//I reuse the HAL_I2C_Master_Transmit
//Nothing happens on the screen

//Here is my code (I tried to remove the useless comments):

#include "main.h"

I2C_HandleTypeDef hi2c1; // Init generated bu CubeMX
SPI_HandleTypeDef hspi1; // Init generated bu CubeMX
PCD_HandleTypeDef hpcd_USB_FS; // Init generated bu CubeMX

uint16_t adresseLCD; // the variable I put the slave address on
uint8_t buffer[]="123"; // The buffer I wanna see on the screen

void SystemClock_Config(void); // Generated by CubeMX
static void MX_GPIO_Init(void); // Generated by CubeMX
static void MX_I2C1_Init(void); // Generated by CubeMX
static void MX_SPI1_Init(void); // Generated by CubeMX
static void MX_USB_PCD_Init(void); // Generated by CubeMX

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_I2C1_Init();
    MX_SPI1_Init();
    MX_USB_PCD_Init();

    adresseLCD=0x3D;
    HAL_I2C_Master_Transmit(&hi2c1, adresseLCD, buffer, 1, 1000);

    adresseLCD=adresseLCD*2; // Yes I could have used "adresseLCD<<1" but I 
    //am not used to that
    HAL_I2C_Master_Transmit(&hi2c1, adresseLCD, buffer, 1, 1000);

    while(1)
    {
    }
}

我希望屏幕上会显示一些东西(甚至是随机值),但什么也没有出现(虽然它会亮起)。我没有收到错误(只有警告,因为我在 WritePIn 时使用“1”而不是“Pin_ON”)

标签: cstm32i2chal

解决方案


你期望它是错误的。

首先是背面焊接的I2C模块,它只是一个简单的串并转换器。当您在 I2C 总线上写入数据时,它会根据数据字节中的 8 个接收位设置其 8 个输出。当您读取数据字节时,它会切换到输入模式并读取 8 个引脚上的逻辑电平并通过串行线传输。您可以在您提供的 PCF8574 数据表中阅读更详细的说明。

即这部分不执行任何“魔术”,它将在输入时获取字符并在显示器上输出它们。这意味着随机数据的输出是徒劳的。

你还需要知道两件事:

  1. 该模块如何连接到显示驱动程序
  2. 使用什么样的显示驱动程序以及如何使用它。

第一个问题的答案可以在网上找到:( I2C液晶模组原理图摘自这里

您可以看到显示器以 4 位模式连接,输出P4-P7(即您在数据字节的四个最高有效位中传输的内容)连接到显示器的数据线,而输出P0-P2连接到控制线RS , R/W , EHP3用于控制背光。

知道了这一点,我们来到了第二个问题。我只能建议,但您的显示模块上更有可能装有 Hitachi HD44780 IC。在上面的数据表中,您可以找到应该在控制线上输出哪些数据的信息。

您可以在第 8 页找到引脚说明:

  • RS选择命令 (0) 或数据 (1)
  • R/W选择写操作 (0) 或读 (1)
  • 而位E实际上是一个频闪灯。在下降沿,即从 1 变为 0 时,显示驱动器从数据线读取数据。这意味着要传递 4 位数据,您应该执行 2 次写入操作:第一个位 2 设置为高,第二个位与所有其他位相同,但位 2 为零。

现在您可以阅读数据表第 25 页的指令列表。4 位模式的初始化序列在第 46 页(图 24)。请注意,对于每一行位,您实际上发送了 2 个数据字节:位 2 高,然后位 2 低。

请注意,在 4 位模式下,所有命令和数据都包含两个写入阶段:第一个 - 上半部分,然后是一个字节的下半部分。每个阶段是 2 次数据写入 I2C 模块,E 位高低,即您需要发送 4 个字节才能输出 1 个字节的数据。


推荐阅读