【stm32简单外设篇】- LCD1602A

一、适用场景

适用场景:字符信息显示(传感器数值、提示信息、菜单)、调试输出、简单人机界面(参数设定、状态提示)、教学(并口/时序/I²C 驱动练习)、低成本信息面板与原型机显示模块。

二、器材清单

LCD1602A 字符液晶模块(16×2,HD44780 兼容) ×1

若干杜邦线(母对母)×1组;

stm32f103(或其他 STM32)开发板 ×1

5V 电源(模块 VCC)×1

三、工作原理(要点)

控制器:LCD1602A 常用 HD44780 兼容控制器,提供并行 8-bit/4-bit 接口与指令集(显示开关、光标、清屏、设置 DDRAM 地址等)。模块还带背光(LED)和对比度 VR(VO)。

接口模式:引脚用 8-bit 模式。I²C 背板(PCF8574)通过串行转并行节省更多引脚(通常用 I²C 地址 0x27/0x3F)。

信号线:常用引脚 VCC/GND/VO/RS/RW/EN/D4..D7/LED+/-(RW 常接地以简化,使用忙标志需接 RW 读忙位)。

时序要点:写指令/数据需遵守 EN 上升/下降脉冲与执行延时(部分驱动通过读忙标志替代延时)。初始化需特定序列(特别是在 4-bit 模式下的初始化三次 0x30 或 0x20 切换)。

四、接线示意

标准库

K、VSS → GND

VDD、A → 5V/3.3V电源

RS→ PD2

RW→ PD3

E→ PD4

D0-7→ PA0-7

HAL库

K、VSS → GND

VDD、A → 5V/3.3V电源

RS→ PB1

RW→ PB3

E→ PB4

D0-7→ PA0-7

五、示例代码

标准库

cpp 复制代码
#include <stdio.h> 
#include <stdarg.h> 
#include <string.h> 
#include <stdlib.h>
#include "stm32f10x.h"
#include "lcd1602.h"
#include "stdlib.h" 
#include "bsp_SysTick.h" 
 

void WriteData(u8 data)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_7,(BitAction)((data & 0x80) >> 7 )); 		//D7
	GPIO_WriteBit(GPIOA, GPIO_Pin_6,(BitAction)((data & 0x40) >> 6 )); 
	GPIO_WriteBit(GPIOA, GPIO_Pin_5,(BitAction)((data & 0x20) >> 5 )); 
	GPIO_WriteBit(GPIOA, GPIO_Pin_4,(BitAction)((data & 0x10) >> 4 )); 
	GPIO_WriteBit(GPIOA, GPIO_Pin_3,(BitAction)((data & 0x08) >> 3 )); 
	GPIO_WriteBit(GPIOA, GPIO_Pin_2,(BitAction)((data & 0x04) >> 2 )); 
	GPIO_WriteBit(GPIOA, GPIO_Pin_1,(BitAction)((data & 0x02) >> 1 )); 
	GPIO_WriteBit(GPIOA, GPIO_Pin_0,(BitAction)(data & 0x01));              //D0
}
 
void LCD1602_GPIO_Configuration(void)
{
	GPIO_InitTypeDef	GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOD ,ENABLE);//使能PB,PE端口时钟
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);	
    
 
 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
}
 
/* 等待液晶准备好 */
void LCD1602_Wait_Ready(void)
{
	u16 sta;
	
	WriteData(0xff);
	LCD_RS_Clr();//表示要操作的数据是数据
	LCD_RW_Set();//表示写操作
	do
	{
		LCD_EN_Set();//使能,开始读取数
		Delay_us(5000);	//延时5ms,非常重要,读取数据
 		sta = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_7);//读取状态字
		LCD_EN_Clr();//关闭使能
	}while(sta & 0x80);//bit15等于1表示液晶正忙,重复检测直到其等于0为止
}
 
/* 向LCD1602液晶写入一字节命令,cmd-待写入命令值 */
void LCD1602_Write_Cmd(u8 cmd)
{
	LCD_RS_Clr();//表示该数据是命令
	LCD_RW_Clr();
	LCD_EN_Clr();
	WriteData(cmd);
	LCD_EN_Set();
	Delay_us(5000);
	LCD_EN_Clr();
}
 
/* 向LCD1602液晶写入一字节数据,dat-待写入数据值 */
void LCD1602_Write_Dat(u8 dat)
{
	LCD_RS_Set();//表示该数据是数据
	LCD_RW_Clr();//表示要进行写操作
	LCD_EN_Clr();//关闭使能脚,防止对填数据造成干扰
	WriteData(dat);//填入数据
	LCD_EN_Set();//拉高使能脚lcd开始读取数据
	Delay_us(5000);//等待读取完成
	LCD_EN_Clr();
}
 
