lcd1602能否显示汉字
1602液晶是字符型液晶,总共有2行,每行16个字符。每个字符有效的可显示字体是5*8点阵字体。所以通常无法显示中文。中文的显示必须选择图形点阵型液晶。
特别地:是指,显示“年月日”,之类的简单的汉字吧?最多支持8个cgram字符。可以自己做。调用字模代码0-7。如:“年”的cgram单元数据为:0fh,09h,0fh,09h,0fh,09h,13h,00h。这8个字节写入cgram单元00h-07h。调用字符代码0。可以看到中文“年”。
lcd1602显示汉字的概念
首先:我们要弄清楚一个概念,其实我们使用1602显示中文汉字,就是利用其内部的自定义字节空间。
第一行的内容对应ddram中80h到8fh内容 第二行的内容对应ddram中c0h到cfh内容
通过查看lcd1602的用户手册,里面提到当我们需要想cgram写入数据时,我们需要先写入cgram的地址,从手册上可知,cgram的地址为0x40.所以当我们要写入数据时,要先写入一条地址命令 write_com(0x040);
然后把你要写入的数据通过写数据命令写入 write_date( 你要写得数据);
把你要显示汉字的代码存放在cgram里,就相当于其他常用字符一样固定在lcd里面了,把你要显示汉字的代码存放在cgram里,就相当于其他常用字符一样固定在lcd里面了,就相当于把你要显示汉字的代码存放在cgram里,就相当于其他常用字符一样固定在lcd里面了,我们都知道lcd1602内部有一个64字节的自定义cgram,那么好,我们就是要利用自定义字节来达到显示汉字的效果。
我们知道一个字符占8个字节,所以在cgram能够存放8个字符。 也就是说,这个64字节的cgram是给我们提供写入数据的, 那么我们怎么把我们要的汉字写入cgram呢?
ddram显示用ram,直接和屏幕上的点相对应。屏幕上的一个点和ddram中的一个位对应,字符屏的ddram和图形屏的ddram有一点点区别。
cgrom 中存储了一些标准的 字符的字模编码,是液晶屏出厂时固化在控制芯片中的,用户不能改变其中的存储内容,只能读取调用,包含有标准的ascii码、日文字符和希腊文字符。
cgram 是控制芯片留给用户,用以存储用户自己设计的字模编码。
字模编码都要先被读取到对应的ddram中,经中转以后,屏幕的相应位置才显示出字符。对于字符屏,要显示某个字符时,往ddram里写字符的索引(一般都是ascii码)就可以完成显示。
lcd1602显示汉字的程序
汉字的字模:
就是显示出来的汉子字体结构。
要定义字模就需要知道1602的cg ram地址和显示字符的地址 dd ram :
1 2 3 4 5 6 7 8 9 10 11 12 1314 15 16
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
第一行第一个字符的地址是( 0x80) ,后面的字符地址以此类推
第二行第一个字符的地址为 ( 0x80 + 0x40),需要在第一行的基地址后面加上一个偏移 量0x40,后面的地址在此基址上再依次加一。
void delay(unsigned int time_i)
{
int i;
for (;tim》0;tim--)
{
for (i=0;i《10;i++);
}
}
void command_out (char out_data)
{
rw=0;
rs=0;
en=1;
db=out_data;
en=0;
delay(10);
}
void outd(char out_data)
{
rs=1;
rw=0;
en=1;
db= out_data;
en=0;
delay(10);
}
outi()是写入指令的函数, outd()是写入数据的函数。 如:
左上角第一个5*7的显示数据为:
0x00,0x01,0x81,0x12,0x24,0x41,0x81,0x10 蓝色区域的相应位为1
这样就可以写出全部4个5*7点阵的显示数据了,把它封装在一个数组中,如数组,
hanzi[]={0x00,0x01,0x81,0x12,0x24,0x41,0x81,0x10, …… …… …… }
之后利用命令:
outi(0x40);
for (i=0;i《64;i++)
{
outd(neu[i]);
}
将这个数组中的数据赋值到1602内部cgram中。完成后,再设置数据在1602上的 显示地址,根据图1的结构,设置好位置,如在第一行第一个字符和第二个字符以及第二行
第一个字符和第二个字符处显示:
command_out (0x80+0x00);
for (i=0;i《4;i++)
{
data_out (i);
}
command_out(0x80+0x40);
for (i=4;i《8;i++)
{ data_out(i);
}
command_out()的作用是设置显示的起始地址,data_out()的作用是将hanzi[]数组中的16 进制数据发送出去,每一个16进制数字对应之5*7点阵上的每一行内容。第1行第1个字 符需要8个16进制数据,第1行第2个字符处也需要816进制数据。还有第2行的两个字 符点阵,这样显示一个汉字需要32个16进制数据。
下面列举一个实例(proteus仿真通过)
//*************************************************************************************** //
硬件连接:1602vdd接5v,vo接地,bl1接5v,bl2接地,8根数据线接p0口,rs rw e分别接p2.0、p2.1、p.4口
//***************************************************************************************//
#include 《reg52.h》
#include 《string.h》
#define busy 0x80 //用于检测lcm状态字中的busy标识
#define lcm_data p0 ;
sbit lcm_rs=p2^0; //寄存器选择
sbit lcm_rw=p2^1; //读/写控制
sbit lcm_e=p2^4; //读/写使能
int i,j;
//自定义字符列表 //
=====================================================================================
unsigned char character0[8] = {0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02}, //年
character1[8] = {0x0f,0x09,0x0f,0x09,0x0f,0x09,0x0b,0x11}, //月
character2[8] = {0x0f,0x09,0x09,0x09,0x0f,0x09,0x09,0x0f}, //日
charactern[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //日
//==========================================================
//=========================================================
//延时程序
//=======================================================
void delay5ms(void)
{
unsigned long int tempcyc = 5552;
while(tempcyc--);
}
void delay400ms(void)
{
unsigned char tempcyca = 5;
unsigned int tempcycb;
while(tempcyca--)
{
tempcycb=7269;
while(tempcycb--);
};
}
//===================================================================
//读写子程序
//=================================================================
//读数据
unsigned char readdatalcm(void)
{
lcm_rs = 1;
lcm_rw = 1;
lcm_e = 1;
lcm_e = 0;
for(i=0;i《100;i++);
lcm_e = 1;
return(lcm_data);
}
//读状态
unsigned char readstatuslcm(void)
{
lcm_data = 0xff;
lcm_rs = 0;
lcm_rw = 1;
lcm_e = 1;
lcm_e = 0;
for(i=0;i《100;i++);
lcm_e = 1;
//while (lcm_data & busy); //检测忙信号
return(lcm_data);
}
//写数据
void writedatalcm(unsigned char wdlcm)
{
readstatuslcm(); //检测忙
lcm_data = wdlcm;
lcm_rs = 1;
lcm_rw = 0;
lcm_e = 1;
lcm_e = 0; //若晶振速度太高可以在这后加小的延时
for(i=0;i《100;i++);//延时
lcm_e = 1;
}
//写指令
void writecommandlcm(unsigned char wclcm,buysc) //buysc为0时忽略忙检测
{
if (buysc) readstatuslcm(); //根据需要检测忙
lcm_data = wclcm;
lcm_rs = 0;
lcm_rw = 0;
lcm_e = 1;
lcm_e = 0;
for(i=0;i《100;i++);
lcm_e = 1;
}
//===========================================================
//初始化子程序
//===================================================================
void lcminit(void) //lcm初始化
{
lcm_data = 0;
writecommandlcm(0x38,0); // 三次显示模式设置,不检测忙信号
delay5ms();
writecommandlcm(0x38,0);
delay5ms();
writecommandlcm(0x38,0);
delay5ms();
writecommandlcm(0x38,1); // 显示模式设置,开始要求每次检测忙信号
delay5ms();
writecommandlcm(0x08,1); // 关闭显示
delay5ms();
writecommandlcm(0x01,1); // 清屏 delay5ms();
writecommandlcm(0x06,1); // 显示光标移动设置
delay5ms();
writecommandlcm(0x0c,1); // 显示开及光标设置
delay5ms();
}
//================================================================
//按指定位置显示一个字符
//===================================================================
void displayonechar(unsigned char x, unsigned char y, unsigned char ddata)
{
y &= 0x1;
x &= 0xf; //限制x不能大于15,y不能大于1
if (y) x |= 0x40; //当要显示第二行时地址码+0x40;
x |= 0x80; //算出指令码
writecommandlcm(x, 0); //这里不检测忙信号,发送地址码
writedatalcm(ddata);
}
//=================================================================
//按指定位置显示一串字符
//void displaylistchar(unsigned char x, unsigned char y, unsigned char code *ddata)
//说明: x(0-15):x参数 y(0-1):y参数 ddata(字符串):要显示的内容(英文、数字、符号)
//========================================================================
void displaylistchar(unsigned char x, unsigned char y, unsigned char code *ddata)
{
unsigned char listlength,j; listlength = strlen(ddata);
y &= 0x1;
x &= 0xf; //限制x不能大于15,y不能大于1
if (x 《= 0xf) //x坐标应小于0xf
{
for(j=0;j《listlength;j++)
{
displayonechar(x, y, ddata[j]); //显示单个字符 x++;
}
}
}
//==========================================================
//显示自定义字符
//void mychar(char xx,char yy,unsigned char *character,unsigned char saveto)
//说明:xx(0-15):为x参数.yy(0-1):y参数.character:要显示的字符的列表地址,在程序前面有定义
//saveto(1-7)为字符保存的ram,每屏最多显示7个自定义字符 //(0x00-0x0h是自定义字符)
//=============================================================
void mychar(char xx,char yy,unsigned char *character,unsigned char saveto)
{
unsigned char add = (saveto《《3) | 0x40;
unsigned char t; //临时变量,每一行的值 /*
t=*(character+0);
writecommandlcm(add, 0); //第1行 writedatalcm(t); t=*(character+1);
writecommandlcm(add+1, 0); //第2行 writedatalcm(t); t=*(character+2);
writecommandlcm(add+2, 0); //第3行 writedatalcm(t); t=*(character+3);
writecommandlcm(add+3, 0); //第4行 writedatalcm(t); t=*(character+4);
writecommandlcm(add+4, 0); //第5行 writedatalcm(t); t=*(character+5);
writecommandlcm(add+5, 0); //第6行 writedatalcm(t); t=*(character+6);
writecommandlcm(add+6, 0); //第7行 writedatalcm(t); t=*(character+7);
writecommandlcm(add+7, 0); //第8行 writedatalcm(t); */
for(i = 0;i《8;i++)
{
writecommandlcm(add+i, 0);
writedatalcm(*(character+i));
}
displayonechar(xx,yy,saveto); //显示字符 }
//===============================================================
//主函数
//=========================================================
main()
{
delay400ms();
lcminit();
delay400ms(); //1602初始化
while(1)
{
displaylistchar(0,0,“this is listchar”); displaylistchar(0,1,“!”);
for(j=0;j《30;j++)for(i=0;i《30000;i++); writecommandlcm(0x01,1); //清屏
delay5ms();
displaylistchar(0,0,“this is onechar:”);
displayonechar(0,1,0x4f);
displayonechar(1,1,0x6e);
displayonechar(2,1,0x65);
displayonechar(3,1,0x21);
for(j=0;j《30;j++)for(i=0;i《30000;i++);
writecommandlcm(0x01,1); //清屏
delay5ms();
displaylistchar(0,0,“this is mychar:”);
mychar(0,1, character0,1);
mychar(1,1, character1,2);
mychar(2,1, character2,3);
for(j=0;j《30;j++)for(i=0;i《30000;i++);
writecommandlcm(0x01,1); //清屏 delay5ms();
}
}
FIFO的一些基础知识
电子标识在ETC上车后还有机会
【短视频】MPS 电源小课堂第三季第十四话:不是所有的升压都是Boost
码垛机器人市场迅速扩大 机器人包装带来更多新的优势
首例自动驾驶汽车撞死行人事故
lcd1602能显示汉字吗_lcd1602显示汉字程序
力合微:成功推出家庭能源路由器高集成通信SoC芯片
SpaceX使用猎鹰9号火箭成功进行第24批星链发射
中兴通讯成功地完成一款支持下行Cat-18终端的研发
知用CYBERTEK高压差分探头DP6070的产品特性及其应用
基于BP01型压力传感器在便携血压计中应用
电竞神车免费送?机械师双十一壕礼送不停!
这部国产智能眼镜很强大,实力不输国外产品
小米电视一枝独秀 互联网电视企业难自保
疫情放开关键期 医疗资源快速优化方案
智能配电监测系统能给我们带来什么
功率放大器在超声电机正反向运动中的应用
复合金属巅峰之作:华为nova 2 Plus魔镜版工艺大起底
2019年一季度电子信息制造业运行情况
夏普正式拆分半导体业务