⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd12864.c

📁 基于51单片机的液晶12864图片驱动及串行收发程序
💻 C
字号:
//P2.0-RS;P2.1-RW;P2.2-E;P2.3-PSB;P2.5RST;P0-DATABUS;

#include "STC89C51.H"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int

#define BUS P1
sbit RS = P2^0;
sbit RW = P2^1;
sbit E = P2^2;
sbit PSB = P2^3;
sbit RST = P2^5;

bit command = 0;
uchar data_receive[4] = {0,0,0,0};
uchar rec_num = 0;

void Delay(uint k)//延时函数
{
	uint i;
	do
		{
			i = 50;
			while(i)i--;
			k--;
		}
	while(k > 0);
}

void LcdBusy(void)//检测LCD模块是否空闲,可以接收指令,等待,直到模块空闲
{
	RS = 0;//RS:H数据,L:指令
	RW = 1;//RW:H:读,L:写
	BUS = 0xFF;//单片机I/O口在读数据前拉到高电平才能正确读取
	while(1)
		{
			E = 1;//E:并口读写起始脚
			if(BUS < 0x80)break;//BUS的最高位为忙标志为,BUSY:H:忙,L:空闲
			E = 0;//结束读指令
		}
	E = 0;//结束读指令
}

void SentAIns(uchar Ins)//写入一个指令
{
	LcdBusy();//等待模块空闲
	RS = 0;//RS:H数据,L:指令
	RW = 0;//RW:H:读,L:写
	E = 1;//E电平从高到低写入总线上的数据
	BUS = Ins & 0xFF;
	E = 0;
}

void SentAData(uchar Data)//写入一个数据
{
	LcdBusy();//等待模块空闲
	RS = 1;//RS:H数据,L:指令
	RW = 0;//RW:H:读,L:写
	E = 1;//E电平从高到低写入总线上的数据
	BUS = Data & 0xFF;
	E = 0;
}
uchar ReadAData(void)//读取显示RAM数据
{
	uchar temp;
	LcdBusy();//等待模块空闲
	RS = 1;//RS:H数据,L:指令
	RW = 1;//RW:H:读,L:写
	E = 1;//E电平从高到低写入总线上的数据
	temp = BUS;
	E = 0;
	return(temp);
}

void LcdInit(void)//模块初始化
{
	RST = 0;//RST由低到高
	Delay(10);
	RST = 1;
	Delay(50);
	SentAIns(0x30);//写入功能设置指令
	Delay(50);
	SentAIns(0x30);//写入功能设置指令
	Delay(50);
	SentAIns(0x0C);//写入显示指令,整体显示开,游标、反白关
	Delay(50);
	SentAIns(0x01);//写入清屏指令
	Delay(50);
	SentAIns(0x06);//写入进入电设置指令,方向向右,默认位移
}

void SetCGRAM(uchar N,uchar *Font)//自定义字体,四个,N代表某一个,*Font指向数据
{
	uchar i;
	SentAIns(0x30);//进入普通模式
	SentAIns(0x30 + N*16);//进入CGRAM自定义字体
	for(i=0;i<32;i++)
	{
		SentAData(*(Font++));
	}
}

void DisPicFull(uchar *PicData)//满屏显示画面函数,图像大小为128×64,将要写的图片的字模写入PicDa[]数组中
{
	uchar i,j;
	SentAIns(0x01);//清屏清除RAM
	SentAIns(0x34);//扩展指令集
	SentAIns(0x34);//绘图显示关
	for(i=0;i<16;i++)//第一行
		{
			SentAIns(0x80 + i);//写入Y地址,16行
			SentAIns(0x80);//写入X地址,上半屏0x80-0x87
			for(j=0;j<16;j++)//循环16次,总共8×2字节数据要输入,从左至右
				{
					SentAData(*(PicData++));//写入图片数据
				}
		}

	for(i=0;i<16;i++)//第二行
		{
			SentAIns(0x90 + i);//写入Y地址,16行
			SentAIns(0x80);//写入X地址,上半屏0x90-0x97
			for(j=0;j<16;j++)//循环16次,总共8×2字节数据要输入,从左至右
				{
					SentAData(*(PicData++));//写入图片数据
				}
		}


	for(i=0;i<16;i++)//第三行
		{
			SentAIns(0x80 + i);//写入Y地址,16行
			SentAIns(0x88);//写入X地址,上半屏0x89-0x8F
			for(j=0;j<16;j++)//循环16次,总共8×2字节数据要输入,从左至右
				{
					SentAData(*(PicData++));//写入图片数据
				}
		}

	for(i=0;i<16;i++)//第四行
		{
			SentAIns(0x90 + i);//写入Y地址,16行
			SentAIns(0x98);//写入X地址,上半屏0x90-0x9F
			for(j=0;j<16;j++)//循环16次,总共8×2字节数据要输入,从左至右
				{
					SentAData(*(PicData++));//写入图片数据
				}
		}

	SentAIns(0x36);//绘图显示开
	SentAIns(0x30);//进入普通模式
}

