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)**
最后:如有其他问题,欢迎共同探讨