/* 清屏 */
void LCD1602_ClearScreen(void)
{
	LCD1602_Write_Cmd(0x01);//0x01是官方给的清屏指令,不用管什么原因
}
 
/* 设置显示RAM起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标 */
void LCD1602_Set_Cursor(u8 x, u8 y)
{
	u8 addr;
	
	if (y == 0)
		addr = 0x00 + x;//0x00是第一行最左侧的地址
	else
		addr = 0x40 + x;//0x40是第二行最左侧的地址
	LCD1602_Write_Cmd(addr | 0x80);//官方要求最高位必须是1,因此无论是在那个地址最高位必须设置为1
}
 
/* 在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,str-字符串指针 */
void LCD1602_Show_Str(u8 x, u8 y, char *str)
{
	LCD1602_Set_Cursor(x, y);
	while(*str != '\0')
	{
		LCD1602_Write_Dat(*str++);
	}
}
 
/* 初始化1602液晶 */
void LCD1602_Init(void)
{
	LCD1602_Write_Cmd(0x38);	//设置显示模式,16*2显示,5*7点阵,8位数据口
	Delay_us(5000);
	LCD1602_Write_Cmd(0x0c);	//打开显示,并光标关闭
	Delay_us(5000);
	LCD1602_Write_Cmd(0x06);	//设置光标的移动显示方式,文字不动,地址自动+1
	Delay_us(5000);
	LCD1602_Write_Cmd(0x01);	//清屏
	Delay_us(5000);
}
#include "stm32f10x.h"
#include "stdio.h"
#include "bsp_SysTick.h"
#include "lcd1602.h"

int main()
{
	SysTick_Init();	    	 //延时函数初始化
	Delay_us(10000);
	LCD1602_GPIO_Configuration();
	LCD1602_Init();
	while(1)
	{
		LCD1602_Show_Str(2, 1, "open");
		Delay_us(5000000);
		LCD1602_Show_Str(2, 1, "close");
		Delay_us(5000000);
	}
}

HAL库

cpp 复制代码
#include "lcd1602.h"
#include "stdlib.h" 	 

/*****************辰哥单片机设计******************
											STM32
 * 文件			:	LCD1602液晶显示屏c文件                     
 * 版本			: V1.0
 * 日期			: 20245.2.6
 * MCU			:	STM32F103C8T6
 * 接口			:	见代码							
 * BILIBILI	:	辰哥单片机设计
 * CSDN			:	辰哥单片机设计
 * 作者			:	辰哥 

**********************BEGIN***********************/



/*******************************************************************************
* 函 数 名       : LcdInit()
* 函数功能		 : 初始化LCD屏
* 输    入       : 无
* 输    出       : 无
*******************************************************************************/		

void LCD1602_Init(void)
{		
//	LCD1602_WriteCom(0x38);  //开显示
//	LCD1602_WriteCom(0x0c);  //开显示不显示光标
//	LCD1602_WriteCom(0x06);  //写一个指针加1
//	LCD1602_WriteCom(0x01);  //清屏
//	LCD1602_WriteCom(0x80);  //设置数据指针起点
	
	LCD1602_WriteCom(0x38);  //开显示
	HAL_Delay(5);
	LCD1602_WriteCom(0x0c);  //开显示不显示光标
	HAL_Delay(5);
	LCD1602_WriteCom(0x06);  //写一个指针加1
	HAL_Delay(5);
	LCD1602_WriteCom(0x01);  //清屏
	HAL_Delay(5);
	LCD1602_WriteCom(0xC0);
	HAL_Delay(5);
	LCD1602_WriteCom(0x80);
}

void LCD1602_DATAPINS(uint8_t Date)
{
//	uint16_t dat_buf;
//	dat_buf=GPIO_ReadOutputData(GPIOA);
//	dat_buf=dat_buf&0xFF00;
//	dat_buf=dat_buf|Date;

//	GPIO_Write(GPIOA, dat_buf);
	for (int i = 0; i < 8; i++)
  {
      HAL_GPIO_WritePin(GPIOA, (1 << i), (Date & (1 << i)) ? GPIO_PIN_SET : GPIO_PIN_RESET);
  }
	
}



