STM32通过I2C控制LCD1602显示


硬件平台:
NUCLEO-STM32F411RE+PCF8574+LCD1602
注意:显示屏背光亮但不显示可能因为对比度不足,可通过电位器调节

I2C简介

I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。 它只需要两根线即可在连接于总线上的器件之间传送信息。 主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件. 在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。
连接方式如下:
在这里插入图片描述
帧地址:I2C总线上的每个设备都有自己的独立地址,主机发起通讯时,通过SDA信号线发送设备地址(SLAVE_ADDRESS)来查找从机。I2C协议规定设备地址可以是7位或10位,实际中7位的地址应用比较广泛。
在这里插入图片描述
以主机向从机写数据为例,其基本结构如图所示,依次为:
起始信号——从机地址——读写信号——数据位——应答位——… … ——停止位
在这里插入图片描述
I2C使用SDA信号线来传输数据,使用SCL信号线进行数据同步。SDA数据线在SCL的每个时钟周期传输一位数据。传输时,SCL为高电平的时候SDA表示的数据有效,即此时的SDA为高电平时表示数据“1”,为低电平时表示数据“0”。当SCL为低电平时,SDA的数据无效,一般在这个时候SDA进行电平切换,为下一次表示数据做好准备。

I2C的数据和地址传输都带响应。响应包括“应答(ACK)”和“非应答(NACK)”两种信号。

作为数据接收端时,当设备(无论主从机)接收到I2C传输的一个字节数据或地址后,若希望对方继续发送数据,则需要向对方发送“应答(ACK)”信号,发送方会继续发送下一个数据;若接收端希望结束数据传输,则向对方发送“非应答(NACK)”信号,发送方接收到该信号后会产生一个停止信号,结束信号传输。

HAL函数介绍

Function name

HAL_StatusTypeDef HAL_I2C_Master_Transmit (I2C_HandleTypeDef * hi2c, uint16_t 

DevAddress, uint8_t * pData, uint16_t Size, uint32_t Timeout)
Function description
Transmits in master mode an amount of data in blocking mode.
Parameters
• hi2c: Pointer to a I2C_HandleTypeDef structure that contains the configuration information for the specified I2C.
• DevAddress: Target device address: The device 7 bits address value in datasheet must be shifted to the left before calling the interface
• pData: Pointer to data buffer
• Size: Amount of data to be sent
• Timeout: Timeout duration
Return values
• HAL: status

Function name

HAL_StatusTypeDef HAL_I2C_Master_Receive (I2C_HandleTypeDef * hi2c, uint16_t 

DevAddress, uint8_t * pData, uint16_t Size, uint32_t Timeout)
Function description
Receives in master mode an amount of data in blocking mode.
Parameters
• hi2c: Pointer to a I2C_HandleTypeDef structure that contains the configuration information for the specified I2C.
• DevAddress: Target device address: The device 7 bits address value in datasheet must be shifted to the left before calling the interface
• pData: Pointer to data buffer
• Size: Amount of data to be sent
• Timeout: Timeout duration
Return values
• HAL: status

PCF8574+LCD1602介绍

IO扩展:PCF8574

PCF8574是一款并口扩展芯片,它与主控芯片通过IIC接口进行通讯。芯片管脚定义如下:
在这里插入图片描述
接线如下:
在这里插入图片描述
PCF8574地址使用手册定义如下:
在这里插入图片描述
查询硬件地址很简单,如果PCF8574背面对应接口被短接就是0,否则1

LCD1602

