LCD1602液晶的使用

基于51单片机使用LCD1602液晶,后面再学习使用基于stm32的TFTLCD。

1.LCD1602的简介

        1602液晶也可以被叫做1602字符型液晶,这个是一种只用来显示字母、数字、符号等的点阵型液晶模块。1602里面存储器有三种:CGROM、CGRAM、DDRAM。

        首先显示内容分为两种,一种是常用字符,存储在CGROM中,用户可以直接调用,另一种是自定义的字符,比如自己设计的一些奇怪的图形之,存储在CGRAM。

(1)DDRAM就是显示数据RAM,用来寄存待显示的字符代码。地址与显示位置如下,每行40个地址,1602只用到前16个,共两行,对应关系如下:

 

        当我们想在指定位置写入内容时,要先指定地址,如在第一行第一位写入,地址位是00H,再加上DB7的1,即80H(0010000000),第二行第一位是40H,再加上DB7的1,C0H(0011000000),依次类推。

        (2)LCD自定义的存储在CGRAM,留给自定义的位置只有8个地址,字模地址为01000000-01000111八个地址,也就是最多自定义8个符号或者图形。

 根据这条指令,来写一个摄氏度℃的自定义符号,对应图如下:

        

        字符对应的数组为table【】={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00},将℃显示出来分为4个步骤

        A.设定CGRAM地址,即写命令LcdWriteCom(0x40),表示第1个自定义字符的存储地址是0x40;1个字符有8位,依次类推,设定第2个自定义字符地址用LcdWriteCom(0x48)......

        B.将表示字符的8位数据,写进设定的地址:用for循环将数据写入。

        C.在想要的地方显示字符:LcdWriteCom(0x80+0x40);//从第2行第1列开始显示。

        D.跟据自定义地址显示字符。LcdWriteData(table1[0]); //table1[]为自定义字符地址数组

补充   :为什么自定义字符地址是0x00~0x07 ?

        常用字符是从0x20开始显示,而0x00—0x0f都是没有用的,其实这个正式为自定义显示字符准备的。当你把上面的代码输入到CGRAM中,LCD1602机会把汉字或字符赋予地址,这个地址是从0x00开始,因为最多只能8个字符,所以当在CGRAM里面输入8个字符代码时,这8个字符的代码的数据地址就是0x00开始到0x07。

        (3)例程:

main.c


#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器
#include "lcd.h"

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;


u8 Disp[]=" Pechin Science ";//C语言中把字符串当作数组来处理

//LCD1602只能自定义8个字符
unsigned char character0[8] = {0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02}; //年

unsigned char character1[8] = {0x0f,0x09,0x0f,0x09,0x0f,0x09,0x0b,0x11}; //月

unsigned char character2[8] = {0x0f,0x09,0x09,0x09,0x0f,0x09,0x09,0x0f}; //日

