预了解知识
- 字体表示:根据选择的字体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);
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;
if (*str > 0x80)
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
{
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);
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];
else temp = asc2_1608[num][pos];
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];
else temp = asc2_1608[num][pos];
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);
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++)
{
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);
}