c - f3发现: trying to use an lcd screen 1602 with an I2C module

标签 c stm32 i2c hal

我正在尝试在我的 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”中函数的说明:

  • @brief 在主模式下以阻塞模式传输一定量的数据。
  • @param hi2c 指向 I2C_HandleTypeDef 结构的指针,该结构包含指定 I2C 的配置信息。
  • @param DevAddress 目标设备地址:调用接口(interface)前必须将数据表中的设备7位地址值左移
  • @param pData 指向数据缓冲区的指针
  • @param Size 要发送的数据量
  • @param Timeout 超时持续时间
  • @retval HAL 状态

HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t 大小, uint32_t 超时)

//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”)

最佳答案

你的预期是错误的。

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

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

您还需要了解两件事:

  1. 该模块如何连接到显示驱动程序
  2. 使用哪种显示驱动程序以及如何使用它。

第一个问题可以在网上找到答案: I2C LCD module schematic (摘自here)

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

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

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

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

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

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

关于c - f3发现: trying to use an lcd screen 1602 with an I2C module,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56668846/

相关文章:

arm - ARM (Cortex M3) 的应用程序内编程如何工作?

STM32 HAL_I2C_Master_Transmit - 为什么我们需要移位地址?

C:检查字符串是否是回文

c - 使用 GSList 作为 GHashTable 值的不同方法

c - 为什么 malloc 似乎允许我在内存上写入?

c++ - C/C++ 中的跨平台自定义文件头

debugging - 使用arm-none-eabi-gdb和openocd轻松访问外设

c - STM32上的ADC单次转换

c - 如何在 TM4C123GXL (Tiva) Launchpad 上使用 I2C

I2C 无法在带有 MicroPython 的 Raspberry Pi Pico W 上工作