如何在彩屏上显示汉字(取模的单汉字显示,bin文件形式的单汉字、多汉字显示)

本文详细介绍了如何在彩屏上显示汉字的方法,包括使用取模软件生成汉字数据、结合打点函数显示单个汉字的过程,以及通过操作BIN文件实现多个汉字的连续显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在我们学习彩屏的过程中,想要在彩屏上显示汉字。所以,读者一定要清楚地知道,其原理无非就是往屏上打点。只要知道核心是往彩屏上执行打点函数,一切都好做了,直入正题!

 

单汉字显示(取模形式)

首先彩屏是没有汉字库的,所以只能自己去百度上下载一个汉字取模软件。我用的是

我们以64*64的字体为例来讲解,通过软件生成一个汉字,比如

/*************************************************************/

/*--  文字:  深  --*/

unsigned char shen_zimo[]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xFC,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF8,0x00,0x00,0x07,0xC0,
0x00,0x7F,0x80,0xFC,0x00,0x00,0x0F,0xE0,0x00,0x7F,0xC0,0xFF,0xFF,0xFF,0xFF,0xF0,
0x00,0x3F,0xE0,0xFF,0xFF,0xFF,0xFF,0xF8,0x00,0x1F,0xE1,0xFC,0x00,0x00,0x1F,0xF8,
0x00,0x1F,0xE1,0xFC,0x00,0x00,0x3F,0xC0,0x00,0x0F,0xE3,0xFC,0x00,0x00,0x3F,0x80,
0x00,0x0F,0xFF,0xFD,0xE0,0x00,0x3F,0x00,0x00,0x07,0xFF,0xFB,0xF8,0x7E,0x7E,0x00,
0x00,0x00,0x3F,0xFB,0xFC,0x7F,0xFC,0x00,0x00,0x00,0x3E,0x07,0xFE,0x1F,0xF0,0x00,
0x00,0x00,0x7C,0x07,0xFE,0x0F,0xFC,0x00,0x3C,0x00,0x7C,0x0F,0xF8,0x07,0xFE,0x00,
0x3F,0x00,0x7C,0x1F,0xE0,0x03,0xFF,0x00,0x3F,0xC0,0xFC,0x3F,0xC7,0x81,0xFF,0x80,
0x1F,0xE0,0xF8,0x3F,0x87,0xE0,0xFF,0x80,0x0F,0xF8,0xF8,0x7F,0x07,0xF8,0x7F,0x80,
0x07,0xF9,0xF8,0xFE,0x07,0xFC,0x3F,0x80,0x07,0xFD,0xF1,0xFC,0x07,0xFC,0x3F,0x80,
0x03,0xFD,0xF3,0xF0,0x07,0xF0,0x1F,0x00,0x03,0xFF,0xF7,0xE0,0x07,0xF0,0x00,0x00,
0x01,0xFF,0xF7,0xC0,0x07,0xF0,0x03,0xC0,0x01,0xFF,0xE0,0x00,0x07,0xF0,0x07,0xE0,
0x00,0xF7,0xE0,0x00,0x07,0xF0,0x0F,0xF0,0x00,0x07,0xE0,0x00,0x07,0xF0,0x1F,0xF8,
0x00,0x0F,0xC7,0xFF,0xFF,0xFF,0xFF,0xF8,0x00,0x0F,0xC7,0xFF,0xFF,0xFF,0xFF,0xFC,
0x00,0x0F,0xC3,0xF8,0x7F,0xFC,0x00,0x3C,0x00,0x1F,0xC0,0x00,0x7F,0xFE,0x00,0x00,
0x00,0x1F,0x80,0x00,0xFF,0xFE,0x00,0x00,0x00,0x1F,0x80,0x01,0xFF,0xFF,0x00,0x00,
0x00,0x3F,0x80,0x01,0xFF,0xFF,0x80,0x00,0x00,0x3F,0x80,0x03,0xFF,0xFF,0x80,0x00,
0x00,0x7F,0x00,0x07,0xFF,0xFF,0xC0,0x00,0x00,0xFF,0x00,0x07,0xFF,0xFF,0xE0,0x00,
0x3F,0xFF,0x00,0x0F,0xF7,0xFF,0xF0,0x00,0x3F,0xFF,0x00,0x1F,0xE7,0xF7,0xF8,0x00,
0x07,0xFE,0x00,0x3F,0xC7,0xF7,0xF8,0x00,0x03,0xFE,0x00,0x7F,0xC7,0xF3,0xFE,0x00,
0x00,0xFE,0x00,0x7F,0x87,0xF1,0xFF,0x00,0x00,0xFE,0x00,0xFF,0x07,0xF1,0xFF,0x80,
0x00,0xFE,0x01,0xFE,0x07,0xF0,0xFF,0xC0,0x00,0xFE,0x03,0xFC,0x07,0xF0,0x7F,0xF0,
0x01,0xFE,0x0F,0xF0,0x07,0xF0,0x3F,0xFC,0x01,0xFE,0x1F,0xE0,0x07,0xF0,0x3F,0xFC,
0x01,0xFE,0x3F,0xC0,0x07,0xF0,0x1F,0xF0,0x01,0xFE,0xFF,0x00,0x07,0xF0,0x0F,0xC0,
0x01,0xFF,0xFC,0x00,0x07,0xF0,0x07,0x80,0x01,0xFF,0xF0,0x00,0x07,0xF0,0x00,0x00,
0x01,0xFE,0x00,0x00,0x07,0xF0,0x00,0x00,0x01,0xFE,0x00,0x00,0x07,0xF0,0x00,0x00,
0x00,0x7E,0x00,0x00,0x07,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x32,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0xBF,0xC9,0xD4,0xDA,
0xCD,0xBC,0xCF,0xF1,0xC7,0xF8,0xC4,0xDA,0xB5,0xE3,0xBB,0xF7,0xA3,0xAC,0xBB,0xAD,
0xD0,0xC2,0xCD,0xBC,0xBB,0xF2,0xD0,0xDE,0xB8,0xC4,0xD4,0xAD,0xCD,0xBC,0x00,0x00,
0x12,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x34,0x38,0x00,0x00
};
/******************************************************************************/

汉字取完以后,就是用上面的生成的数组数据结合打点函数进行显示,如下

/***********************************************************************************/
//单个汉字的显示
//打点方向:从左到右,从上到下
//						起始坐标                         字体颜色            字体的宽度        字体的取模数组
void LCD_ShowChar_dadian(unsigned short int  x,unsigned short int  y,unsigned int color,unsigned short int  size,unsigned char ch[])
{
	unsigned char height=0,width=0,x0=0;
	unsigned char number=0;
	unsigned int t=0,a=0;
	number=ch[0];
	for(height=0;height<size;height++)//64为字体高度
	{
		
		for(width=0;width<size/8;width++)///宽度
		{
			for(t=0;t<8;t++)
			{
				if((number&0x80)==0x80)////高位到低位
				{
					GPU_GotoXy(x+x0, y+height);//打点函数的坐标
					GPU_WrRGB(color);//打点函数(此处我是分开两条写的,读者的打点函数可以合成一条函数,意思一样,因人而异)
				}
				else
				{
					GPU_GotoXy(x+x0, y+height);
					GPU_WrRGB(0x1000000);//0x1000000表示不打背景色,想要背景色就是更改此值
				}
					number<<=1;
					x0++;
						
			}
			number=ch[++a];
			
		}
			x0=0;//第1行发完以后要将x0置零,因为64*64,所以共64行
	}
}

如下:

/***************************************************************************************************************************************************/

Bin文件形式的单汉字显示

首先我们是操作Bin文件的,所以这里是要用到一点文件操作,同时由于文件有点大,只能存在SD卡上,通过SD卡来读取BIN文件。通过STM32里面做好的库直接拿来用


FATFS myfs[2];                 // Work area (file system object) for logical drive
FIL myfsrc, myfdst;            // file objects
FRESULT myres;                 // FatFs function common result code
UINT mybr, mybw;               // File R/W count

这里给大家普及一下知识:

