TFT液晶屏显示中英文

预了解知识

  • 字体表示:根据选择的字体1206或1608,它们表示字符是12个或16个像素高(对应循环第一个for),字符的宽度是6个或8个像素宽(对应循环嵌套的for),通过for来遍历像素定义中的每一个数字0或1,1的时候显示该像素点,0的时候不显示,这样就能够显示出文字了。
  • 叠加方式:就是不管原来的底色是什么,当像素为1的时候就显示该点,为0的时候什么也不做。所以如果是实时更新数据显示会一直累加之前的像素的上面造成所谓的“花屏”。
  • 非叠加方式:就是为1的时候显示该点,比叠加方式多了一步,为0时显示底色就可以把上一次不相干的像素点变成底色,其实是一种“障眼法”。

字符字节数计算

  • 每个32×32的汉字点阵,有128个字节(高32个像素点,宽32个像素点,每一个像素点代表1位,32×32=32×4×8=128×8位=128字节)
  • 举例:如果提取的字体规格大小:宽×2 = 高,要实现8×16的汉字点阵所需要的字节数。函数入口参数size为16,程序表达式:uint8_t csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2);

如何让TFT屏显示中英文

  • 使用TFT屏的驱动硬件为ST7735S,软件驱动为模拟SPI,这里主要讲解在TFT屏上显示中英文的程序流程,细节驱动不在此说明。
  • 显示字符函数原型为:void Show_Str(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint16_t *str,uint8_t size,uint8_t mode);
/******************************************************************************
 * @fn		Show_Str
 *
 * @brief	显示字符,包含中英文显示
 *
 * @param	x,y - 起点坐标宽,高
 * @param	fc - 前置画笔颜色
 * @param	bc - 背景颜色
 * @param	str - 字符串
 * @param	size - 字体大小
 * @param	mode - 显示模式 0,填充模式;1,叠加模式
 *
 * @return	none
 */
void Show_Str(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint16_t *str, uint8_t size, uint8_t mode)
{
	uint16_t x0 = x;							  	  
	uint8_t bHz = 0; //字符或者中文 
	while (*str ! =0) //数据未结束
	{ 
		if (!bHz)
		{
			if( x > (lcddev.width - size / 2) || y > (lcddev.height - size)) 
				return; //超出LCD屏的宽高最大设定值
			if (*str > 0x80) //字符型表示范围0x00~0x7F
				bHz = 1; //中文 
			else //字符
			{  
				if (*str == 0x0D) //换行符号
				{   
					y += size;
					x = x0;
					str++; 
				}  
				else
				{
					if (size == 12 || size == 16)
					{  
						LCD_ShowChar(x, y, fc, bc, *str, size, mode);
						x += size / 2; //字符,宽为全字的一半 
					}
					else //字库中没有集成16X32的英文字体,用8X16代替
					{
						LCD_ShowChar(x, y, fc, bc, *str, 16, mode);
						x += 8; //字符,为全字的一半 
					}
				} 
				str++; 
			}
		}
		else //中文 
		{   
			if (x > (lcddev.width - size) || y > (lcddev.height - size)) 
				return;  
			bHz = 0; //清除标志
			if (size == 32)
				GUI_DrawFont32(x, y, fc, bc, str, mode);	 
			else if (size == 24)
				GUI_DrawFont24(x, y, fc, bc, str, mode);
			else
				GUI_DrawFont16(x, y, fc, bc, str, mode);

			str += 2; //中文表示占两个字节
			x += size; //下一个汉字偏移	  
		}						 
	}   
}
  • 显示单个英文字符函数原型:void LCD_ShowChar(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t num, uint8_t size,uint8_t mode);
/******************************************************************************
 * @fn		LCD_ShowChar
 *
 * @brief	显示单个英文字符
 *
 * @param	x,y - 起点坐标宽,高
 * @param	fc - 前置画笔颜色
 * @param	bc - 背景颜色
 * @param	num - 数值
 * @param	size - 字体大小
 * @param	mode - 显示模式 0,填充模式;1,叠加模式
 *
 * @return 	none
 */
void LCD_ShowChar(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t num, uint8_t size,uint8_t mode)
{  
	uint8_t temp;
	uint8_t pos, t;
	uint16_t colortemp = POINT_COLOR;  
		   
	num = num - ' '; //得到偏移后的值
	LCD_SetWindows(x, y, x + size / 2 - 1, y + size - 1); //设置单个文字显示窗口
	if (!mode) //非叠加方式
	{
		for (pos = 0; pos < size; pos++)
		{
			if (size == 12)temp = asc2_1206[num][pos];//调用1206字体
			else temp = asc2_1608[num][pos];		 //调用1608字体
			for (t = 0; t < size / 2; t++)
			{    	     
				if (temp & 0x01)POINT_COLOR = fc;   //非叠加方式时,像素点上描前置颜色,没有像素点描背景颜色
				else POINT_COLOR = bc;   
				LCD_DrawPoint(x + t, y + pos); 
				temp >>= 1; 
			}
		}
	}
	else //叠加方式,不先清屏会存在花屏现象
	{
		for (pos = 0; pos < size; pos++)
		{
			if (size == 12)temp = asc2_1206[num][pos];//调用1206字体
			else temp = asc2_1608[num][pos];		 //调用1608字体
			for (t = 0; t < size / 2; t++)
			{   
				POINT_COLOR = fc;          
				if (temp & 0x01)LCD_DrawPoint(x + t, y + pos);//画一个点  
				temp >>= 1; 
			}
		}
	}
	POINT_COLOR = colortemp;
	LCD_SetWindows(0, 0, lcddev.width - 1, lcddev.height - 1); //恢复窗口为全屏    	   	 	  
} 
  • 显示单个16×16中文函数原型为:void GUI_DrawFont16(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *s, uint8_t mode);
/******************************************************************************
 * @fn		GUI_DrawFont16
 *
 * @brief	显示单个16×16中文字体
 *
 * @param	x,y - 起点坐标宽,高
 * @param	fc - 前置画笔颜色
 * @param	bc - 背景颜色
 * @param	s - 字符串地址
 * @param	mode - 显示模式 0,填充模式;1,叠加模式
 *
 * @return 	none
 */
void GUI_DrawFont16(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *s, uint8_t mode)
{
	uint8_t i, j;
	uint16_t k;
	uint16_t HZnum;
	uint16_t x0 = x;
	HZnum = sizeof(tfont16) / sizeof(typFNT_GB16);	//自动统计汉字数目
	
	for (k = 0; k < HZnum; k++) 
	{
		if ((tfont16[k].Index[0] == *(s)) && (tfont16[k].Index[1] == *(s + 1))) //遍历确定汉字
		{ 
			LCD_SetWindows(x, y, x + 16 - 1, y + 16 - 1);
			for (i = 0; i < 16 * 2; i++) //16×16字体,16 * (16 / 8) = 32个字节
			{
				for (j = 0; j < 8; j++)
				{
					if (!mode) //非叠加方式
					{
						if (tfont16[k].Msk[i] & (0x80 >> j))
							LCD_WR_DATA_16Bit(fc);
						else 
							LCD_WR_DATA_16Bit(bc);
					}
					else //叠加方式
					{
						POINT_COLOR = fc;
						if (tfont16[k].Msk[i] & (0x80 >> j))
							LCD_DrawPoint(x, y);//画一个点
						x++;
						if ((x - x0) == 16)
						{
							x = x0;
							y++;
							break;
						}
					}
				}
			}
		}				  
		continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
	}

	LCD_SetWindows(0, 0, lcddev.width - 1, lcddev.height - 1);//恢复窗口为全屏  
}
  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值