第 28 章 LCD—液晶显示中英文(附个人遇到的一些问题)

28.1 字符编码

1.1 ASCII 编码 1.2 中文编码

1.2.1 GB2312 标准

1.2.1.1 区位码

1.2.2 GBK 编码

1.2.3 GB18030

1.2.4 Big5 编码

1.3 Unicode 字符集和编码

1.3.1 UTF-32

1.3.2 UTF-16

1.3.3 UTF-8

1.4 BOM

28.2 什么是字模?

2.1 字模的构成

2.2 字模显示原理

2.3 如何制作字模

(1) 配置字模格式

(2) 生成 GB2312 字模

2.4 字模寻址公式

2.5 存储字模文件

28.3 各种模式的液晶显示字符实验

3.1 硬件设计

3.2 显示 ASCII 编码的字符

3.2.1 编程要点

(1) 获取字模数据;

(2) 根据字模格式,编写液晶显示函数;

(3) 编写测试程序,控制液晶英文。

3.2.2 代码分析

1.ASCII 字模数据

2.管理英文字模的结构体

3.切换字体

4.ASCII 字符显示函数

(1) 输入参数

(2) 根据字符计算字模的数组偏移

(3) 设置显示窗口并发送显示命令

(4) 行循环与列循环

5.显示字符串

6.清除屏幕字符

7.显示 ASCII 码示例

3.3 显示 GB2312 编码的字符

3.3.1 编程要点

(1) 获取字模数据;

(2) 根据字模格式,编写液晶显示函数;

(3) 编写测试程序,控制液晶汉字。

3.3.2 代码分析

1.显示汉字字符

(1) 使用 ILI9341_OpenWindow 和 ILI9341_Write_Cmd 来设置显示窗口并发送显示像素命令。

(2) 使用 GetGBKCode 函数获取字模数据

(3) 遍历像素点。

2.显示中英文字符串

3.获取 SPI-FLASH 中的字模数据

(1) 初始化 SPI 外设

(2) 取出要显示字符的 GB2312 编码的高位字节和低位字节

(3) 根据字符的编码及字模的大小导出的寻址公式

(4) 利用 SPI_FLASH_BufffferRead 函数,从 SPI-FLASH 中读取该字模的数据

(5) 获取到的字模数据存储到 pBuffffer 指针指向的存储空间,显示汉字的函数直接利用它来显示字符。

4.获取 SD 卡中的字模数据

5.显示 GB2312 字符示例

确保以下所有环节都正常:

• SPI-FLASH 或 SD 卡中是否有字库文件?

• 文件存储的位置或路径是否与程序的配置一致?

• 开发环境中的字符编码选项是否与字库的编码一致?

3.4 显示任意大小的字符

3.4.1 编程要点

3.4.2 代码分析

1.缩放字模数据

(1) 输入参数

(2) 计算缩放比例

(3) 检查输入参数

(4) 映射字模

(5) 缩放字符

(6) 缩放结果

2.利用缩放的字模数据显示字符

3.利用缩放的字模显示字符串

4.利用缩放的字模显示示例

main.c

在这里插入代码片#include "bsp_ili9341_lcd.h"
#include "usart.h"
void LCD_Direction_Show(void);
void LCD_Test(void);
void ILI9341_DispStringLine_EN (  uint16_t line,  char * pStr );
void Delay(__IO uint32_t nCount);	 //简单的延时函数
void 										 Printf_Charater								 (void);  
extern uint16_t lcdid;
/**
* @brief 主函数
* @param 无 
* @retval 无
*/
int main ( void ) 
{	
	//LCD 初始化
	ILI9341_Init ();         

	/* USART config */
	USART_Config();  
	
	printf("\r\n ********** 液晶屏中文显示程序(字库在外部FLASH)*********** \r\n"); 
	printf("\r\n 若汉字显示不正常,请阅读工程中的readme.txt文件说明,根据要求给FLASH重刷字模数据\r\n"); 

 //其中0、3、5、6 模式适合从左至右显示文字,
 //不推荐使用其它模式显示文字	其它模式显示文字会有镜像效果			
 //其中 6 模式为大部分液晶例程的默认显示方向  
	ILI9341_GramScan ( 6 );
	
	Printf_Charater();
	
	while ( 1 )
	{
		LCD_Test();
	}
	
	
}

