📄 lcd-lgm.c
字号:
/*******************************************************
程序功能:LCD汉字及图形点阵显示
作者:剑影
厦门大学03级机电工程系
email:gmdengxm@163.com
QQ群:22086176
*********************************************************
接线说明:
80C51 LGM12641BS1R 和 AMPIR 128 X 64
P0.0~7 --- DB0~7
P0.0~7接74ls373 D0~7 = Q0~7
Q0---RW
Q1---DI(RS)
Q4 --- CS2( AMPIR 128 X 64)CS1( LGM12641BS1R)
Q5--- CS1( AMPIR 128 X 64) CS2( LGM12641BS1R)
!(WR&RD) ---- E
ALE ---LE(74ls373)
*********************************************************
AMPIR 128 X 64 命令说明
DI WR D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 1 1 1 1 1 1 D *D = 1时显示开 ×D = 0时显示关
0 0 1 1 A A A A A A * 设定显示开始行寄存器位置
0 0 1 0 1 1 1 A A A *设定页地址
0 0 0 1 A A A A A A *设定列地址
1 0 D7 0 D5 D4 0 0 0 0 *D7为1表示LCD忙,D7=0可以读写操作,D5 = 1显示关状态,D5 = 0显示开状态,D4=1表示正在初始化,D4=0初始化完毕
0 1 D D D D D D D D *写入数据,列地址自动加1
1 1 D D D D D D D D *读取显示状态
********************************************************/
#include <REG51.H>
#include <ABSACC.H>
typedef unsigned char uchar;
typedef unsigned int uint;
/****************LCD读写控制字*****************/
//左半部
#define LLCD_CMD_WR PBYTE[0x10] //写命令rs = 0 wr = 0
#define LLCD_CMD_RD PBYTE[0x11] //读命令rs = 0 wr = 1
#define LLCD_DATA_WR PBYTE[0x12] //写数据rs = 1 wr = 0
#define LLCD_DATA_RD PBYTE[0x13] //读数据rs = 1 wr = 1
//右半部
#define RLCD_CMD_WR PBYTE[0x20] //同上,为LCD右半部分的读写指令
#define RLCD_CMD_RD PBYTE[0x21]
#define RLCD_DATA_WR PBYTE[0x22]
#define RLCD_DATA_RD PBYTE[0x23]
#define LCD_DOT_MAXX 128 //此LCD为128X64,分左右两部分,每部分64X64
#define LCD_DOT_MAXY 64
#define LCD_MAXX 8 //以16为一个单位,行上最多可显示8个单位
#define LCD_MAXY 4 //列上可以显示4个单位,整个屏幕可显示8x4 =32个中文字符
sbit busy = P0^7;
/***************数组定义***********************/
code uchar hanzi1[] =
{
/*-- 文字: 厦 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x00,0xF0,0x10,0xF0,0xB0,0xB0,0xF0,0xB0,0xB0,0xF0,0xF0,0x10,0x00,0x00,
0x00,0x10,0x0C,0x07,0x28,0x2B,0x1B,0x1F,0x1F,0x1F,0x17,0x33,0x33,0x30,0x30,0x00,
/*-- 文字: 门 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x00,0xE0,0x80,0x10,0x30,0x20,0x20,0x30,0x20,0x20,0x20,0xE0,0x00,0x00,
0x00,0x10,0x18,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,
/*-- 文字: 大 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x80,0xC0,0x80,0x80,0x80,0xF0,0xF0,0x80,0x80,0x80,0x80,0x00,0x00,0x00,
0x00,0x10,0x18,0x18,0x18,0x0C,0x06,0x03,0x01,0x02,0x06,0x0C,0x18,0x38,0x10,0x00,
/*-- 文字: 学 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0xC0,0x40,0x70,0x40,0x40,0xF0,0x40,0x40,0x70,0x50,0x40,0xC0,0x00,0x00,
0x00,0x0C,0x05,0x04,0x24,0x25,0x25,0x36,0x1F,0x0D,0x05,0x04,0x04,0x0D,0x0C,0x04,
};
code uchar hanzi2[] =
{
/*-- 文字: 机 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x40,0x40,0xF0,0x40,0x40,0x00,0xE0,0x20,0x20,0xE0,0x20,0x00,0x00,0x00,
0x00,0x04,0x06,0x03,0x3F,0x03,0x12,0x1C,0x0F,0x00,0x00,0x0F,0x18,0x18,0x18,0x08,
/*-- 文字: 电 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x40,0xE0,0xA0,0xA0,0xA0,0xF0,0xB0,0xA0,0xA0,0xA0,0xE0,0x00,0x00,0x00,0x00,
0x00,0x00,0x07,0x06,0x06,0x02,0x0F,0x1A,0x1A,0x32,0x36,0x33,0x30,0x30,0x18,0x00,
/*-- 文字: 工 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x00,0x20,0x20,0x20,0x20,0xE0,0x60,0x20,0x20,0x20,0x20,0x00,0x00,0x00,
0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x18,0x18,0x18,0x18,0x00,
/*-- 文字: 程 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0xC0,0xA0,0xA0,0xE0,0x90,0x90,0xF0,0xF0,0xA0,0xA0,0xA0,0xF0,0x00,0x00,0x00,
0x00,0x06,0x02,0x1F,0x3F,0x01,0x12,0x15,0x15,0x1F,0x1F,0x15,0x15,0x10,0x10,0x00,
/*-- 文字: 系 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x20,0xA0,0xA0,0xE0,0xE0,0xA0,0xA0,0x50,0x50,0x10,0x10,0x00,0x00,0x00,
0x00,0x10,0x10,0x18,0x1A,0x2F,0x23,0x3E,0x3E,0x03,0x05,0x09,0x1A,0x18,0x10,0x00,
};
code uchar hanzi3[] =
{
/*-- 文字: 0 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*-- 文字: 3 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*-- 文字: 机 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x40,0x40,0xF0,0x40,0x40,0x00,0xE0,0x20,0x20,0xE0,0x20,0x00,0x00,0x00,
0x00,0x04,0x06,0x03,0x3F,0x03,0x12,0x1C,0x0F,0x00,0x00,0x0F,0x18,0x18,0x18,0x08,
/*-- 文字: 械 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x40,0xC0,0xF0,0x40,0x00,0x40,0xC0,0x40,0xF0,0x40,0xF0,0x40,0x00,0x00,
0x04,0x04,0x02,0x01,0x3F,0x15,0x1A,0x07,0x02,0x1F,0x0F,0x0E,0x19,0x38,0x10,0x10,
};
code uchar hanzi4[] =
{
/*-- 文字: 剑 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x80,0x80,0xC0,0x40,0xA0,0xB0,0xB0,0xC0,0x40,0x00,0xC0,0x00,0x30,0xF0,0x00,0x00,
0x00,0x10,0x18,0x1F,0x18,0x1E,0x08,0x0E,0x08,0x10,0x13,0x30,0x38,0x1F,0x00,0x00,
/*-- 文字: 影 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x00,0x70,0x50,0xD0,0x50,0x70,0x70,0x80,0x40,0x20,0x30,0x90,0x00,0x00,
0x01,0x01,0x11,0x1F,0x27,0x3E,0x07,0x0F,0x31,0x22,0x12,0x11,0x09,0x0C,0x06,0x00,
/*-- 文字: 制 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x80,0x40,0x70,0x40,0xF0,0xD0,0xC0,0x40,0x00,0xE0,0x00,0x30,0xF0,0x00,0x00,
0x01,0x01,0x11,0x1F,0x03,0x3F,0x03,0x06,0x1E,0x10,0x17,0x30,0x38,0x1F,0x00,0x00,
/*-- 文字: 作 --*/
/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x60,0x60,0xE0,0xE0,0x90,0x40,0x60,0x30,0xF0,0x60,0x60,0x60,0x40,0x40,0x00,
0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x3F,0x05,0x05,0x05,0x05,0x04,0x00,
};
code uchar bmp[] =
{
/*-- 宽度x高度=32x32 --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xE0,0xF0,0x30,0x18,0x04,0x02,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0x80,0xC0,0xC0,0xE0,0xF0,0xF0,0xF0,0xF8,0xF8,0xFC,0xFC,
0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0x1F,0x0F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x70,0xFC,0xFE,0xFF,0x7F,0x3B,0x71,0x7B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xE7,0x87,0x07,0x0F,0x0F,0x07,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0F,0x0B,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x0E,0x18,0x01,0x03,
0x07,0x0F,0x0F,0x1C,0x18,0x30,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
/***************变量定义***********************/
uchar x,y;
struct cursortype
{
uchar x,y,side;
}cousor;
/***************函数定义***********************/
void lcd_cmd_wr(uchar cmdcode, uchar right); //写命令
void lcd_data_wr(uchar ldata, uchar right); //写数据
void lcd_busy_rd(uchar right); //读状态
void chk_busy(uchar right);
void lcd_hanzi_wr(uchar posx,uchar posy,uchar *hanzi);
void lcd_str_wr(uchar row,uchar col,uchar n,uchar *str);
void lcd_bmp_wr(uchar posx,uchar posy,uchar wth,uchar hgh,uchar *bmp);
void lcd_rol();
void lcd_init();
void delay(uint nms); //延时 n ms
/****************主函数***********************/
void main()
{
lcd_init();
lcd_str_wr(0,1,4,hanzi1);
delay(100);
lcd_str_wr(1,1,5,hanzi2);
delay(100);
lcd_str_wr(2,1,4,hanzi3);
delay(100);
lcd_str_wr(3,1,4,hanzi4);
delay(100);
lcd_bmp_wr(0,0x60,32,32,bmp);
delay(100);
while(1)
{
lcd_rol();
delay(1000);
}
}
/****************子函数***********************/
void lcd_cmd_wr(uchar cmdcode, uchar right) //写指令
{
chk_busy(right);
if(right == 1) //如果right = 1,则对右半部进行读写
{
RLCD_CMD_WR = cmdcode;
}
else //否则写左半部LCD
{
LLCD_CMD_WR = cmdcode;
}
}
void lcd_data_wr(uchar ldata, uchar right) //对LCD进行数据读写,
{
chk_busy(right); //检测LCD忙
if(right == 1)
{
RLCD_DATA_WR = ldata;
}
else
{
LLCD_DATA_WR = ldata;
}
}
void lcd_busy_rd(uchar right)
{
if( right == 1)
{
RLCD_CMD_RD;
}
else
{
LLCD_CMD_RD;
}
}
void chk_busy(uchar right) //检测LCD忙,right = 1 为右半部,
{
lcd_busy_rd(right); //right = 0为左半部,遇忙等待
while(busy);
}
void delay(uint nms) //延时程序
{
uint i;
for(; nms > 0; nms--)
for(i = 0; i < 500; i++);
}
void lcd_init() //LCD初始化
{
uint k;
lcd_cmd_wr(0x3e+1,0); //左半部显示开
lcd_cmd_wr(0xc0+0,0); //左半部顶行为第0行
lcd_cmd_wr(0xb8+0,0); //设定左半部页地址
lcd_cmd_wr(0x40+0,0); //设定左半部列地址
lcd_cmd_wr(0x3e+1,1); //右半部显示开
lcd_cmd_wr(0xc0+0,1); //右半部顶行设定为第0行
lcd_cmd_wr(0x40+0,1); //设定列地址
lcd_cmd_wr(0xb8+0,1); //设定页地址
for(k = 0; k < 256; k++) //LCD屏初始化
{
lcd_data_wr(0x00,0);
lcd_data_wr(0x00,1);
}
lcd_cmd_wr(0xb8+4,0);
lcd_cmd_wr(0x40+0,0);
lcd_cmd_wr(0xb8+4,1);
lcd_cmd_wr(0x40+0,1);
for(k = 0; k < 256; k++)
{
lcd_data_wr(0x00,0);
lcd_data_wr(0x00,1);
}
}
void lcd_hanzi_wr1(uchar posx,uchar posy,uchar * hanzi) //对LCD在指定位置写入单个汉字
{
uchar i;
if(posy < 4) //posy < 4 在左半部写
{
lcd_cmd_wr(0xb8+2*posx,0);
lcd_cmd_wr(0x40+16*posy,0);
for(i = 0; i < 16; i++)
{
lcd_data_wr(hanzi[2*i],0);
}
lcd_cmd_wr(0xb8+2*posx+1,0);
lcd_cmd_wr(0x40+16*posy,0);
for(i = 0; i < 16; i++)
{
lcd_data_wr(hanzi[2*i+1],0);
}
}
else //否则在右半部写
{
lcd_cmd_wr(0xb8+posx*2,1);
lcd_cmd_wr(0x40+16*(posy-4),1);
for(i = 0; i < 16; i++)
{
lcd_data_wr(hanzi[2*i],1);
}
lcd_cmd_wr(0xb8+2*posx+1,1);
lcd_cmd_wr(0x40+16*(posy-4),1);
for(i = 0; i < 16; i++)
{
lcd_data_wr(hanzi[2*i+1],1);
}
}
}
void lcd_hanzi_wr(uchar posx,uchar posy,uchar * hanzi) //对LCD在指定位置写入单个汉字
{
uchar i;
if(posy < 4) //posy < 4 在左半部写
{
lcd_cmd_wr(0xb8+2*posx,0);
lcd_cmd_wr(0x40+16*posy,0);
for(i = 0; i < 16; i++)
{
lcd_data_wr(hanzi[i],0);
}
lcd_cmd_wr(0xb8+2*posx+1,0);
lcd_cmd_wr(0x40+16*posy,0);
for(i = 16; i < 32; i++)
{
lcd_data_wr(hanzi[i],0);
}
}
else //否则在右半部写
{
lcd_cmd_wr(0xb8+posx*2,1);
lcd_cmd_wr(0x40+16*(posy-4),1);
for(i = 0; i < 16; i++)
{
lcd_data_wr(hanzi[i],1);
}
lcd_cmd_wr(0xb8+2*posx+1,1);
lcd_cmd_wr(0x40+16*(posy-4),1);
for(i = 16; i < 32; i++)
{
lcd_data_wr(hanzi[i],1);
}
}
}
void lcd_str_wr(uchar row,uchar col,uchar n,uchar *str)
{
uchar i;
for(i = 0 ; i < n; i++)
{
if( col > 7)
{
row++;
col = col - 8;
}
lcd_hanzi_wr(row,col,str+i*32);
col++;
}
}
void lcd_bmp_wr(uchar posx,uchar posy,uchar wth,uchar hgh,uchar *bmp) //posx 取值为0~3,posy = 0~128,宽wth和高hgh必须为8的倍数
{
uchar i,j; //这里行posx如果不取8的倍数,则要另外算
hgh =hgh/8;
for(i = 0; i < hgh; i++)
{
if(posy < 64) //
{
lcd_cmd_wr(0xb8+posx+i,0);
lcd_cmd_wr(0x40+posy,0);
for(j = 0; j < wth;j++)
{
lcd_data_wr(bmp[32*i+j],0);
}
}
else
{
lcd_cmd_wr(0xb8+posx+i,1);
lcd_cmd_wr(0x40+posy-64,1);
for(j = 0; j < wth; j++)
{
lcd_data_wr(bmp[32*i+j],1);
}
}
}
}
void lcd_rol() //向上滚屏
{
uchar i;
for(i = 0; i < 64; i++)
{
lcd_cmd_wr(0xc0+i,0);
lcd_cmd_wr(0xc0+i,1);
delay(10);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -