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来完成。

作者:蓉城儿女

物联沃分享整理
物联沃-IOTWORD物联网 » lcd1602显示字符串(stm32+hal+lcd1602)

发表回复