!本博客是 《LCD1602自定义点阵字符》的学习笔记以及补(chao)充(xie)
LCD1602能存8个自定义字符, 首地址分别为0X40,0X48,0X50,0X58,0X60,0X68,0X70,0X78;
也就是说0x40到0x7F都是用来存自定义字符的
每个地址为一行(按字节寻址),但是每一行只有第五位有效,行也是前五行有效
存储和显示都是两步实现
一步write_command()确定地址
第二步write_data()确定操作数
write_command()和write_data()都是lcd1602经常写的函数,详见后面代码
要存储自定义字符需要两步
比如将十储存到首地址为0x40
write_command(0x40); // line1
write_data(0x40);
write_command(0x40); // line2
write_data(0x40);
write_command(0x40); // line3
write_data(0x40);
write_command(0x40); // line4
write_data(0x40);
write_command(0x40); // line5
write_data(0x40);
write_command(0x40); // line6
write_data(0x40);
write_command(0x40); // line7
write_data(0x40);
显示自定义字符也是这个步骤
可以取模软件将自定义字符存到一个数组里面,然后两个函数用于修改和显示自定义字符
// custom_code is between on 0 and 7
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); // set to the i-th line
write_data(char_lattice[i]); // write a line bit
}
}
void display_custom_char(uchar n, uchar custom_code)
{
write_command(0x80+n); // set to the n-th char
write_data(custom_code); // display the custom_code char
}
还可以将显示字符串的函数完善一下,将自定义字符串也自动识别显示。
我就懒得实现了。
下面是一个算是完整能用的代码
/* Main.c file generated by New Project wizard
*
* Created: 周四 5月 27 2021
* Processor: 80C31
* Compiler: Keil for 8051
*/
#include
#include
#define DATA_BUS (P0)
// Define P3 pins
sbit RS = P2^0;
sbit RW=P2^1;
sbit E=P2^2;
// Define new types
typedef unsigned char uchar;
typedef unsigned int uint;
// Function Prototypes
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};/*"业",2*/
uchar ye2[] = {0x00,0x30,0x34,0xB4,0x28,0xFC,0x00};/*"业",2*/
void main(void)
{
LCD_init();
while(1)
{ //string(0x80,"1900301517!");
//string(0xC0," LuHongye");
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);
}
}
/*******************************************
LCD1602 Driver mapped as IO peripheral
*******************************************/
// Delay
void delay(uint j)
{
uchar i = 60;
for(; j>0; j--)
{
while(--i);
i = 59;
while(--i);
i = 60;
}
}
// Test the Busy bit
void check_busy(void)
{
do
{
DATA_BUS = 0xff;
E = 0;
RS = 0;
RW = 1;
E = 1;
_nop_();
} while(DATA_BUS & 0x80);
E = 0;
}
// Write a command
void write_command(uchar com)
{
check_busy();
E = 0;
RS = 0;
RW = 0;
DATA_BUS = com;
E = 1;
_nop_();
E = 0;
delay(1);
}
// Write Data
void write_data(uchar _data)
{
check_busy();
E = 0;
RS = 1;
RW = 0;
DATA_BUS = _data;
E = 1;
_nop_();
E = 0;
delay(1);
}
// Initialize LCD controller
void LCD_init(void)
{
write_command(0x38); // 8-bits, 2 lines, 7x5 dots
write_command(0x0C); // no cursor, no blink, enable display
write_command(0x06); // auto-increment on
write_command(0x01); // clear screen
delay(1);
}
// Display a string
void string(uchar ad, uchar *s)
{
write_command(ad);
while(*s>0)
{
write_data(*s++);
delay(100);
}
}
// custom_code is between on 0 and 7
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); // set to the i-th line
write_data(char_lattice[i]); // write a line bit
}
}
void display_custom_char(uchar n, uchar custom_code)
{
write_command(0x80+n); // set to the n-th char
write_data(custom_code); // display the custom_code char
}
参考博客:《LCD1602自定义点阵字符》