/* 用于测试各种液晶的函数 */
void LCD_Test(void) 
{ 
	/* 演示显示变量 */
static uint8_t testCNT = 0;
char dispBuff[100];
 testCNT++; 
 LCD_SetFont(&Font8x16);
 LCD_SetColors(RED,BLACK);

 ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH); /* 清屏,显示全黑 */
 /******** 显示字符串示例 *******/
 ILI9341_DispStringLine_EN_CH(LINE(0),"野火 BH");
 //显示指定大小的字符
 ILI9341_DisplayStringEx(0,1*24,24,24,(uint8_t *)"野火 BH",0);
 ILI9341_DisplayStringEx(2*48,0*48,48,48,(uint8_t *)"野火 BH",0);

 /******** 显示变量示例 *******/
 LCD_SetTextColor(GREEN);
 /* 使用 c 标准库把变量转化成字符串 */
 sprintf(dispBuff,"显示变量: %d ",testCNT);
 LCD_ClearLine(LINE(5)); /* 清除单行文字 */

 /* 然后显示该字符串即可,其它变量也是这样处理 */
 ILI9341_DispStringLine_EN_CH(LINE(5),dispBuff);
 Delay(0xFFFFFF);
 /*... 以下部分省略 */
 }
///*用于测试各种液晶的函数*/
//void LCD_Test(void)
//{
//	/*演示显示变量*/
//	static uint8_t testCNT = 0;	
//	char dispBuff[100];
//	
//	testCNT++;	
//	
//	LCD_SetFont(&Font8x16);
//	LCD_SetColors(RED,BLACK);

//  ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);	/* 清屏,显示全黑 */
//	/********显示字符串示例*******/ 
//  ILI9341_DispStringLine_EN_CH(LINE(0),"野火3.2寸LCD参数:");
//  ILI9341_DispStringLine_EN_CH(LINE(1),"分辨率:240x320 px");
//  if(lcdid == LCDID_ILI9341)
//  {
//    ILI9341_DispStringLine_EN_CH(LINE(2),"ILI9341液晶驱动");
//  }
//  else if(lcdid == LCDID_ST7789V)
//  {
//    ILI9341_DispStringLine_EN_CH(LINE(2),"ST7789V液晶驱动");
//  }
//  ILI9341_DispStringLine_EN_CH(LINE(3),"XPT2046触摸屏驱动");

//	/********显示变量示例*******/
//	LCD_SetTextColor(GREEN);

//	/*使用c标准库把变量转化成字符串*/
//	sprintf(dispBuff,"显示变量: %d ",testCNT);
//  LCD_ClearLine(LINE(5));	/* 清除单行文字 */
//	
//	/*然后显示该字符串即可,其它变量也是这样处理*/
//	ILI9341_DispStringLine_EN_CH(LINE(5),dispBuff);

//	/*******显示图形示例******/
//  /* 画直线 */
//  
//  LCD_ClearLine(LINE(7));/* 清除单行文字 */
//	LCD_SetTextColor(BLUE);

//  ILI9341_DispStringLine_EN_CH(LINE(7),"画直线:");
//  
//	LCD_SetTextColor(RED);
//  ILI9341_DrawLine(50,170,210,230);  
//  ILI9341_DrawLine(50,200,210,240);
//  
//	LCD_SetTextColor(GREEN);
//  ILI9341_DrawLine(100,170,200,230);  
//  ILI9341_DrawLine(200,200,220,240);
//	
//	LCD_SetTextColor(BLUE);
//  ILI9341_DrawLine(110,170,110,230);  
//  ILI9341_DrawLine(130,200,220,240);
//  
//  Delay(0xFFFFFF);
//  
//  ILI9341_Clear(0,16*8,LCD_X_LENGTH,LCD_Y_LENGTH-16*8);	/* 清屏,显示全黑 */
//  
//  
//  /*画矩形*/

//  LCD_ClearLine(LINE(7));	/* 清除单行文字 */
//	LCD_SetTextColor(BLUE);

//  ILI9341_DispStringLine_EN_CH(LINE(7),"画矩形:");

