lcd1602显示字符串(stm32+hal+lcd1602)

一、lcd1602说明
       是一种字符型液晶显示模块,不能显示汉字。

        有16个引脚,如下:

        我们在代码中使用了11个引脚,如上图红色标记,分别是:

        RS:区分命令和数据,0表示命令,1表示数据
        RW:读写区分,1读,0写
        E:使能位,高电平使能

        DB0-DB7:数据或命令

二、stm32芯片的引脚分别与lcd1602的11个引脚相连,使用stm32CubeMX软件进行初始化工程,我的连接如下图

        引脚都配置成输出模式,并取别名,建议以lcd1602引脚名来命名,方便记忆:

        当然还需要配置时钟、下载方式、工程属性等,最后自动生成初始化代码。

三、使用keil软件打开工程,并添加文件lcd1602.c、lcd1602.c,加入到工程

lcd1602.c代码如下

#include "lcd1602.h"

//内部函数,写一个字节显示数据
void WriteByteData(char c)
{
	RS_H();
	RW_L();
	E_L();
	//将c的8个bit位分别放到DB0到DB7
	HAL_GPIO_WritePin(GPIOB,DB0_Pin,(GPIO_PinState)(c&0x01));
	HAL_GPIO_WritePin(GPIOB,DB1_Pin,(GPIO_PinState)((c>>1)&0x01));
	HAL_GPIO_WritePin(GPIOB,DB2_Pin,(GPIO_PinState)((c>>2)&0x01));
	HAL_GPIO_WritePin(GPIOB,DB3_Pin,(GPIO_PinState)((c>>3)&0x01));
	HAL_GPIO_WritePin(GPIOB,DB4_Pin,(GPIO_PinState)((c>>4)&0x01));
	HAL_GPIO_WritePin(GPIOC,DB5_Pin,(GPIO_PinState)((c>>5)&0x01));
	HAL_GPIO_WritePin(GPIOC,DB6_Pin,(GPIO_PinState)((c>>6)&0x01));
	HAL_GPIO_WritePin(GPIOC,DB7_Pin,(GPIO_PinState)((c>>7)&0x01));
	//补充完整代码
	E_H();
	HAL_Delay(1);
	E_L();
}
//内部函数,写一个字节命令
void WriteByteCmd(char c)
{
	RS_L();
	RW_L();
	E_L();
	//将C的8个bit位分别放到DB0到DB7
	HAL_GPIO_WritePin(GPIOB,DB0_Pin,(GPIO_PinState)(c&0x01));
	HAL_GPIO_WritePin(GPIOB,DB1_Pin,(GPIO_PinState)((c>>1)&0x01));
	HAL_GPIO_WritePin(GPIOB,DB2_Pin,(GPIO_PinState)((c>>2)&0x01));
	HAL_GPIO_WritePin(GPIOB,DB3_Pin,(GPIO_PinState)((c>>3)&0x01));
	HAL_GPIO_WritePin(GPIOB,DB4_Pin,(GPIO_PinState)((c>>4)&0x01));
	HAL_GPIO_WritePin(GPIOC,DB5_Pin,(GPIO_PinState)((c>>5)&0x01));
	HAL_GPIO_WritePin(GPIOC,DB6_Pin,(GPIO_PinState)((c>>6)&0x01));
	HAL_GPIO_WritePin(GPIOC,DB7_Pin,(GPIO_PinState)((c>>7)&0x01));
	//补充完整代码
	E_H();
	HAL_Delay(1);
	E_L();
}
//初始化函数定义
void lcd1602_init(void)
{
	WriteByteCmd(0x38);//8个数据线,显示两行,5*7点阵
	WriteByteCmd(0x0C);//显示功能打开0x0c
	WriteByteCmd(0x06);//光标自动右边移动0x06
	WriteByteCmd(0x01);//清屏0x01
}
//内部函数:设置显示的起始地址
int setAddr(int row,int col)
{
	char addr;
	if(row == 0)
		addr = 0x80+col;
	else if(row == 1)
		addr = 0x80+0x40+col;
	else
		return -1;
	WriteByteCmd(addr);
	return 0;
}

//写字符串函数定义
void ShowString(int row,int col,char data[])
{
	//定位
	int ret = setAddr(row,col);
	if(ret !=0)
		return ;
	char *p = data;
	while(*p)
	{
		WriteByteData(*p);
		p++;
	}
}