汉字的区码和位码由于国标码是四位十六进制,为了便于交流,大家常用的是四位十进制的区位码。所有的国标汉字与符号组成一个94×94的矩阵。在此方阵中,每一行称为一个"区",每一列称为一个"位",因此,这个方阵实际上组成了一个有94个区(区号分别为1到94)、每个区内有94个位(位号分别为1到94)的汉字字符集。一个汉字所在的区号和位号简单地组合在一起就构成了该汉字的"区位码"。在汉字的区位码中,高两位为区号,低两位为位号。 在区位码中,01-09区为682个特殊字符,16~87区为汉字区,包含6763个汉字 。其中16-55区为一级汉字(3755个最常用的汉字,按拼音字母的次序排列),56-87区为二级汉字(3008个汉字,按部首次序排列)。所以,当我们需要n个任意汉字时,我们不必建一个全部汉字表,而是利用区位码实现常用汉字的提取。

我们通过软件进行汉字库 .bin生成。     

生成好的文件放到SD卡里面       

 

所以这里操作Bin文件的函数如下


///取bin文件的数据函数
//核心介绍一下((High8bit-0xb0)*94+Low8bit-0xa1)*64*8;语句就是根据约定的映射关系由汉字内码求得该汉字字模在字库中的存放起始位置
//((High8bit-0xb0)*94+Low8bit-0xa1)表示字库偏移,高位为区码,低位为位码
//64*8表示一个占多少个字节
int GetGBKCode_from_sd(unsigned char* pBuffer,const unsigned char * c)
{ 
    unsigned char High8bit,Low8bit;
    unsigned long int pos;
    High8bit=*c;     /* 取高8位数据 */
    Low8bit=*(c+1);  /* 取低8位数据 */
    
    pos = ((High8bit-0xb0)*94+Low8bit-0xa1)*64*8;	

    f_mount(0, &myfs[0]);
    myres = f_open(&myfsrc , "a2.bin", FA_OPEN_EXISTING | FA_READ);//打开文件
    
    if ( myres == FR_OK ) 
    {
			
        f_lseek (&myfsrc, pos);														 //指针偏移
        myres = f_read( &myfsrc, pBuffer, 512, &mybr );		 //64*64大小的汉字 
        
        f_close(&myfsrc);
        return 0;  
    }
    
    else
        return -1;    
}

注意:我这里的通过软件生成的Bin文件汉字库只是有汉字(也就是说只取16~87区为汉字区),没有半角符号、字母等,如果读者的Bin文件汉字库里面有半角符号、字母等,则汉字的屏偏移应该为((High8bit-0xa1)*94+Low8bit-0xa1)。

 

我这生成好的64*64的bin文件字库(只生成16~87区为汉字区)

链接:https://pan.baidu.com/s/1EModA57-qMoFuwj-3aZE5g 密码:n2ol

 

核心的部分介绍完,现在就谈谈显示单个汉字


unsigned char buffer[512];


//单个字显示函数
void LCD_ShowChar_ku(u16 x,u16 y,uint32_t color,u16 size,unsigned char *ch)
{
	unsigned char height=0,width=0,x0=0,t=0;
	unsigned char number=0;
	unsigned int a=0;

	GetGBKCode_from_sd(buffer,ch);  /* 取字模数据 */

	number=buffer[0];
	
	
	for(height=0;height<size;height++)//64为字体高度
	{
		for(width=0;width<size/8;width++)///宽度为方框  1行有size/8个字节
		{
			for(t=0;t<8;t++)
			{
				if((number&0x80)==0x80)
				{
					GPU_GotoXy(x+x0, y+height);
					GPU_WrRGB(color);
				}
				else
				{
					GPU_GotoXy(x+x0, y+height);
					GPU_WrRGB(0x1000000);
				}
					number<<=1;
					x0++;
					
			}
			number=buffer[++a];
			
		}
			x0=0;//一行发完以后要将x0置零
	}
}

多个汉字的显示:

//多汉字显示函数
void LCD_ShowChar_ku_duo(u16 x,u16 y,uint32_t color,u16 size,unsigned char *ch)
{
	while(*ch != '\0')
	{
		LCD_ShowChar_ku( x, y, color, size, ch);//调用单汉字
		ch+=2;
		x+=size;
//以下两个if语句表示当一行(列)汉字不够显示的时候,自动切换下一行(列)
		if(x>(SSD_LCDH-size))
		{
			x=0;
			y+=64;//此处加的数据根据汉字的大小而定的
		}
		if(y>(SSD_LCDV-size))
		{
			y=0;
		}
	}
}

 

觉得不错,点个赞!!!

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值