单片机控制点阵字符显示及字模提取原理

    单片机应用经常会用到液晶显示或者LED点阵屏,是用点阵的方式显示的,要显示汉字或字符的时候会用到字模,字模就是字在点阵上显示时对应的编码。以字模的方式存储图形或者文字,每一个点都需要一个bit位来存储,该位为0代表该像素点不显示,为1代表显示。这样,一个字节就可以存储8个像素点的显示情况。

    一般采用宋体小四号的字符来做显示,这样一个英文字符刚好占8*16个像素;而汉字需要两倍,即16*16像素来显示一个汉字。这样,存储一个英文字符每行8个点需要1个字节存储,一共16行需要16个字节,

 同理一个汉字需要32个


所以如果M这个英文字符按从左到右从上到下的方式从高位到低位取模

C代码   收藏代码
  1. 0 0 0 0 0 0 0 0   
  2. 0 0 0 0 0 0 0 0   
  3. 0 0 0 0 0 0 0 0   
  4. 1 1 1 0 1 1 1 0   
  5. 0 1 1 0 1 1 0 0   
  6. 0 1 1 0 1 1 0 0   
  7. 0 1 1 0 1 1 0 0   
  8. 0 1 1 0 1 1 0 0   
  9. 0 1 0 1 0 1 0 0   
  10. 0 1 0 1 0 1 0 0   
  11. 0 1 0 1 0 1 0 0   
  12. 0 1 0 1 0 1 0 0   
  13. 0 1 0 1 0 1 0 0   
  14. 1 1 0 1 0 1 1 0   
  15. 0 0 0 0 0 0 0 0   
  16. 0 0 0 0 0 0 0 0   

 

 其中为1的地方画出了M的形状;如果把0换成空格,由1拼成的M就显示出来了:             

C代码   收藏代码
  1.                   
  2.                   
  3.                   
  4. 1 1 1   1 1 1     
  5.   1 1   1 1       
  6.   1 1   1 1       
  7.   1 1   1 1       
  8.   1 1   1 1       
  9.   1   1   1       
  10.   1   1   1       
  11.   1   1   1       
  12.   1   1   1       
  13.   1   1   1       
  14. 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代码   收藏代码
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. unsigned char am[] = {0x00,0x00,0x00,0xEE,0x6C,0x6C,0x6C,0x6C,0x54,0x54,0x54,0x54,0x54,0xD6,0x00,0x00}; //M  
  5.   
  6. void showM(){  
  7.     int i,j;  
  8.     unsigned char t;  
  9.     for (i = 0; i < 16; ++i) {   //对于每一行  
  10.         t = am[i];              //取出代表这一行点的数据  
  11.         for (j = 0; j < 8; ++j) {    //对于这行中的每个点  
  12.             if (0x80 & t) {     //从左到右如果最左位1,则显示  
  13.                 printf("MM");  
  14.             }else{  
  15.                 printf("  ");  
  16.             }  
  17.             t <<= 1;          //将右边的数据往左移动  
  18.         }  
  19.         printf("\n");  
  20.     }  
  21. }  
  22.   
  23. int main(void) {  
  24.     showM();  
  25.     return EXIT_SUCCESS;  
  26. }  

 

 

 

 然而,对于中文字符,每个汉字每行有16个像素,需要2个字节,所以每行需要对两个字节数据进行打印,所以要增加一个for循环:
C代码   收藏代码
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. unsigned char ch[] = {  
  5.         /*--  文字:  播  --*/  
  6.         /*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/  
  7.         0x20,0x3C,0x27,0xC0,0x22,0x48,0xF9,0x50,0x27,0xFE,0x20,0xE0,0x29,0x50,0x32,0x4E,  
  8.         0x6F,0xFC,0xA2,0x48,0x22,0x48,0x23,0xF8,0x22,0x48,0x22,0x48,0xA3,0xF8,0x42,0x08  
  9. };  
  10.   
  11. void showM()  
  12. {  
  13.     int i, j;  
  14.     unsigned char t, u;     //分别表示一个汉字每行的左半边8像素和右半边8像素  
  15.     for (i = 0; i < 16; ++i)  
  16.     {   //对于每一行  
  17.         t = ch[i * 2];              //取出代表这一行点的数据  
  18.         u = ch[i * 2 + 1];  
  19.         for (j = 0; j < 8; ++j)//打印左半边像素  
  20.         {   //对于这行中的每个点  
  21.             if (0x80 & t)  
  22.             {       //从左到右如果最左位1,则显示  
  23.                 printf("MM");  
  24.             }  
  25.             else  
  26.             {  
  27.                 printf("  ");  
  28.             }  
  29.             t <<= 1;          //将右边的数据往左移动  
  30.         }  
  31.         for (j = 0; j < 8; ++j)//打印右半边像素  
  32.         {   //对于这行中的每个点  
  33.             if (0x80 & u)  
  34.             {       //从左到右如果最左位1,则显示  
  35.                 printf("MM");  
  36.             }  
  37.             else  
  38.             {  
  39.                 printf("  ");  
  40.             }  
  41.             u <<= 1;          //将右边的数据往左移动  
  42.         }  
  43.         printf("\n");  
  44.     }  
  45. }  
  46.   
  47. int main(void) {  
  48.     showM();  
  49.     return EXIT_SUCCESS;  
  50. }  
 打印结果:
C代码   收藏代码
  1.     MM              MMMMMMMM      
  2.     MM    MMMMMMMMMM              
  3.     MM      MM    MM    MM        
  4. MMMMMMMMMM    MM  MM  MM          
  5.     MM    MMMMMMMMMMMMMMMMMMMM    
  6.     MM          MMMMMM            
  7.     MM  MM    MM  MM  MM          
  8.     MMMM    MM    MM    MMMMMM    
  9.   MMMM  MMMMMMMMMMMMMMMMMMMM      
  10. MM  MM      MM    MM    MM        
  11.     MM      MM    MM    MM        
  12.     MM      MMMMMMMMMMMMMM        
  13.     MM      MM    MM    MM        
  14.     MM      MM    MM    MM        
  15. MM  MM      MMMMMMMMMMMMMM        
  16.   MM        MM          MM        
 这样就显示了一个汉字。

 

 

 

  • 下载次数: 16



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();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值