TFT-LCD屏幕显示ASCII字符和字符串
在前面初始化完LCD屏幕以及学会填充颜色后,这次编写显示ASCII字符和字符串函数
程序
font_ASCII.h
用取模软件取出不同字体的ASCII码字模数据,从空格号开始取,对应十进制为32,空格号之前的都是一些控制字符,用二维数组保存数据,后续代码中可以根据一维数组下标来找到要显示的字符,然后再遍历数据进行显示
注意:24号字体的每一个字符的一维数组大小是48,后续代码中就要遍历写入这48个数据,每次写两个
/**
* ASCII字符集,16号字体
* 偏移量32(即取模从空格开始取,码值为32)
* 宽x高:8x16
* 字体:宋体
* 逐行式(从第一行开始向右每取8个点作为一个字节,不足8个点就补0)
* 逆向(取模顺序从低到高,即第一个点作为最低位)
*/
const uint8_t ucAscii_1608[95][16] =
{
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x08,0x08,0x08,0x08,0x00,0x18,0x18,0x00,0x00},/*"!",1*/
{0x00,0x00,0x00,0x3C,0x24,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/
{0x00,0x00,0x00,0x44,0x24,0x24,0xFF,0x24,0x24,0x24,0xFF,0x22,0x12,0x12,0x00,0x00},/*"#",3*/
{0x00,0x00,0x08,0x3C,0x2E,0x6A,0x0E,0x0C,0x38,0x68,0x6A,0x6A,0x2E,0x1C,0x08,0x00},/*"$",4*/
{0x00,0x00,0x00,0x26,0x25,0x15,0x1D,0x16,0x68,0x58,0x54,0x54,0x52,0x62,0x00,0x00},/*"%",5*/
……………………………………
}
/**
* ASCII字符集,24号字体
* 偏移量32(即取模从空格开始取,码值为32)
* 宽x高:12x24
* 字体:宋体
* 逐行式(从第一行开始向右每取8个点作为一个字节,不足8个点就补0)
* 逆向(取模顺序从低到高,即第一个点作为最低位)
*/
const uint8_t ucAscii_2412[95][48] =
{
{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,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
………………
}
TFT_LCD.c
LCD显示英文字符
/**
* @name LCD_ShowChar
* @brief LCD屏幕显示英文字符
* @param usXstar:窗口起点x轴坐标
* usYstar:窗口起点y轴坐标
* cChar:要显示的英文字符
* usColor_Background:选择英文字符的背景色
* usColor_Foreground:选择英文字符的前景色
* font:字体选择 参数:ASCII_font_16 :16号字体;ASCII_font_24 :24号字体
* @retval None
*/
static void LCD_ShowChar(uint16_t usXstar,
uint16_t usYstar,
const char cChar,
uint16_t usColor_Background,
uint16_t usColor_Foreground,
ASCII_font_t font)
{
uint8_t ucIndex,ucTemp,ucPage,ucColumn;
//检查输入参数是否合法
assert_param(IS_ASCII_FONT(font));
//ASCII字模数组索引,需要减去偏移量(' '->空格键的码值)
ucIndex = cChar - ' ';
//判断字体 - 16号字体,则字体的高度为16,宽度为8
if(font == ASCII_font_16)
{
//设置窗口,宽为8,高为16
LCD_SetWindows(usXstar,usYstar,8,16);
//逐行写入数据,共16行,每行8个像素点
for(ucPage=0;ucPage<16;ucPage++)
{
//从ASCII字符集数组获取像素数据
//像素点数据为1时,写入字符颜色,为0时,写入背景颜色
ucTemp = ucAscii_1608[ucIndex][ucPage];
for(ucColumn=0;ucColumn<8;ucColumn++)
{
if((ucTemp & BIT0) == BIT0)
{
LCD_WRITE_DATA(usColor_Foreground); //字体颜色
}
else
{
LCD_WRITE_DATA(usColor_Background); //背景颜色
}
ucTemp >>= 1;
}
}
}
//判断字体 - 24号字体
if(font == ASCII_font_24)
{
//设置窗口,宽为12,高为24
LCD_SetWindows(usXstar,usYstar,12,24);
//逐行写入数据,共24行,每行12个像素点(占两个字节)
//每个字符的一维数组数据有48个,每次写两个字节(一个8位,一个4位),所以ucPage+=2
for(ucPage=0;ucPage<48;ucPage+=2)
{
//从ASCII字符集数组获取像素数据 ,前8个像素点
//像素点数据为1时,写入字符颜色,为0时,写入背景颜色
ucTemp = ucAscii_2412[ucIndex][ucPage];
for(ucColumn=0;ucColumn<8;ucColumn++)
{
if((ucTemp & BIT0) == BIT0)
{
LCD_WRITE_DATA(usColor_Foreground);
//HAL_Delay(500); //加上延时,可以观看字符显示过程
}
else
{
LCD_WRITE_DATA(usColor_Background);
//HAL_Delay(500);
}
ucTemp >>= 1;
}
//从ASCII字符集数组获取像素数据,后4个像素点
//像素点数据为1时,写入字符颜色,为0时,写入背景颜色
ucTemp = ucAscii_2412[ucIndex][ucPage+1];
for(ucColumn=0;ucColumn<4;ucColumn++)
{
if((ucTemp & BIT0) == BIT0)
{
LCD_WRITE_DATA(usColor_Foreground);
//HAL_Delay(500);
}
else
{
LCD_WRITE_DATA(usColor_Background);
//HAL_Delay(500);
}
ucTemp >>= 1;
}
}
}
}
注意点:
1.ASCII码取模是从空格号开始的,对应十进制为32,所以在函数中处理传进来的字符时,要先减去字符的空格号,才能得到想要的字符的十进制值,赋给变量ucIndex,然后ucIndex作为二维数组的一维坐标,找到对应字符的字模数据
2.TFT-LCD与LCD12864点阵屏不同,12864是哪一个点阵写入1就被点亮,点阵是黑色的,所以看得见,虽然ASCII码值也是通过取模软件的点阵方式取来的,这些点阵在TFT-LCD上就通过薄膜晶体管来显示,所以TFT-LCD需要对写入数据的每一位进行判断,如果该位为1,显示字体颜色,如果该位为0,则显示背景颜色,则不同颜色一对比就形成了字符
3.在写入24号字体时,因为字体宽度为12个像素点,而字模数组的数据都是8位的,所以12个像素点就只能先写8位,再写4位,写完一行的8位数据,ucPage+1,在字符的一维数组中找下一个8位的数据,但只循环4次,取低4位的数据,所以共写入了12位像素点数据,写完一行后屏幕会根据窗口宽度自动换行,所以下一行就再取数组中的两个字节写入,每次两个,直到48个字节都写完,就显示出了字符
写完8位是紧接着写4位的,并没有空格,图片为了区分8位和4位,加了空格
LCD显示英文字符串
/**
* @name LCD_ShowString
* @brief LCD屏幕显示英文字符串
* @param usXstar:窗口起点x轴坐标
* usYstar:窗口起点y轴坐标
* pcStr:要显示的英文字符串
* usColor_Background:选择英文字符的背景色
* usColor_Foreground:选择英文字符的前景色
* font:字体选择 参数:ASCII_font_16 :16号字体;ASCII_font_24 :24号字体
* @retval None
*/
static void LCD_ShowString(uint16_t usXstar,
uint16_t usYstar,
const char* pcStr,
uint16_t usColor_Background,
uint16_t usColor_Foreground,
ASCII_font_t font)
{
while(*pcStr != '\0')
{
//自动换行
if((usXstar+font/2) > LCD_WIGHT) //如果起始列地址加上字体宽度已经超过了屏幕宽度,则进行换行
{
usXstar = 0; //起始列地址置0
usYstar += font; //起始行地址加一个字体高度,让上方的字体显示完整
}
//自动换页
if((usYstar+font) > LCD_HIGHT) //如果起始行地址加上一个字体高度已经超过了屏幕的高度,则进行换页,从屏幕原点开始显示
{
usXstar = 0; //起始列地址置0
usYstar = 0; //起始行地址置0
}
//调用显示字符函数
TFT_LCD.LCD_ShowChar(usXstar,usYstar,*pcStr,usColor_Background,usColor_Foreground,font);
pcStr++; //指针指向下一个字符
usXstar+=font/2; //列地址加上一个字符宽度
}
}
显示字符串函数要判断字符串的长度是否超过屏幕宽度,是则换行,高度是否超过屏幕的高度,是则换页,从起始列地址和起始行地址都是0的位置开始显示
调用显示字符函数,取出字符串的每一个字符,然后传入函数中进行显示,每显示一个字符,列地址就要加上一个字符宽度,再来显示下一个字符
系统运行,由main函数调用
/*
* @name Run
* @brief 系统运行
* @param None
* @retval None
*/
static void Run()
{
TFT_LCD.LCD_ShowChar(0,0,'A',Color_GREEN,Color_RED,ASCII_font_24);
TFT_LCD.LCD_ShowChar(8,25,'B',Color_GREEN,Color_RED,ASCII_font_24);
TFT_LCD.LCD_ShowChar(16,50,'C',Color_GREEN,Color_RED,ASCII_font_24);
TFT_LCD.LCD_ShowChar(24,75,'D',Color_GREEN,Color_RED,ASCII_font_24);
TFT_LCD.LCD_ShowChar(32,100,'E',Color_GREEN,Color_RED,ASCII_font_24);
TFT_LCD.LCD_ShowString(80,150,"Hello World!",Color_WHITE,Color_RED,ASCII_font_16);
TFT_LCD.LCD_ShowString(0,170,"Good Good Study,Day Day Up",Color_BLUE,Color_YELLOW,ASCII_font_24);
}