//	LCD_SetTextColor(RED);
//  ILI9341_DrawRectangle(50,200,100,30,1);
//	
//	LCD_SetTextColor(GREEN);
//  ILI9341_DrawRectangle(160,200,20,40,0);
//	
//	LCD_SetTextColor(BLUE);
//  ILI9341_DrawRectangle(170,200,50,20,1);
//  
//  Delay(0xFFFFFF);
//	
//	ILI9341_Clear(0,16*8,LCD_X_LENGTH,LCD_Y_LENGTH-16*8);	/* 清屏,显示全黑 */

//  /* 画圆 */
//  LCD_ClearLine(LINE(7));	/* 清除单行文字 */
//	LCD_SetTextColor(BLUE);
//	
//  ILI9341_DispStringLine_EN_CH(LINE(7),"画圆");
//	
//	LCD_SetTextColor(RED);
//  ILI9341_DrawCircle(100,200,20,0);
//	
//	LCD_SetTextColor(GREEN);
//  ILI9341_DrawCircle(100,200,10,1);
//	
//	LCD_SetTextColor(BLUE);
//	ILI9341_DrawCircle(140,200,20,0);

//  Delay(0xFFFFFF);
//  
//  ILI9341_Clear(0,16*8,LCD_X_LENGTH,LCD_Y_LENGTH-16*8);	/* 清屏,显示全黑 */

//}
///* 用于测试各种液晶的函数 */
//void LCD_Test(void) 
//{  /* 演示显示变量 */
//static uint8_t testCNT = 0; 
// char dispBuff[100];
// testCNT++; 
// LCD_SetFont(&Font8x16);
// LCD_SetColors(RED,BLACK);

// ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH); /* 清屏,显示全黑 */
// /******** 显示字符串示例 *******/
// ILI9341_DispStringLine_EN(LINE(0),"BH 3.2 inch LCD para:");
// ILI9341_DispStringLine_EN(LINE(1),"Image resolution:240x320 px");
// ILI9341_DispStringLine_EN(LINE(2),"ILI9341 LCD driver");
// ILI9341_DispStringLine_EN(LINE(3),"XPT2046 Touch Pad driver");

// /******** 显示变量示例 *******/
// LCD_SetFont(&Font16x24);
// LCD_SetTextColor(GREEN);

// /* 使用 c 标准库把变量转化成字符串 */
// sprintf(dispBuff,"Count : %d ",testCNT);
// LCD_ClearLine(LINE(4)); /* 清除单行文字 */

// /* 然后显示该字符串即可,其它变量也是这样处理 */
// ILI9341_DispStringLine_EN(LINE(4),dispBuff);
// /* 以下省略其它液晶演示示例 */
// }

// /* 用于展示 LCD 的八种方向模式 */
// void LCD_Direction_Show(void)
// {

// uint8_t i = 0;
// char dispBuff[100];

// //轮流展示各个方向模式
// for (i=0; i<8; i++) {
// LCD_SetFont(&Font16x24);
// LCD_SetColors(RED,BLACK);

// ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH); /* 清屏,显示全黑 */
// //其中 0、3、5、6 模式适合从左至右显示文字,
// //不推荐使用其它模式显示文字 其它模式显示文字会有镜像效果
// //其中 6 模式为大部分液晶例程的默认显示方向
// ILI9341_GramScan ( i );

// sprintf(dispBuff,"o%d. X --->",i);
// ILI9341_DispStringLine_EN(LINE(0),dispBuff);//沿 X 方向显示文字

// sprintf(dispBuff,"o%d.Y|V",i);
// ILI9341_DispString_EN_YDir(0,0,dispBuff);//沿 Y 方向显示文字

// Delay(0xFFFFFF);

 //显示测试
 // * !!!其中 0、3、5、6 模式适合从左至右显示文字,不推荐使用其它模式显示文字
 //其它模式显示文字会有镜像效果
// LCD_Test();
// }
// }
// 
/*用于测试各种液晶的函数*/
//void LCD_Test(void)
//{
//	/*演示显示变量*/
//	static uint8_t testCNT = 0;	
//	char dispBuff[100];
//	
//	testCNT++;	
//	
//	LCD_SetFont(&Font8x16);
//	LCD_SetColors(RED,BLACK);

