LCD*1602控制

/*
数据端口
LCD_DB0    P00
LCD_DB1    P01
   .		.
   .		.
   .		.
LCD_DB7    P07
总之:P0用于数据传输,1次传送8位数据
LCD_E      P27
LCD_RS     P26
LCD_RW     P36


RS = 0,指向指令寄存器
RS = 1,指向数据寄存器
R/W = 0写操作
R/W = 1读操作
*/

#include <reg52.h>
//#define LCM_RW P3^6 //定义引脚
//#define LCM_RS P3^7
//#define LCM_E P3^5
sbit LCM_RW =P3^6 ;//定义引脚
sbit LCM_RS =P2^6;
sbit LCM_E =P2^7;
#define LCM_Data P0
#define Busy 0x80 //用于检测LCM状态字中的Busy标识

#define uchar unsigned char

void WriteDataLCM(uchar WDLCM);
void WriteCommandLCM(unsigned char WCLCM,BuysC);
unsigned char ReadDataLCM(void);
unsigned char ReadStatusLCM(void);
void LCMInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void Delay5Ms(void);
void Delay400Ms(void);

unsigned char code cdle_net[] = {"huanglu"};
unsigned char code email[] = {"freedom"};

void main(void)
{
	Delay400Ms(); //启动等待,等LCM讲入工作状态
	LCMInit(); //LCM初始化
	Delay5Ms(); //延时片刻(可不要)

	DisplayListChar(0, 0, cdle_net);
	DisplayListChar(0, 1, email);
	ReadDataLCM();//测试用句无意义
	while(1);
}

//写数据
void WriteDataLCM(uchar WDLCM)
{
	ReadStatusLCM(); //检测忙

	LCM_Data = WDLCM;

	LCM_RS = 1;//用数据寄存器
	LCM_RW = 0;//写操作

	LCM_E = 0; //若晶振速度太高可以在这后加小的延时
	LCM_E = 0; //延时
	LCM_E = 1;
}

//写指令
void WriteCommandLCM(uchar WCLCM, BuysC) //BuysC为0时忽略忙检测
{
	if (BuysC) 
		ReadStatusLCM(); //根据需要检测忙

	LCM_Data = WCLCM;  
	 
	LCM_RS = 0;	//指令寄存器
	LCM_RW = 0; //写操作

	LCM_E = 0;
	LCM_E = 0;
	LCM_E = 1; 
}

//读数据
unsigned char ReadDataLCM(void)
{
	LCM_RS = 1; 
	LCM_RW = 1;

	LCM_E = 0;
	LCM_E = 0;
	LCM_E = 1;

	return(LCM_Data);
}

/*
忙时等待
全局变量:LCM_Data, LCM_RS, LCM_RW, LCM_E, Busy
工作原理:当Busy = 1,代表忙时,等待;
          当Busy = 0,代表不忙,结束等待!
*/
unsigned char ReadStatusLCM(void)
{
	LCM_Data = 0xFF; 

	LCM_RS = 0;	//指令寄存器
	LCM_RW = 1; //读

	LCM_E = 0;
	LCM_E = 0;
	LCM_E = 1;
	while (LCM_Data & Busy); //检测忙信号,等待,直到忙时 标志位 为0
	return(LCM_Data); 
}

void LCMInit(void) //LCM初始化
{
	LCM_Data = 0;
	WriteCommandLCM(0x38,0); //三次显示模式设置,不检测 忙信号	 0x38 = 0011 1000
	Delay5Ms(); 
	WriteCommandLCM(0x38,0);
	Delay5Ms(); 
	WriteCommandLCM(0x38,0);
	Delay5Ms(); 
	 //RS RW 7 6 5 4 3 D C B
	WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
	WriteCommandLCM(0x08,1); //关闭显示							   0x08 = 0000 1 0 0 0
	WriteCommandLCM(0x01,1); //显示清屏							   0x01 = 0000 0 0 0 1
	WriteCommandLCM(0x06,1); // 显示光标移动设置				   0x06 = 0000 0 1 1 0   显示移位,左移
	WriteCommandLCM(0x0C,1); // 显示开及光标设置				   0x0c = 0000 1 1 0 0
}

//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
	Y &= 0x1;									   //0001
	//X &= 0xF; //限制X不能大于15,Y不能大于1		   //1111

	//当Y = 1时,开始写第二行,Y = 0时,写第一行
	if (Y) 
		X |= 0x40; //当要显示第二行时地址码+0x40;

	X |= 0x80; //算出指令码	   X = X + 0X80

	WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
	WriteDataLCM(DData);
}

//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
	unsigned char ListLength;

	ListLength = 0;

	Y &= 0x1;  //有了此限定后,Y可以为0,或者为1
	X &= 0xF; //X 最大为15,最小为0  

	while (DData[ListLength] > 0x20) //若到达字串尾则退出
	{
		if (X <= 0xF) //X坐标应小于0xF  
		{
			DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
			ListLength++;
			X++;
		}
	}
}

//5ms延时
void Delay5Ms(void)
{
	unsigned int TempCyc = 5552;
	while(TempCyc--);
}

//400ms延时
void Delay400Ms(void)
{
	unsigned char TempCycA = 5;
	unsigned int TempCycB;
	while(TempCycA--)
	{
		TempCycB=7269;
		while(TempCycB--);
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值