LCD1602的四线驱动

LCD1602使用4线方式驱动

先介绍硬件环境:
MCU:STM32F030F4,主频16Mhz
显示器:LCD1602A,黄绿屏
软件环境:STM32CUBE_MX
编译器:keil MDK;

不多说了,直接上代码:

头文件

/**
硬件连接:

DB4–PA0
DB5–PA1
DB6–PA3
DB7–PA4

RW—PA9
RS—PA10
E----PB1

/
/

读状态。输入RS=0,RW=1,E=高脉冲。输出:D0—D7为状态字。

读数据。输入RS=1,RW=1,E=高脉冲。输出:D0—D7为数据。

写命令。输入RS=0,RW=0,E=高脉冲。输出:无。

写数据。输入RS=1,RW=0,E=高脉冲。输出:无。

**/
#ifndef __LCD_1602_H
#define __LCD_1602_H

#include “main.h”

#define COM 0
#define DAT 1
#define LCD_RS_H() HAL_GPIO_WritePin(LCD_RS_GPIO_Port,LCD_RS_Pin,GPIO_PIN_SET)
#define LCD_RS_L() HAL_GPIO_WritePin(LCD_RS_GPIO_Port,LCD_RS_Pin,GPIO_PIN_RESET)
#define LCD_RW_H() HAL_GPIO_WritePin(LCD_RW_GPIO_Port,LCD_RW_Pin,GPIO_PIN_SET)
#define LCD_RW_L() HAL_GPIO_WritePin(LCD_RW_GPIO_Port,LCD_RW_Pin,GPIO_PIN_RESET)
#define LCD_E_H() HAL_GPIO_WritePin(LCD_E_GPIO_Port,LCD_E_Pin,GPIO_PIN_SET)
#define LCD_E_L() HAL_GPIO_WritePin(LCD_E_GPIO_Port,LCD_E_Pin,GPIO_PIN_RESET)
#define LCD_BusySta() HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3)

void LCD1602_Init(void);
void LCD1602_ClearScreen(void);

void LCD1602_Show_Str(uint8_t x, uint8_t y, uint8_t *str);

#endif

//

C文件

#include “lcd1602.h”
void LCD1602_Set_Cursor(uint8_t x, uint8_t y);

///4线LCD1602
//函数名: delay
//函数功能:LCD1602延时
//注释:
void delay(unsigned char z)
{
unsigned char x,y,j;
for(j=0;j<4;j++)
for(x=z;x>0;x–)
for(y=110;y>0;y–);
}

//
void Send2Lcd(uint8_t data,uint8_t rs)
{
uint8_t i;

if(rs)  LCD_RS_H();
else    LCD_RS_L();

LCD_RW_L();

for(i=0;i<2;i++)
{
    GPIOA->ODR = (GPIOA->ODR & 0xfff0) | ((data>>4) & 0x0f);
	LCD_E_H();
	delay(50);
	LCD_E_L();
	data <<= 4;
}	

}

//void LCD_CheckBusy(void)
//{
//
// uint16_t portValue;
// portValue = GPIOA->ODR;
// GPIOA->ODR= portValue | 0X000F;
//
// LCD_RS_L();
// LCD_RW_H();
// LCD_E_H();
//
// while(LCD_BusySta());
// LCD_E_L();
//}

/*向1602写入一字节命令,cmd-待写入命令 */
//写入指令PA4-7 RS-0 RW-0
void LCD1602_Write_Cmd(uint8_t cmd)
{
// LCD_CheckBusy();
Send2Lcd(cmd,COM);
}

/* 向1602写入一字节数据*/
void LCD1602_Write_Dat(uint8_t dat)
{
// LCD_CheckBusy();
Send2Lcd(dat,DAT);
}

/清屏/
void LCD1602_ClearScreen(void)
{
LCD1602_Write_Cmd(0x01);
HAL_Delay(2);
}

/* 设置RAM其实地址,即光标位置,(X,Y)对应屏幕上的字符坐标 */
void LCD1602_Set_Cursor(uint8_t x, uint8_t y)
{
// uint8_t addr;
//
// if (y == 0)
// addr = 0x00 + x;
// else
// addr = 0x40 + x;
// LCD1602_Write_Cmd(addr | 0x80);
switch(x)
{
case 0:
y|=0x80;
break;
case 1:
y|=0xc0;
break;
}
LCD1602_Write_Cmd(y);
}

/* 在液晶上显示字符串,(X,Y)-对应屏幕上的其实坐标,str-字符串指针 */
void LCD1602_Show_Str(uint8_t x, uint8_t y, uint8_t *str)
{
LCD1602_Set_Cursor(x, y);
while(*str != ‘\0’)
{
LCD1602_Write_Dat(*str++);
}
}

/* 初始化液晶 */
void LCD1602_Init(void)
{
HAL_Delay(50);
LCD1602_Write_Cmd(0x33);
HAL_Delay(5);
LCD1602_Write_Cmd(0x32);
HAL_Delay(1);

LCD1602_Write_Cmd(0x28);	//16*2显示,5*7点阵,4位数据口
HAL_Delay(1); 

LCD1602_Write_Cmd(0x01);	//清屏 
HAL_Delay(1);

LCD1602_Write_Cmd(0x06);	//文字不动,地址自动+1 
HAL_Delay(1);
LCD1602_Write_Cmd(0x0c);

}
//
//

注意项点:

1、在发送数据的时候,因为硬件是直接在PA低四位,所以采用了寄存器直接输出,如果不是,请调整数据发送。
2、初始化命令要按上面程序的来,我之前用其他初始化程序,在debug完成后,能正常显示,但是直接上电就总是显示不正常。

最后来个图片验证一下吧。
LCD1602的四线驱动_第1张图片
LCD1602的四线驱动_第2张图片

你可能感兴趣的:(测试,液晶屏,单片机,stm32)