!本博客是 《LCD1602自定义点阵字符》的学习笔记以及补(chao)充(xie)
LCD1602能存8个自定义字符, 首地址分别为0X40,0X48,0X50,0X58,0X60,0X68,0X70,0X78;
也就是说0x40到0x7F都是用来存自定义字符的
每个字符都是5x7的点阵,以0x40为例
每个地址为一行(按字节寻址),但是每一行只有第五位有效,行也是前五行有效 行也是前七行有效
存储和显示都是两步实现
一步write_command()确定地址
第二步write_data()确定操作数
write_command()和write_data()都是lcd1602经常写的函数,详见后面代码
要存储自定义字符需要两步
- 向lcd1602发送命令,定位行
- 写入每行对应的数据
比如将十储存到首地址为0x40
write_command(0x40);
write_data(0x04);
write_command(0x41);
write_data(0x04);
write_command(0x42);
write_data(0x3F);
write_command(0x43);
write_data(0x04);
write_command(0x44);
write_data(0x04);
write_command(0x45);
write_data(0x04);
write_command(0x46);
write_data(0x04);
显示自定义字符也是这个步骤
- write_command(0x80+[0x40第二行]+第几个字符);
- write_data(第几个自定义字符,也可以看ascii码表,前八个是自定义字符);
显示非自定义字符和自定义字符步骤一样
可以取模软件将自定义字符存到一个数组里面,然后两个函数用于修改和显示自定义字符
void ch_custom_char(uchar *char_lattice, uchar custom_code)
{
int i;
for(i=0;i<8;i++)
{
write_command(0x40+custom_code*8+i);
write_data(char_lattice[i]);
}
}
void display_custom_char(uchar n, uchar custom_code)
{
write_command(0x80+n);
write_data(custom_code);
}
还可以将显示字符串的函数完善一下,将自定义字符串也自动识别显示。
我就懒得实现了。
下面是一个算是完整能用的代码
#include <reg51.h>
#include<intrins.h>
#define DATA_BUS (P0)
sbit RS = P2^0;
sbit RW=P2^1;
sbit E=P2^2;
typedef unsigned char uchar;
typedef unsigned int uint;
void check_busy(void);
void LCD_init(void);
void write_command(uchar com);
void string(uchar ad ,uchar *s);
void lcd_test(void);
void delay(uint);
void write_data(uchar _data);
void ch_custom_char(uchar *char_lattice, uchar custom_code);
void display_custom_char(uchar n, uchar custom_code);
uchar lu[] = {0x00,0x01,0x01,0x05,0x01,0x07,0x00};
uchar ye2[] = {0x00,0x30,0x34,0xB4,0x28,0xFC,0x00};
void main(void)
{
LCD_init();
while(1)
{
ch_custom_char(lu,1);
display_custom_char(0,0);
ch_custom_char(ye2,2);
display_custom_char(1,2);
delay(100);
write_command(0x01);
delay(100);
}
}
void delay(uint j)
{
uchar i = 60;
for(; j>0; j--)
{
while(--i);
i = 59;
while(--i);
i = 60;
}
}
void check_busy(void)
{
do
{
DATA_BUS = 0xff;
E = 0;
RS = 0;
RW = 1;
E = 1;
_nop_();
} while(DATA_BUS & 0x80);
E = 0;
}
void write_command(uchar com)
{
check_busy();
E = 0;
RS = 0;
RW = 0;
DATA_BUS = com;
E = 1;
_nop_();
E = 0;
delay(1);
}
void write_data(uchar _data)
{
check_busy();
E = 0;
RS = 1;
RW = 0;
DATA_BUS = _data;
E = 1;
_nop_();
E = 0;
delay(1);
}
void LCD_init(void)
{
write_command(0x38);
write_command(0x0C);
write_command(0x06);
write_command(0x01);
delay(1);
}
void string(uchar ad, uchar *s)
{
write_command(ad);
while(*s>0)
{
write_data(*s++);
delay(100);
}
}
void ch_custom_char(uchar *char_lattice, uchar custom_code)
{
int i;
for(i=0;i<8;i++)
{
write_command(0x40+custom_code*8+i);
write_data(char_lattice[i]);
}
}
void display_custom_char(uchar n, uchar custom_code)
{
write_command(0x80+n);
write_data(custom_code);
}
参考博客:《LCD1602自定义点阵字符》
2023年5月10日更新
偶尔点进来看了一边,发现好像有很多错误,做了点修改
将行也是前五行有效修改为`行也是前七行有效
将
write_command(0x40);
write_data(0x40);
write_command(0x40);
write_data(0x40);
write_command(0x40);
write_data(0x40);
write_command(0x40);
write_data(0x40);
write_command(0x40);
write_data(0x40);
write_command(0x40);
write_data(0x40);
write_command(0x40);
write_data(0x40);
(我复制粘贴的时候不急的改参数了吧,应该没改错吧)
修改为
write_command(0x40);
write_data(0x04);
write_command(0x41);
write_data(0x04);
write_command(0x42);
write_data(0x3F);
write_command(0x43);
write_data(0x04);
write_command(0x44);
write_data(0x04);
write_command(0x45);
write_data(0x04);
write_command(0x46);
write_data(0x04);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)