LCD1602的控制芯片(MCU)是HD44780。控制模式有两种-8位模式和4位模式,本文使用4位模式。
功能简介:
Clear Display
Clear display writes space code 20H (character pattern for character code 20H must be a blank pattern) into all DDRAM addresses. It then sets DDRAM address 0 into the address counter, and returns the display to its original status if it was shifted. In other words, the display disappears and the cursor or blinking goes to the left edge of the display (in the first line if 2 lines are displayed). It also sets I/D to 1 (increment mode) in entry mode. S of entry mode does not change.
Return Home
Return home sets DDRAM address 0 into the address counter, and returns the display to its original status if it was shifted. The DDRAM contents do not change.
The cursor or blinking go to the left edge of the display (in the first line if 2 lines are displayed).
Entry Mode Set
I/D: Increments (I/D = 1) or decrements (I/D = 0) the DDRAM address by 1 when a character code is written into or read from DDRAM.
The cursor or blinking moves to the right when incremented by 1 and to the left when decremented by 1. The same applies to writing and reading of CGRAM.
S: Shifts the entire display either to the right (I/D = 0) or to the left (I/D = 1) when S is 1. The display does not shift if S is 0.
If S is 1, it will seem as if the cursor does not move but the display does. The display does not shift when reading from DDRAM. Also, writing into or reading out from CGRAM does not shift the display.
Display On/Off Control
D: The display is on when D is 1 and off when D is 0. When off, the display data remains in DDRAM, but
can be displayed instantly by setting D to 1.
C: The cursor is displayed when C is 1 and not displayed when C is 0. Even if the cursor disappears, the function of I/D or other specifications will not change during display data write. The cursor is displayed using 5 dots in the 8th line for 5 × 8 dot character font selection and in the 11th line for the 5 × 10 dot character font selection.
B: The character indicated by the cursor blinks when B is 1. The blinking is displayed as switching between all blank dots and displayed characters at a speed of 409.6-ms intervals when fcp or fOSC is 250 kHz. The cursor and blinking can be set to display simultaneously. (The blinking frequency changes according to fOSC or the reciprocal of fcp. For example, when fcp is 270 kHz, 409.6 × 250/270 = 379.2 ms.)
Cursor or Display Shift
Cursor or display shift shifts the cursor position or display to the right or left without writing or reading display data. This function is used to correct or search the display. In a 2-line display, the cursor moves to the second line when it passes the 40th digit of the first line. Note that the first and second line displays will shift at the same time.
When the displayed data is shifted repeatedly each line moves only horizontally. The second line display does not shift into the first line position.
The address counter (AC) contents will not change if the only action performed is a display shift.
Function Set
DL: Sets the interface data length. Data is sent or received in 8-bit lengths (DB7 to DB0) when DL is 1, and in 4-bit lengths (DB7 to DB4) when DL is 0.When 4-bit length is selected, data must be sent or received twice.
N: Sets the number of display lines.
F: Sets the character font.
Note: Perform the function at the head of the program before executing any instructions (except for the read busy flag and address instruction). From this point, the function set instruction cannot be executed unless the interface data length is changed.
Set CGRAM Address
Set CGRAM address sets the CGRAM address binary AAAAAA into the address counter. Data is then written to or read from the MPU for CGRAM.
4位模式初始化如下:
在这里插入图片描述

具体实现

CubeMX设置

I2C:
在这里插入图片描述
时钟设置:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

代码

创建文件i2c-lcd.h:

#include "stm32f4xx_hal.h"
void lcd_init (void);   // initialize lcd
void lcd_send_cmd (char cmd);  // send command to the lcd
void lcd_send_data (char data);  // send data to the lcd
void lcd_send_string (char *str);  // send string to the lcd
void lcd_put_cur(int row, int col); // put cursor at the entered position rol(0 or 1), col(0 - 15)
void lcd_clear (void);

创建文件i2c-lcd.c:

#include "i2c-lcd.h"
#include "main.h"

extern I2C_HandleTypeDef hi2c1;  // change your handler here accordingly
#define SLAVE_ADDRESS_LCD  0x4E // change this according to ur setup

void lcd_send_cmd (char cmd){
	char data_u, data_l;
	uint8_t i2c_frame_data[4];
	data_u = (cmd&0xf0);
	data_l = ((cmd<<4)&0xf0);
	i2c_frame_data[0] = data_u|0x0C;  //en=1, rs=0
	i2c_frame_data[1] = data_u|0x08;  //en=0, rs=0
	i2c_frame_data[2] = data_l|0x0C;  //en=1, rs=0
	i2c_frame_data[3] = data_l|0x08;  //en=0, rs=0
	HAL_I2C_Master_Transmit(&hi2c1, SLAVE_ADDRESS_LCD, (uint8_t *) i2c_frame_data, 4, 100);
	HAL_Delay(1);
}

void lcd_send_data (char data){
	char data_u, data_l;
	uint8_t i2c_frame_data[4];
	data_u = (data&0xf0);
	data_l = ((data<<4)&0xf0);
	i2c_frame_data[0] = data_u|0x0D;  //en=1, rs=0
	i2c_frame_data[1] = data_u|0x09;  //en=0, rs=0
	i2c_frame_data[2] = data_l|0x0D;  //en=1, rs=0
	i2c_frame_data[3] = data_l|0x09;  //en=0, rs=0
	HAL_I2C_Master_Transmit(&hi2c1, SLAVE_ADDRESS_LCD, (uint8_t *) i2c_frame_data, 4, 100);
	HAL_Delay(1);
}

void lcd_clear (void){
	lcd_send_cmd (0x01);  // clear display
	HAL_Delay(1);
}

void lcd_put_cur(int row, int col){
	switch(row){
	case 0:
		col |= 0x80;
		break;
	case 1:
		col |= 0xC0;
		break;
	}
	lcd_send_cmd(col);
}

void lcd_init (void){
    // 4-bit mode initialization
	HAL_Delay(50); // wait for >40ms
	lcd_send_cmd(0x30);
	HAL_Delay(5); // wait for > 4.1ms
	lcd_send_cmd(0x30);
	HAL_Delay(1); // wait for >100us
	lcd_send_cmd(0x30);
	HAL_Delay(10);
	lcd_send_cmd(0x20); // 4-bit mode
	HAL_Delay(10);
    // display initialization
	lcd_send_cmd(0x28); // Function set --> DL = 0 (4-bit mode), N = 1 (2 line display), F = 0 (5x8 characters)
	HAL_Delay(1);
	lcd_send_cmd(0x08); // Display on/off control --> D = 0, C = 0, B = 0 --> display off
	HAL_Delay(1);
	lcd_send_cmd(0x01); // clear display
	HAL_Delay(1);
	lcd_send_cmd(0x06); // Enter mode set --> I/D = 1 (increment cursor) & S = 0 (no shift)
	HAL_Delay(1);
	lcd_send_cmd(0x0E); // Display on /off control --> D = 1, C = 1, B = 0

	HAL_Delay(1);
}