//  ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);	/* 清屏,显示全黑 */
//	/********显示字符串示例*******/
//  ILI9341_DispStringLine_EN(LINE(0),"BH 3.2 inch LCD para:");
//  ILI9341_DispStringLine_EN(LINE(1),"Image resolution:240x320 px");
//  ILI9341_DispStringLine_EN(LINE(2),"ILI9341 LCD driver");
//  ILI9341_DispStringLine_EN(LINE(3),"XPT2046 Touch Pad driver");
//  
//	/********显示变量示例*******/
//	LCD_SetFont(&Font16x24);
//	LCD_SetTextColor(GREEN);

//	/*使用c标准库把变量转化成字符串*/
//	sprintf(dispBuff,"Count : %d ",testCNT);
//  LCD_ClearLine(LINE(4));	/* 清除单行文字 */
//	
//	/*然后显示该字符串即可,其它变量也是这样处理*/
//	ILI9341_DispStringLine_EN(LINE(4),dispBuff);

//	/*******显示图形示例******/
//	LCD_SetFont(&Font24x32);
//  /* 画直线 */
//  
//  LCD_ClearLine(LINE(4));/* 清除单行文字 */
//	LCD_SetTextColor(BLUE);

//  ILI9341_DispStringLine_EN(LINE(4),"Draw line:");
//  
//	LCD_SetTextColor(RED);
//  ILI9341_DrawLine(50,170,210,230);  
//  ILI9341_DrawLine(50,200,210,240);
//  
//	LCD_SetTextColor(GREEN);
//  ILI9341_DrawLine(100,170,200,230);  
//  ILI9341_DrawLine(200,200,220,240);
//	
//	LCD_SetTextColor(BLUE);
//  ILI9341_DrawLine(110,170,110,230);  
//  ILI9341_DrawLine(130,200,220,240);
//  
//  Delay(0xFFFFFF);
//  
//  ILI9341_Clear(0,16*8,LCD_X_LENGTH,LCD_Y_LENGTH-16*8);	/* 清屏,显示全黑 */
//  
//  
//  /*画矩形*/

//  LCD_ClearLine(LINE(4));	/* 清除单行文字 */
//	LCD_SetTextColor(BLUE);

//  ILI9341_DispStringLine_EN(LINE(4),"Draw Rect:");

//	LCD_SetTextColor(RED);
//  ILI9341_DrawRectangle(50,200,100,30,1);
//	
//	LCD_SetTextColor(GREEN);
//  ILI9341_DrawRectangle(160,200,20,40,0);
//	
//	LCD_SetTextColor(BLUE);
//  ILI9341_DrawRectangle(170,200,50,20,1);
//  
//  
//  Delay(0xFFFFFF);
//	
//	ILI9341_Clear(0,16*8,LCD_X_LENGTH,LCD_Y_LENGTH-16*8);	/* 清屏,显示全黑 */

//  /* 画圆 */
//  LCD_ClearLine(LINE(4));	/* 清除单行文字 */
//	LCD_SetTextColor(BLUE);
//	
//  ILI9341_DispStringLine_EN(LINE(4),"Draw Cir:");

//	LCD_SetTextColor(RED);
//  ILI9341_DrawCircle(100,200,20,0);
//	
//	LCD_SetTextColor(GREEN);
//  ILI9341_DrawCircle(100,200,10,1);
//	
//	LCD_SetTextColor(BLUE);
//	ILI9341_DrawCircle(140,200,20,0);

//  Delay(0xFFFFFF);
//  
//  ILI9341_Clear(0,16*8,LCD_X_LENGTH,LCD_Y_LENGTH-16*8);	/* 清屏,显示全黑 */

//}
/*"当"字符的字模16x16 */ 	  
unsigned char charater_matrix[] =    
{ /*"当",0*/
0x01,0x00,0x21,0x08,0x11,0x08,0x09,0x10,0x09,0x20,0x01,0x00,0x7F,0xF8,0x00,	0x08,
0x00,0x08,0x00,0x08,0x3F,0xF8,0x00,0x08,0x00,0x08,0x00,0x08,0x7F,0xF8,0x00,0x08,

};
/**
  * @brief  使用串口在上位机打印字模
	*					演示字模显示原理
  * @retval 无
  */
