前言
使用单片机对spi串口屏进行文本显示应该怎么做呢?虽然lcd厂商会提供单片机的驱动但是很多简单的示例是不满足项目需求的!我会详细的介绍给大家字库是如何导入到keil工程的!
一、常规汉族格式
一般对于较小尺寸的屏幕比如2.4 2.6 3.2寸屏幕,根据需要一般有16、24、32号字体,而lcd厂商一般会提供这类的底层示例,比如下方的:
Display a single 16x16 Chinese character
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_WriteData_16Bit(fc); else Lcd_WriteData_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);//恢复窗口为全屏 }
Display a single 24x24 Chinese character
void GUI_DrawFont24(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(tfont24)/sizeof(typFNT_GB24); //自动统计汉字数目 for (k=0;k<HZnum;k++) { if ((tfont24[k].Index[0]==*(s))&&(tfont24[k].Index[1]==*(s+1))) { LCD_SetWindows(x,y,x+24-1,y+24-1); for(i=0;i<24*3;i++) { for(j=0;j<8;j++) { if(!mode) //非叠加方式 { if(tfont24[k].Msk[i]&(0x80>>j)) Lcd_WriteData_16Bit(fc); else Lcd_WriteData_16Bit(bc); } else { POINT_COLOR=fc; if(tfont24[k].Msk[i]&(0x80>>j)) LCD_DrawPoint(x,y);//画一个点 x++; if((x-x0)==24) { x=x0; y++; break; } } } } } continue; //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响 } LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复窗口为全屏 }
Display a single 32x32 Chinese character
void GUI_DrawFont32(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(tfont32)/sizeof(typFNT_GB32); //自动统计汉字数目 for (k=0;k<HZnum;k++) { if ((tfont32[k].Index[0]==*(s))&&(tfont32[k].Index[1]==*(s+1))) { LCD_SetWindows(x,y,x+32-1,y+32-1); for(i=0;i<32*4;i++) { for(j=0;j<8;j++) { if(!mode) //非叠加方式 { if(tfont32[k].Msk[i]&(0x80>>j)) Lcd_WriteData_16Bit(fc); else Lcd_WriteData_16Bit(bc); } else { POINT_COLOR=fc; if(tfont32[k].Msk[i]&(0x80>>j)) LCD_DrawPoint(x,y);//画一个点 x++; if((x-x0)==32) { x=x0; y++; break; } } } } } continue; //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响 } LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复窗口为全屏 }
二、如何创造出字体呢?
1.软件怎么用?
一般使用zimo22来生成,我们以16*16为例
打开软件
选择参数设置,其他选项
点击文字输入区字体选择
如果是16*16 就是小四大小即可,点击确定
在文字输入区输入文字,比如:成功
然后ctrl+enter之后如下图:
然后点击取模方式如下图
点击c51格式之后代码就出来了
/*-- 文字: 成 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x50,0x00,0x48,0x00,0x40,0x3F,0xFE,0x20,0x40,0x20,0x40,0x20,0x44,0x3E,0x44,
0x22,0x44,0x22,0x28,0x22,0x28,0x22,0x12,0x2A,0x32,0x44,0x4A,0x40,0x86,0x81,0x02,
/*-- 文字: 功 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x40,0x00,0x40,0x00,0x40,0xFE,0x40,0x11,0xFC,0x10,0x44,0x10,0x44,0x10,0x44,
0x10,0x44,0x10,0x84,0x10,0x84,0x1E,0x84,0xF1,0x04,0x41,0x04,0x02,0x28,0x04,0x10,
3.怎么用呢?这个玩意只是数组而已,我们调用方式其实很简单
1)先做数组
2)学会调用
void Apf_GUI_Show_Str(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_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>16)//字库中没有集成12X24 16X32的英文字体,用8X16代替 { LCD_ShowChar(x,y,fc,bc,*str,16,mode); x+=8; //字符,为全字的一半 } else { LCD_ShowChar(x,y,fc,bc,*str,size,mode); x+=size/2; //字符,为全字的一半 } } 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;//下一个汉字偏移 } } }
参数:x,y,前景色,背景色,汉字,大小,是否覆盖 Apf_GUI_Show_Str(190+16,47,WHITE,BLACK,"图",16,0);
24*24 32*32就是字模生成软件的字体大小不同而已,其他的一样,这个框架可以用在任何tftlcd上来绘制字体
总结
后期会将图片如何显示在tftlcd上做简单的介绍!