//清屏函数定义
void clearScreen(void)
{
	WriteByteCmd(0x01);//清屏0x01
}

lcd1602.h代码:

#ifndef __LCD1602_H__
#define __LCD1602_H__
#include "main.h"

#define RS_H()  HAL_GPIO_WritePin(GPIOC,RS1602_Pin,GPIO_PIN_SET)
#define RS_L()  HAL_GPIO_WritePin(GPIOC,RS1602_Pin,GPIO_PIN_RESET)
#define RW_H()  HAL_GPIO_WritePin(GPIOA,RW1602_Pin,GPIO_PIN_SET)
#define RW_L()  HAL_GPIO_WritePin(GPIOA,RW1602_Pin,GPIO_PIN_RESET)
#define E_H()  HAL_GPIO_WritePin(GPIOB,E1602_Pin,GPIO_PIN_SET)
#define E_L()  HAL_GPIO_WritePin(GPIOB,E1602_Pin,GPIO_PIN_RESET)
//初始化函数声明
void lcd1602_init(void);
//显示字符串函数声明
void ShowString(int row,int col,char data[]);
//清屏函数声明
void clearScreen(void);

#endif

main函数中添加lcd1602头文件,然后添加代码如下:

#include "lcd1602.h"

四、编译、烧写代码,然后观察现象

五、代码解析

1)写时序如下:

如下图可以看出,使能的持续实践至少是tpw,为150纳秒,HAL库函数没有提供到纳秒的延时(可以自己写),我们就延时一毫秒,时间是足够的。

根据上两张图,完成代码如下所示:

2)lcd1602显示的每个位置都有地址,将光标指向那个地址就在那显示数据

所以上面每个字符的显示位置要加上0x80。说明一下,由于我们是芯片向lcd1602写数据显示,所以检查忙的动作可以不用做。
根据上面写出代码:

3)stm32与lcd1602,总共要用到11个引脚,在芯片资源比较紧张的情况下,可以4条数据线进行数据或命令传输,传输一个字节信息需要传两次,这种情况需要借助于HD44780来完成。

### 使用 HAL 库驱动 LCD1602 显示屏 为了使用 HAL 库来驱动 LCD1602 显示屏,通常需要通过 I2C 或者 4/8-bit 数据总线接口与 LCD 进行通信。下面提供了一个基于 I2C 接口的例子。 #### 初始化硬件资源 首先,在初始化阶段配置好 GPIO 和 I2C 外设参数: ```c // 定义I2C地址以及LCD命令集 #define LCD_I2C_ADDR (0x27 << 1) // 假定LCD模块的I2C地址为0x27 #define CMD_CLEAR 0x01 // 清除显示指令 #define CMD_HOME 0x02 // 返回起始位置指令 ... void MX_GPIO_Init(void); void MX_I2C1_Init(void); int main(void){ HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); // 配置GPIO端口用于控制背光灯等辅助功能 MX_I2C1_Init(); // 初始化I2C外设 LcdInit(); // 调用自定义函数完成LCD初始化设置 while(1){ ... } } ``` #### 编写 LCD 控制函数 接着编写几个基本的操作函数,比如发送数据、发送命令给 LCD 屏幕: ```c #include "stm32f1xx_hal.h" static void LcdWriteByte(uint8_t data, uint8_t mode){ uint8_t buffer[2]; buffer[0] = RS | EN; if(mode == DATA_MODE){buffer[0]|=RS;} buffer[1]=data; HAL_I2C_Master_Transmit(&hi2c1,LCD_I2C_ADDR,buffer,sizeof(buffer),HAL_MAX_DELAY); } void LcdSendCommand(uint8_t cmd){ LcdWriteByte(cmd,CMD_MODE); DelayMs(2); // 短暂延时等待执行完毕 } void LcdSendData(uint8_t dat){ LcdWriteByte(dat,DATA_MODE); } void LcdClear(){ LcdSendCommand(CMD_CLEAR); DelayMs(2); } void LcdHome(){ LcdSendCommand(CMD_HOME); DelayMs(2); } ... ``` 以上代码片段展示了如何利用 STM32HAL 库实现对 LCD1602 的基础操作[^1]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值