void Printf_Charater(void)   
{   
	int i,j;   
	unsigned char kk; 
  
	/*i用作行计数*/
  for ( i=0;i<16;i++)   
	{   
		/*j用作一字节内数据的移位计数*/
		/*一行像素的第一个字节*/
    for(j=0; j<8; j++)   
    {      
			/*一个数据位一个数据位地处理*/
      kk = charater_matrix[2*i] << j ;  //左移J位          
			if( kk & 0x80)     
			{   
				printf("*"); //如果最高位为1,输出*号,表示笔迹
			}   
			else  
			{   
				printf(" "); //如果最高位为0,输出空格,表示空白  
			}   
    }   
		/*一行像素的第二个字节*/
    for(j=0; j<8; j++)   
		{              
      kk = charater_matrix[2*i+1] << j ;  //左移J位   
       
			if( kk & 0x80)         
			{   
				printf("*"); //如果最高位为1,输出*号,表示笔迹   
			}   
			else  
			{   
				printf(" "); //如果最高位为0,输出空格,表示空白 
			}   
		}         
    printf("\n");    //输出完一行像素,换行 
	}   
	printf("\n\n"); 		//一个字输出完毕
}   
void Delay(__IO uint32_t nCount)	 //简单的延时函数
{
	for(; nCount != 0; nCount--);
}


其他文件:

在这里插入图片描述

问题:已经声明和定义,却报函数未定义解决方法

在这里插入图片描述
解决方案:
在这里插入图片描述

**问题:LCD显示屏无论怎么修改ili_9341_lcd.c,ili_9341_lcd.h和main.c都一直不显示中文

解决方案:可查看是是否在fonts.c文件中定义int GetGBKCode_from_EXFlash( uint8_t * pBuffer, uint16_t c)**
最后:如有其他问题,欢迎共同探讨

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我来回答你的问题。首先,你需要连接好你的STM32F4开发板和LCD屏幕,确保它们能够正常工作。然后,你需要了解如何使用STM32F4芯片库函数来控制LCD屏幕和LED灯。 在控制LCD屏幕方面,你可以使用STM32F4芯片库提供的一些函数,如LCD_Init()函数来初始化LCD屏幕,LCD_Clear()函数来清空屏幕,LCD_SetTextColor()函数来设置文本颜色等等。 在控制LED灯方面,你可以使用STM32F4芯片库提供的GPIO(通用输入/输出)函数来控制LED灯的亮灭。例如,你可以使用GPIO_WriteBit()函数来控制一个GPIO引脚的输出状态。 然后,你需要编一些代码来实现LED灯的闪烁和LCD屏幕的显示。具体来说,你可以使用一个循环来控制LED灯的闪烁次数,每次闪烁时,在LCD屏幕上显示当前闪烁次数。当闪烁次数达到预设值后,循环结束。 下面是一个基于STM32F4芯片库函数的示例代码,其中LED灯连接在GPIOG的Pin13上,LCD屏幕连接在SPI2总线上: ``` #include "stm32f4xx.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_spi.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_lcd.h" int main(void) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOG, &GPIO_InitStructure); LCD_Init(); LCD_Clear(LCD_COLOR_BLACK); LCD_SetTextColor(LCD_COLOR_WHITE); int blink_count = 10; while (blink_count > 0) { GPIO_WriteBit(GPIOG, GPIO_Pin_13, Bit_SET); Delay(500); GPIO_WriteBit(GPIOG, GPIO_Pin_13, Bit_RESET); Delay(500); LCD_ClearLine(LINE(5)); char buf[16]; sprintf(buf, "Blink: %d", blink_count); LCD_DisplayStringLine(LINE(5), (uint8_t *)buf); blink_count--; } while (1) { // do something else } } ``` 这段代码将LED灯连接到GPIOG的Pin13上,并将LCD屏幕连接到SPI2总线上。在main()函数中,它先初始化了GPIO和LCD屏幕,然后使用一个循环来控制LED灯的闪烁次数。在每次闪烁时,它会在LCD屏幕上显示当前闪烁次数。最后,它进入一个死循环,可以在这里执行其他任务。 希望这个回答能够帮助到你!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自动化王祖豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值