单片机应用经常会用到液晶显示或者LED点阵屏,是用点阵的方式显示的,要显示汉字或字符的时候会用到字模,字模就是字在点阵上显示时对应的编码。以字模的方式存储图形或者文字,每一个点都需要一个bit位来存储,该位为0代表该像素点不显示,为1代表显示。这样,一个字节就可以存储8个像素点的显示情况。
一般采用宋体小四号的字符来做显示,这样一个英文字符刚好占8*16个像素;而汉字需要两倍,即16*16像素来显示一个汉字。这样,存储一个英文字符每行8个点需要1个字节存储,一共16行需要16个字节,
同理一个汉字需要32个
所以如果M这个英文字符按从左到右从上到下的方式从高位到低位取模
C代码
-
0 0 0 0 0 0 0 0
-
0 0 0 0 0 0 0 0
-
0 0 0 0 0 0 0 0
-
1 1 1 0 1 1 1 0
-
0 1 1 0 1 1 0 0
-
0 1 1 0 1 1 0 0
-
0 1 1 0 1 1 0 0
-
0 1 1 0 1 1 0 0
-
0 1 0 1 0 1 0 0
-
0 1 0 1 0 1 0 0
-
0 1 0 1 0 1 0 0
-
0 1 0 1 0 1 0 0
-
0 1 0 1 0 1 0 0
-
1 1 0 1 0 1 1 0
-
0 0 0 0 0 0 0 0
-
0 0 0 0 0 0 0 0
其中为1的地方画出了M的形状;如果把0换成空格,由1拼成的M就显示出来了:
C代码
-
-
-
-
1 1 1 1 1 1
-
1 1 1 1
-
1 1 1 1
-
1 1 1 1
-
1 1 1 1
-
1 1 1
-
1 1 1
-
1 1 1
-
1 1 1
-
1 1 1
-
1 1 1 1 1
因此,我们要记录16行中每一行由0和1组成的一字节整数的值,就记录了这张位图;
如第1,2,3行是00000000,它的值为0,第四行是11101110,用十六进制表示就是0xee;
以此类推,得到16个单字节整数:0x00,0x00,0x00,0xEE,0x6C,0x6C,0x6C,0x6C,0x54,0x54,0x54,0x54,0x54,0xD6,0x00,0x00
这些数组可以通过软件计算出来,我们只需要在单片机中通过代码读取这些数据就可以显示出来了,
解析过程与编码这些数据是刚好相反的。
C代码
-
#include
-
#include
-
-
unsigned char am[] = {0x00,0x00,0x00,0xEE,0x6C,0x6C,0x6C,0x6C,0x54,0x54,0x54,0x54,0x54,0xD6,0x00,0x00};
-
-
void showM(){
-
int i,j;
-
unsigned char t;
-
for (i = 0; i < 16; ++i) {
-
t = am[i];
-
for (j = 0; j < 8; ++j) {
-
if (0x80 & t) {
-
printf("MM");
-
}else{
-
printf(" ");
-
}
-
t <<= 1;
-
}
-
printf("
");
-
}
-
}
-
-
int main(void) {
-
showM();
-
return EXIT_SUCCESS;
-
}
然而,对于中文字符,每个汉字每行有16个像素,需要2个字节,所以每行需要对两个字节数据进行打印,所以要增加一个for循环:
C代码
-
#include
-
#include
-
-
unsigned char ch[] = {
-
-
-
0x20,0x3C,0x27,0xC0,0x22,0x48,0xF9,0x50,0x27,0xFE,0x20,0xE0,0x29,0x50,0x32,0x4E,
-
0x6F,0xFC,0xA2,0x48,0x22,0x48,0x23,0xF8,0x22,0x48,0x22,0x48,0xA3,0xF8,0x42,0x08
-
};
-
-
void showM()
-
{
-
int i, j;
-
unsigned char t, u;
-
for (i = 0; i < 16; ++i)
-
{
-
t = ch[i * 2];
-
u = ch[i * 2 + 1];
-
for (j = 0; j < 8; ++j)
-
{
-
if (0x80 & t)
-
{
-
printf("MM");
-
}
-
else
-
{
-
printf(" ");
-
}
-
t <<= 1;
-
}
-
for (j = 0; j < 8; ++j)
-
{
-
if (0x80 & u)
-
{
-
printf("MM");
-
}
-
else
-
{
-
printf(" ");
-
}
-
u <<= 1;
-
}
-
printf("
");
-
}
-
}
-
-
int main(void) {
-
showM();
-
return EXIT_SUCCESS;
-
}
打印结果:
C代码
-
MM MMMMMMMM
-
MM MMMMMMMMMM
-
MM MM MM MM
-
MMMMMMMMMM MM MM MM
-
MM MMMMMMMMMMMMMMMMMMMM
-
MM MMMMMM
-
MM MM MM MM MM
-
MMMM MM MM MMMMMM
-
MMMM MMMMMMMMMMMMMMMMMMMM
-
MM MM MM MM MM
-
MM MM MM MM
-
MM MMMMMMMMMMMMMM
-
MM MM MM MM
-
MM MM MM MM
-
MM MM MMMMMMMMMMMMMM
-
MM MM MM
这样就显示了一个汉字。
public class en {
public static char am[] = {0x00,0x00,0x00,0xEE,0x6C,0x6C,0x6C,0x6C,0x54,0x54,0x54,0x54,0x54,0xD6,0x00,0x00}; //M
public static void showM(){
int i,j;
char t;
for (i = 0; i < 16; ++i) { //对于每一行
t = am[i]; //取出代表这一行点的数据
for (j = 0; j < 8; ++j) { //对于这行中的每个点
if ((0x80&t)>0) { //从左到右如果最左位1,则显示
System.out.print("MM");
}else{
System.out.print(" ");
}
t <<= 1;//将右边的数据往左移动
}
System.out.println();
}
}
public static void main(String[] args) {
showM();
}
}
public class cn {
public static char ch[] = {
/*-- 文字: 播 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x20, 0x3C, 0x27, 0xC0, 0x22, 0x48, 0xF9, 0x50, 0x27, 0xFE, 0x20, 0xE0, 0x29, 0x50, 0x32, 0x4E, 0x6F, 0xFC,
0xA2, 0x48, 0x22, 0x48, 0x23, 0xF8, 0x22, 0x48, 0x22, 0x48, 0xA3, 0xF8, 0x42, 0x08 };
public static void showM() {
int i, j;
char t, u; //分别表示一个汉字每行的左半边8像素和右半边8像素
for (i = 0; i < 16; ++i) { // 对于每一行
t = ch[i * 2]; // 取出代表这一行点的数据
u = ch[i * 2 + 1];
for (j = 0; j < 8; ++j)// 打印左半边像素
{ // 对于这行中的每个点
if ((0x80 & t) > 1) { // 从左到右如果最左位1,则显示
System.out.print("MM");
} else {
System.out.print(" ");
}
t <<= 1; // 将右边的数据往左移动
}
for (j = 0; j < 8; ++j)// 打印右半边像素
{ // 对于这行中的每个点
if ((0x80 & u) > 1) { // 从左到右如果最左位1,则显示
System.out.print("MM");
} else {
System.out.print(" ");
}
u <<= 1; // 将右边的数据往左移动
}
System.out.println();
}
}
public static void main(String[] args) {
showM();
}
}