unsigned char characterN[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //日

uchar code table1[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};  //自定义字符数据地址
/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

void main(void)
{
	u8 i;
	LcdInit();
	//显示字库的字符
	LcdWriteCom(0x80);//显示在第1行
	for(i=0;i<16;i++)	//显示存储在CGROM的字符
	{
		LcdWriteData(Disp[i]);	
	}

	//显示相邻两个的自定义字符
	LcdWriteCom(0x40); 	//设定CGRAM地址
	for(i=0;i<8;i++)   //把自定义字符存储到设定地址
	{
		LcdWriteData(character0[i]);	
	}
	LcdWriteCom(0x48); 	//1个字符有8位,所以第2个字符地址是0x40+8=0x48	
	for(i=0;i<8;i++)	
	{
		LcdWriteData(character1[i]);	
	}

	LcdWriteCom(0x80+0x40);//从第2行第1列开始显示
   	for(i=0;i<2;i++)	//	根据自定义地址显示2个字符
	{
		LcdWriteData(table1[i]);			
	}


	LcdWriteCom(0x50); 	//设定第3个字符地址	
	for(i=0;i<8;i++)	//
	{
		LcdWriteData(character2[i]);	
	}
	LcdWriteCom(0x80+0x44);	 //显示在第2行第5列开始显示
    LcdWriteData(table1[2]);	
	
	while(1);				
}

  LCD.c

#include "lcd.h"

/*******************************************************************************
* 函 数 名         : Lcd1602_Delay1ms
* 函数功能		   : 延时函数,延时1ms
* 输    入         : c
* 输    出         : 无
* 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时。
*******************************************************************************/

void Lcd1602_Delay1ms(uint c)   //误差 0us
{
    uchar a,b;
	for (; c>0; c--)
	{
		 for (b=199;b>0;b--)
		 {
		  	for(a=1;a>0;a--);
		 }      
	}
    	
}

/*******************************************************************************
* 函 数 名         : LcdWriteCom
* 函数功能		   : 向LCD写入一个字节的命令
* 输    入         : com
* 输    出         : 无
*******************************************************************************/
#ifndef 	LCD1602_4PINS	 //当没有定义这个LCD1602_4PINS时
void LcdWriteCom(uchar com)	  //写入命令
{
	LCD1602_E = 0;     //使能
	LCD1602_RS = 0;	   //选择发送命令
	LCD1602_RW = 0;	   //选择写入
	
	LCD1602_DATAPINS = com;     //放入命令
	Lcd1602_Delay1ms(1);		//等待数据稳定

	LCD1602_E = 1;	          //写入时序
	Lcd1602_Delay1ms(5);	  //保持时间
	LCD1602_E = 0;
}
#else 
void LcdWriteCom(uchar com)	  //写入命令
{
	LCD1602_E = 0;	 //使能清零
	LCD1602_RS = 0;	 //选择写入命令
	LCD1602_RW = 0;	 //选择写入

	LCD1602_DATAPINS = com;	//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;	 //写入时序
	Lcd1602_Delay1ms(5);
	LCD1602_E = 0;

	LCD1602_DATAPINS = com << 4; //发送低四位
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;	 //写入时序
	Lcd1602_Delay1ms(5);
	LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名         : LcdWriteData
* 函数功能		   : 向LCD写入一个字节的数据
* 输    入         : dat
* 输    出         : 无
*******************************************************************************/		   
#ifndef 	LCD1602_4PINS		   
void LcdWriteData(uchar dat)			//写入数据
{
	LCD1602_E = 0;	//使能清零
	LCD1602_RS = 1;	//选择输入数据
	LCD1602_RW = 0;	//选择写入

	LCD1602_DATAPINS = dat; //写入数据
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;   //写入时序
	Lcd1602_Delay1ms(5);   //保持时间
	LCD1602_E = 0;
}
#else
void LcdWriteData(uchar dat)			//写入数据
{
	LCD1602_E = 0;	  //使能清零
	LCD1602_RS = 1;	  //选择写入数据
	LCD1602_RW = 0;	  //选择写入

	LCD1602_DATAPINS = dat;	//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;	  //写入时序
	Lcd1602_Delay1ms(5);
	LCD1602_E = 0;

	LCD1602_DATAPINS = dat << 4; //写入低四位
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;	  //写入时序
	Lcd1602_Delay1ms(5);
	LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名       : LcdInit()
* 函数功能		 : 初始化LCD屏
* 输    入       : 无
* 输    出       : 无
*******************************************************************************/		   
#ifndef		LCD1602_4PINS
void LcdInit()						  //LCD初始化子程序
{
 	LcdWriteCom(0x38);  //开显示
	LcdWriteCom(0x0c);  //开显示不显示光标
	LcdWriteCom(0x06);  //写一个指针加1
	LcdWriteCom(0x01);  //清屏
	LcdWriteCom(0x80);  //设置数据指针起点
}
#else
void LcdInit()						  //LCD初始化子程序
{
	LcdWriteCom(0x32);	 //将8位总线转为4位总线
	LcdWriteCom(0x28);	 //在四位线下的初始化
	LcdWriteCom(0x0c);  //开显示不显示光标
	LcdWriteCom(0x06);  //写一个指针加1
	LcdWriteCom(0x01);  //清屏
	LcdWriteCom(0x80);  //设置数据指针起点
}
#endif

      LCD.H

#ifndef __LCD_H_
#define __LCD_H_
/**********************************
当使用的是4位数据传输的时候定义,
使用8位取消这个定义
**********************************/
//#define LCD1602_4PINS

/**********************************
包含头文件
**********************************/
#include<reg52.h>

//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint 
#define uint unsigned int
#endif

/**********************************
PIN口定义
**********************************/
#define LCD1602_DATAPINS P0
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;

/**********************************
函数声明
**********************************/
/*在51单片机12MHZ时钟下的延时函数*/
void Lcd1602_Delay1ms(uint c);   //误差 0us
/*LCD1602写入8位命令子函数*/
void LcdWriteCom(uchar com);
/*LCD1602写入8位数据子函数*/	
void LcdWriteData(uchar dat)	;
/*LCD1602初始化子程序*/		
void LcdInit();						  

#endif

  (4)字模提取

           LCD1602是5*8点阵,但是5*8不能提取代码,最少只能8*8,所以我们这里只用图像的后5列,前3列不用。

        新建图像 8*8,然后再图像里面点想要显示的字符,汉字,注意是在后5列中点,黑点表示显示,白点不显示,用鼠标左键可以切换。

这软件里面可以选择C51或汇编,这里选择C51,就可以产生代码了。

 

        

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值