📄 lcd12864.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 + -