void lcd_send_string (char *str){
    while(*str){lcd_send_data(*str++);}
	HAL_Delay(1);
}

main.c:

  lcd_init();
  lcd_send_string("Hello World!");
  HAL_Delay(1000);
  lcd_put_cur(1, 0);
  lcd_send_string("from Cedr1c");
  • 32
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 要将STM32F103C8T6连接到LCD1602I2C),需要进行以下步骤: 1. 硬件连接:将STM32F103C8T6的SCL引脚连接到LCD1602的SCL引脚,将STM32F103C8T6的SDA引脚连接到LCD1602的SDA引脚。同时,将STM32F103C8T6的VCC引脚连接到LCD1602的VCC引脚,将STM32F103C8T6的GND引脚连接到LCD1602的GND引脚。 2. 软件配置:在STM32F103C8T6的开发环境中,打开I2C总线的相关配置。配置I2C总线的主设备地址和时钟频率等参数。 3. 初始化LCD1602使用相应的库文件或编写代码初始化LCD1602。初始化过程中,需要对LCD1602发送一系列命令来设置显示模式、光标等。 4. 发送数据:使用I2C总线将要显示的数据发送给LCD1602。将数据传输到I2C总线发送缓冲区,然后通过I2C总线发送给LCD1602。 5. 显示内容:通过发送特定的命令,控制LCD1602显示数据、光标等内容。 需要注意的是,在进行连接和操作过程中,要仔细检查引脚连接是否准确,确保电路连接正确。另外,对于STM32F103C8T6和LCD1602I2C通信协议需按照具体的硬件规格手册进行配置和操作。 ### 回答2: 连接STM32F103C8T6和LCD1602I2C)需要使用I2C(Inter-Integrated Circuit)总线进行通信。下面是连接步骤: 步骤1:硬件连接 将STM32F103C8T6的PB6引脚连接到LCD1602的串行数据(SDA)引脚。 将STM32F103C8T6的PB7引脚连接到LCD1602的串行时钟(SCL)引脚。 在STM32F103C8T6和LCD1602之间连接电源和地线。 步骤2:配置I2C总线 打开STM32CubeIDE(或其他STM32开发环境)创建一个新工程。 在工程中选择正确的STM32F103C8T6型号和I2C外设。 配置I2C总线的时钟速度和其他参数。 步骤3:编写代码 在主函数中初始化I2C总线。 设置LCD1602I2C地址。 发送初始化命令以配置LCD1602。 通过I2C发送数据和命令以在LCD屏幕上显示字符和执行其他操作。 步骤4:编译和下载 编译项目并生成可执行文件。 使用烧录器将可执行文件下载到STM32F103C8T6开发板上。 步骤5:运行 上电并运行程序,STM32F103C8T6将通过I2C总线与LCD1602进行通信,并在屏幕上显示字符等信息。 以上是连接STM32F103C8T6和LCD1602I2C)的基本步骤。请记得根据实际情况进行适当调整和修改。 ### 回答3: 连接STM32F103C8T6与LCD1602I2C)涉及以下几个方面: 1. 硬件连接: 首先,将STM32F103C8T6的VCC引脚连接到LCD1602的VCC引脚,将GND引脚连接到GND引脚。 然后,将STM32F103C8T6的PB8引脚连接到LCD1602的SDA引脚,将PB9引脚连接到LCD1602的SCL引脚。 最后,将STM32F103C8T6的VCC引脚通过一个10K电阻连接到LCD1602的VCC引脚,以供电源。 2. 软件配置: 在编程环境中打开STM32F103C8T6的工程,进入配置选项。 启用I2C模块并将其配置为合适的速率(如100kHz)。 配置GPIO引脚PB8和PB9作为I2C外设功能,并选择合适的I2C引脚映射。 在编程代码中包含I2CLCD1602的库函数。 3. 编写代码: 初始化I2C模块,设置I2C的地址、速率等参数。 初始化LCD1602,设置数据线、显示模式、光标等参数。 编写LCD1602显示内容的函数。 在主函数中调用LCD1602显示函数,实现特定的显示效果。 4. 测试与调试: 烧录程序到STM32F103C8T6开发板上,确保连接正确。 打开电源,观察LCD1602是否显示预期的内容。 如有需要,进行调试并修正代码或硬件连接。 通过以上步骤,STM32F103C8T6可以成功连接到LCD1602I2C),并能够通过编程控制LCD1602显示所需的内容。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值