void main(void)
{
uchar code PicData[1024] = //128×64图像的字模
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x00,0x00,0x00,0x10,0x70,0x30,0x70,0x00,0xC0,0x02,0x61,0x80,0x00,
0x00,0x3F,0x18,0x1F,0xFF,0xE0,0xF8,0x70,0x30,0x70,0x00,0xE0,0x03,0x33,0x80,0x00,
0x00,0x3F,0x18,0x1F,0xFF,0xF7,0xF2,0x70,0x30,0x60,0x00,0xC0,0x03,0xBB,0x00,0x00,
0x00,0x37,0xFF,0x80,0x6C,0x00,0x63,0x70,0x34,0x62,0x00,0xC0,0x01,0xBB,0x00,0x00,
0x00,0x36,0xFF,0x80,0x6C,0x00,0x63,0xF1,0xFF,0xFF,0x00,0xC1,0x87,0xFF,0xE0,0x00,
0x00,0x3D,0x9B,0x0F,0xFF,0xE7,0xF9,0x70,0xB0,0x60,0x7F,0xFF,0xCF,0xFF,0xF0,0x00,
0x00,0x3C,0xDF,0x07,0xFF,0xE7,0xFC,0x70,0x30,0x60,0x00,0xE0,0x0C,0x02,0xE0,0x00,
0x00,0x36,0xFE,0x06,0x6C,0xE0,0xE7,0x70,0x3F,0xFE,0x00,0xE0,0x1F,0xFF,0xC0,0x00,
0x00,0x37,0xFC,0x86,0xEC,0xE0,0xFB,0x70,0x7F,0xFE,0x00,0xE0,0x0B,0xFF,0x80,0x00,
0x00,0x33,0xFF,0xC6,0xCC,0xE1,0xFB,0x7D,0xF1,0x8C,0x01,0xF0,0x00,0x1C,0x00,0x00,
0x00,0x33,0xFF,0xC6,0xCF,0xE3,0xF9,0xFD,0xF0,0xDC,0x01,0xF0,0x00,0x38,0xE0,0x00,
0x00,0x3F,0x3C,0x07,0x8F,0xE3,0x7F,0xF0,0x30,0xF8,0x01,0x98,0x1F,0xFF,0xE0,0x00,
0x00,0x3E,0x7C,0x07,0x03,0xE6,0x68,0x70,0x30,0xF0,0x03,0x9C,0x00,0x38,0x00,0x00,
0x00,0x30,0x66,0x06,0x00,0xE4,0x60,0x70,0x30,0x70,0x07,0x0E,0x00,0x38,0x00,0x00,
0x00,0x30,0xC3,0x87,0xFF,0xE0,0x60,0x70,0xF1,0xFC,0x0E,0x07,0xC0,0xF8,0x00,0x00,
0x00,0x33,0x83,0xC6,0x00,0xE0,0x60,0x70,0xF7,0x9F,0x3C,0x03,0xC0,0xF8,0x00,0x00,
0x00,0x37,0x00,0x8C,0x00,0xC0,0x60,0x70,0x7E,0x06,0x70,0x01,0x80,0x30,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
	//串口初始化
    SCON = 0x50;		        /* SCON: mode 1, 8-bit UART, enable rcvr      */
    TMOD |= 0x20;               /* TMOD: timer 1, mode 2, 8-bit reload        */
    TH1 = 0xFD;               /* TH1:  reload value for 1200 baud @ 11.0592MHz   */
	TL1 = 0xFD;
    TR1 = 1;                  /* TR1:  timer 1 run                          */
    ES = 1;
	EA = 1;


SBUF = 0x58;
while(!TI);
TI = 0;

LcdInit();

//基本指令
//SentAIns(0x30);//基本指令集
//SentAIns(0x01);//清除显示,DDRAM填满20H代码,并且设定DDRAM的地址计数器AC为00H;更新设置进入设定点将I/D设为1,游标右移AC加1
//SentAIns(0x02);//地址归零,设定DDRAM的地址寄存器为00H,并且将游标移到开头原点位置;这个指令并不改变DDRAM的内容
//SentAIns(0x04);//进入设定点,游标左移,DDRAM 地址计数器(AC)减1,画面整体右移
//SentAIns(0x05);//进入设定点,游标左移,DDRAM 地址计数器(AC)减1,画面整体右移
//SentAIns(0x06);//进入设定点,游标右移,DDRAM 地址计数器(AC)加1,画面整体右移
//SentAIns(0x07);//进入设定点,游标右移,DDRAM 地址计数器(AC)加1,画面整体左移
//SentAIns(0x08);//显示开关设置,整体显示关,游标显示关,游标显示反白关
SentAIns(0x0C);//显示开关设置,整体显示开,游标显示关,游标显示反白关
//SentAIns(0x0E);//显示开关设置,整体显示开,游标显示开,游标显示反白关
//SentAIns(0x0F);//显示开关设置,整体显示开,游标显示开,游标显示反白开
//SentAIns(0x10);//游标向左移动
//SentAIns(0x14);//游标向右移动
//SentAIns(0x18);//显示向左移动,游标跟着移动
//SentAIns(0x1C);//显示向右移动,游标跟着移动
//SentAIns(0x30);//8位MPU接口
//SentAData(0xXX);//写显示数据到RAM,数据为0xXX;CGRAM,DDRAM,IRAM地址都可以连续写入2个字节的显示数据,当写入第二个字节时,地址计数器AC的值自动加一

//扩充指令
//SentAIns(0x34);//扩充指令集
//SentAIns(0x01);//待命模式,任何指令都可以结束待命模式
//SentAIns(0x03);//允许输入垂直卷动地址
//SentAIns(0x02);//允许输入IRAM地址(扩充指令)及允许设定CGRAM地址(基本指令)
//SentAIns(0x04);//第一,三行反白显示
//SentAIns(0x05);//第二,四行反白显示
//SentAIns(0x08);//进入睡眠模式
//SentAIns(0x0C);//脱离睡眠模式
//SentAIns(0x36);//绘图显示开
//SentAIns(0x34);//绘图显示关



//SentAIns(0x0E);//有光标,不闪烁
//	SentAIns(0x0F);//有光标,闪烁
//	SentAIns(0x01);//光标闪烁

	DisPicFull(PicData);

	while(1)
		{
			if(command == 1)
				{
					command = 0;
					SBUF = 0xEB;
					while(!TI);
					TI = 0;
					SBUF = data_receive[1];
					while(!TI);
					TI = 0;
					SBUF = data_receive[2];
					while(!TI);
					TI = 0;
					SBUF = data_receive[3];
					while(!TI);
					TI = 0;
					//显示16×16汉字
					SentAIns(data_receive[1]);//显示汉字的位置
					SentAData(data_receive[2]);//显示汉字高字节
					SentAData(data_receive[3]);//显示汉字低字节

//					SentAIns(0x1C);
//					SentAIns(0x34);//扩充指令集
//					SentAIns(0x08);//反白显示
//					SentAIns(0x30);//基本指令集
	//显示8×1字符
//	SentAIns(data_receive[1]);//显示字符的位置
//	SentAData(data_receive[2]);//显示字符字节

				}
		}
}

void Serial() interrupt 4 using 1
{
	if(_testbit_(RI))
	{
		if (SBUF == 0xEB)
		{
			rec_num = 0;
			data_receive[rec_num] = SBUF;
			rec_num++;
		}
		else 
        {
			data_receive[rec_num] = SBUF;
			rec_num++;
		}
		if(rec_num >= 4)
		{   
			command = 1;
			rec_num = 0;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -