#include <REG51.H> #include <ABSACC.H> #define uchar unsigned char #define uint unsigned int //左半部 #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[] = { 0x00,0x20,0x20,0x90,0xD2,0x34,0x00,0xF0,0x10,0x50,0xFF,0x28,0x08,0xF8,0x00,0x00, 0x04,0x02,0x01,0x00,0x3F,0x01,0x00,0x01,0x02,0x02,0x7F,0x01,0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0xF0,0xAC,0x8B,0xF8,0x00,0x80,0x78,0x04,0x3C,0x40,0x40,0x40,0x00, 0x01,0x21,0x19,0x07,0x02,0x10,0x3F,0x01,0x1E,0x12,0x12,0x11,0x0F,0x00,0x00,0x00, 0x00,0x00,0xF0,0x10,0x90,0x90,0xFF,0x48,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x03,0x02,0x02,0x1F,0x21,0x21,0x21,0x20,0x20,0x20,0x1C,0x00,0x00, 0x00,0x00,0xF8,0x24,0xFC,0x00,0x10,0x10,0x50,0x92,0x14,0xC8,0x08,0x88,0x00,0x00, 0x20,0x18,0x07,0x11,0x3F,0x00,0x00,0x1F,0x14,0x12,0x09,0x0A,0x08,0x1F,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x90,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; code uchar hanzi2[] = { 0x00,0x00,0x00,0xFC,0x80,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, 0x08,0x04,0x03,0x00,0x10,0x11,0x0A,0x04,0x03,0x00,0x03,0x04,0x18,0x10,0x10,0x00, 0x00,0xC0,0xA0,0x98,0x86,0x60,0x10,0x40,0x40,0xC0,0x3E,0x20,0x20,0xE0,0x00,0x00, 0x00,0x0C,0x0A,0x05,0x04,0x23,0x12,0x08,0x06,0x01,0x08,0x10,0x0E,0x01,0x00,0x00, 0x00,0x40,0x64,0x54,0xCC,0x22,0x32,0x60,0x00,0xF8,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x10,0x12,0x12,0x0F,0x09,0x05,0x04,0x00,0x03,0x10,0x20,0x7F,0x00,0x00,0x00, 0x00,0x80,0x80,0x80,0x90,0x90,0x7E,0x48,0xC8,0x60,0x50,0x4C,0x40,0x40,0x00,0x00, 0x00,0x10,0x10,0x08,0x08,0x04,0x3F,0x49,0x44,0x44,0x42,0x38,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x90,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; code uchar hanzi3[] = { 0x00,0x00,0xC0,0x00,0xC4,0x08,0x18,0x00,0xC0,0x30,0x0C,0x00,0x40,0x40,0x80,0x00, 0x00,0x13,0x10,0x08,0x08,0x05,0x02,0x05,0x04,0x08,0x0A,0x0C,0x08,0x00,0x00,0x00, 0x00,0x00,0x08,0x08,0x08,0x88,0x48,0xE4,0x14,0x8C,0x84,0x04,0x04,0x04,0x00,0x00, 0x00,0x04,0x04,0x02,0x01,0x00,0x00,0x3F,0x00,0x00,0x00,0x01,0x03,0x06,0x00,0x00, 0x08,0x08,0x08,0xC8,0x28,0x28,0xE8,0x08,0x08,0xF8,0x04,0x04,0x04,0x04,0x04,0x00, 0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x10,0x20,0x3F,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x80,0x70,0x00,0x00,0xFE,0x00,0x00,0x00,0xC8,0x08,0x10,0x30,0x00,0x00, 0x00,0x40,0x41,0x20,0x20,0x10,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xF8,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x31,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xF8,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x31,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; code uchar hanzi4[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x18,0x04,0x54,0xFC,0xAA,0xAB,0xFE,0xAA,0x82,0x8A,0x06,0x00,0x00,0x00, 0x00,0x08,0x09,0x05,0x33,0x09,0x28,0x7E,0x04,0x15,0x32,0x06,0x04,0x04,0x04,0x00, 0x00,0x00,0x00,0x20,0x20,0x20,0x21,0xF2,0x16,0x10,0x10,0x10,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x20,0x22,0x22,0x22,0x1F,0x11,0x11,0x11,0x10,0x10,0x10,0x10,0x00, }; code uchar bmp[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0xF0,0xF0,0xF0, 0xE0,0xC0,0x00,0x00,0x80,0xC0,0xE0,0xE0,0xE0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xE0,0xF0,0xF8,0xF8,0xF8,0xF8,0xF0,0xE3,0x0F,0x1F,0x1F,0x1F,0x1F, 0x1F,0x0F,0x00,0x00,0x1F,0x1F,0x3F,0x3F,0x3F,0x1F,0xCF,0xE7,0xE0,0xE0,0xE0,0xE0, 0x00,0x00,0x00,0x03,0x07,0x07,0x0F,0x8F,0xC7,0xC7,0xE3,0x70,0x78,0x7C,0x7E,0x1F, 0x1F,0xFF,0xFF,0x7F,0xFF,0xFE,0xFC,0xF8,0x70,0xE3,0xCF,0x9F,0x9F,0x3F,0x1F,0x1F, 0x00,0x00,0x00,0x00,0x00,0x3E,0x7F,0xFF,0xFF,0xF1,0xE0,0xCE,0xCE,0xDF,0xCE,0xC0, 0xC0,0xFF,0xF0,0xC0,0xCF,0xCF,0xCF,0xCF,0xC0,0xE0,0xFF,0xFF,0xFF,0xFF,0x7E,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,5,hanzi1); // 行,左右LCD的汉字个数(<4就写在左边.否则就写在右边),表示这一行写几个汉字,汉字的代码 delay(100); lcd_str_wr(1,1,5,hanzi2); delay(100); lcd_str_wr(2,1,5,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 < 2000; 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++) //这个FOR 循环语句是为了清楚不显示字的部分 { 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) //行,左右LCD的汉字个数(<4就写在左边.否则就写在右边),表示这一行写几个汉字,第几个汉字的代码 { uchar i; for(i = 0 ; i < n; i++) { if( col > 7) { row++; //表示行加一行 col = col - 8; //换了一行,就相应的每行汉字的计算个数也应该相应的从0开始重新计数 } 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的左,; 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); // 只要D7是高电平,就可以了,b0和c0都是一样的. lcd_cmd_wr(0xc0+i,1); // ....................................... delay(8); } }