单片机控制点阵字符显示及字模提取原理
程序员文章站
2024-03-15 14:01:41
...
单片机应用经常会用到液晶显示或者LED点阵屏,是用点阵的方式显示的,要显示汉字或字符的时候会用到字模,字模就是字在点阵上显示时对应的编码。以字模的方式存储图形或者文字,每一个点都需要一个bit位来存储,该位为0代表该像素点不显示,为1代表显示。这样,一个字节就可以存储8个像素点的显示情况。
一般采用宋体小四号的字符来做显示,这样一个英文字符刚好占8*16个像素;而汉字需要两倍,即16*16像素来显示一个汉字。这样,存储一个英文字符每行8个点需要1个字节存储,一共16行需要16个字节,
同理一个汉字需要32个
所以如果M这个英文字符按从左到右从上到下的方式从高位到低位取模
- 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就显示出来了:
- 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
这些数组可以通过软件计算出来,我们只需要在单片机中通过代码读取这些数据就可以显示出来了,
解析过程与编码这些数据是刚好相反的。
- #include <stdio.h>
- #include <stdlib.h>
- unsigned char am[] = {0x00,0x00,0x00,0xEE,0x6C,0x6C,0x6C,0x6C,0x54,0x54,0x54,0x54,0x54,0xD6,0x00,0x00}; //M
- 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) { //从左到右如果最左位1,则显示
- printf("MM");
- }else{
- printf(" ");
- }
- t <<= 1; //将右边的数据往左移动
- }
- printf("\n");
- }
- }
- int main(void) {
- showM();
- return EXIT_SUCCESS;
- }
- #include <stdio.h>
- #include <stdlib.h>
- unsigned 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
- };
- void showM()
- {
- int i, j;
- unsigned 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,则显示
- printf("MM");
- }
- else
- {
- printf(" ");
- }
- t <<= 1; //将右边的数据往左移动
- }
- for (j = 0; j < 8; ++j)//打印右半边像素
- { //对于这行中的每个点
- if (0x80 & u)
- { //从左到右如果最左位1,则显示
- printf("MM");
- }
- else
- {
- printf(" ");
- }
- u <<= 1; //将右边的数据往左移动
- }
- printf("\n");
- }
- }
- int main(void) {
- showM();
- return EXIT_SUCCESS;
- }
- 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
推荐阅读