void LCD1602_WriteCom(uint8_t com)	  //写入命令
{
	LCD1602_RS_L;	   //选择发送命令
	LCD1602_RW_L;	   //选择写入
	LCD1602_E_L;     //使能

	LCD1602_DATAPINS(com);     //放入命令
	HAL_Delay(1);		//等待数  据稳定

	LCD1602_E_H;	          //写入时序
	HAL_Delay(5);		  //保持时间
	LCD1602_E_L;

}

/*******************************************************************************
* 函 数 名         : LcdWriteData
* 函数功能		   : 向LCD写入一个字节的数据
* 输    入         : dat
* 输    出         : 无
*******************************************************************************/		   
   
void LCD1602_WriteData(uint8_t dat)			//写入数据
{
	LCD1602_RS_H;	   //选择发送命令
	LCD1602_RW_L;	   //选择写入
	LCD1602_E_L;     //使能
	
	LCD1602_DATAPINS(dat);  //写入数据
	HAL_Delay(1);

	LCD1602_E_H;   //写入时序
	HAL_Delay(5);   //保持时间
	LCD1602_E_L;

}

/*------------------------------------------------
              写入字符函数
------------------------------------------------*/
 void LCD1602_Write_Char(unsigned char x,unsigned char y,unsigned char Data) 
{     
 if (y == 0) 
 	{     
 	LCD1602_WriteCom(0x80 + x);    //第一行    
 	}    
 else 
 	{     
 	LCD1602_WriteCom(0xC0 + x);  //第二行     
 	}        
 LCD1602_WriteData( Data); //显示字符      
}
 



/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
 void LCD1602_Write_String(unsigned char x,unsigned char y,unsigned char *s) 
 {     
 if (y == 0) 
 	{     
	 LCD1602_WriteCom(0x80 + x);  //第一行   
 	}
 else 
 	{     
 	LCD1602_WriteCom(0xC0 + x);  //第二行   
 	}        
	while (*s) //判断是否检测到结尾符
 	{     
		 LCD1602_WriteData( *s);//显示字符     
		 s ++;  //指针加1   
 	}
 }
 
  /*------------------------------------------------
                清屏函数
------------------------------------------------*/
 void LCD1602_Clear(void) 
{ 
 LCD1602_WriteCom(0x01); 
 HAL_Delay(5);
}
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "lcd1602.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */
	int i=0;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
	LCD1602_Init();
	LCD1602_Write_String(0,0,"HELLO!!!   ");//显示字符串
	HAL_Delay(200);
//	LCD1602_Write_String(0,1,"  						");//显示字符串
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		i++;
		HAL_Delay(500);
		LCD1602_WriteCom(0xC6);
		HAL_Delay(2);
		LCD1602_WriteData(i+0x30);
//		LCD1602_WriteData('A');
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

六、讲解视频

https://www.bilibili.com/video/BV17emoBVEvD/?spm_id_from=333.1387.upload.video_card.click&vd_source=f7dfe1b14f260b9cc3a146d2dbfd0719

https://www.bilibili.com/video/BV1ctmoB7EwF/?spm_id_from=333.1387.upload.video_card.click&vd_source=f7dfe1b14f260b9cc3a146d2dbfd0719

https://www.bilibili.com/video/BV19CmoBKENp/?spm_id_from=333.1387.upload.video_card.click&vd_source=f7dfe1b14f260b9cc3a146d2dbfd0719

相关推荐
意法半导体STM322 小时前
【官方原创】在H563上使用RTX5 RTOS LAT1584
stm32·单片机·嵌入式硬件·mcu
巧克力味的桃子2 小时前
让程序在读取到整数0时就终止循环
c语言·算法
mastercoder--2 小时前
速通51单片机————矩阵键盘及其应用
嵌入式硬件·计算机外设·51单片机
d111111111d2 小时前
STM32 I2C通信详解:从机地址与寄存器地址的作用
笔记·stm32·单片机·嵌入式硬件·学习
普中科技2 小时前
【普中51单片机开发攻略--基于普中-2&普中-3&普中-4】-- 第 14 章 矩阵按键实验
单片机·嵌入式硬件·51单片机·开发板·按键检测·矩阵按键·普中科技
C++ 老炮儿的技术栈3 小时前
时序数据库 相对于关系型数据库,有什么区别
c语言·开发语言·c++·机器人·时序数据库·visual studio
Mapple.3 小时前
TMS320C6748的初始化与STM32做个类比
stm32·单片机·嵌入式硬件
俊俊谢3 小时前
华大HC32F460轮询方式SPI通讯配置
单片机·嵌入式硬件·spi·hc32f460
k***92163 小时前
C语言模拟面向对象三大特性与C++实现对比
java·c语言·c++