完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
一、建立自己的点阵集
上一篇博客,给大家介绍了在LCD上显示汉字/特殊图形需要知道对应的显示编码(GBK码/ASCII码),显示编码对应着每个图形的点阵集(数组),我们可以通过这个点阵集,将自己DIY的图形显示在LCD上面。现在先说一下怎么做一个自己的点阵集。一般情况下,用PCtoLCD2002这个软件,可以自动帮我们生成每个图形对应着的点阵集。 打开这个软件先点1选择字符模式,再点2,3设置每个图形的大小,然后从4处在这里插入图片描述写入我们的要显示的图形。生成字模之前点击齿轮(设置)来设置我们生成字模的格式。 一般的我们选择默认就好了,更改一下点阵大小和显示格式就行。到这一步,我们就可以生成自己的图形的点阵集了。 点击生成字模后,我们便得到了这三个汉字的字模了。返回最开始,我们选择模式时更改为图形模式,便可以DIY自己想要显示的图形,自己可以选择图形的大小,这里我选择64*64大小的点阵集来DIY。 至此,我们就得到了4个数组,每个数组显示一个图形。 二、将自定义图形显示在LCD上 我们先定义3个文件,show.c show.h graph.h,并且将上面的4个数组放在graph.h里。 因为特殊字符囧并没有自己的显示编码,所以我们不采用显示编码方式显示图形,而是直接通过数组名来显示。我们直接上函数: //显示一个DIY图形 //x,y:图形显示的坐标 //num:第几个图形 //size:图形大小 //mode:0,正常显示,1,叠加显示 void Show_Graph(u16 x,u16 y,u8 *num,u8 size,u8 mode) { u8 temp; u16 t,t1; u16 y0 = y; u16 x0 = x; u16 csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数 for(t = 0;t < csize;t++) { temp = num[t]; for(t1 = 0;t1 < 8;t1++) { if(temp&0x80)LCD_Fast_DrawPoint(x,y,POINT_COLOR); else if(mode==0)LCD_Fast_DrawPoint(x,y,BACK_COLOR); temp<<=1; y++; if((y-y0) == size) { y=y0; x++; break; } if((x-x0) == size) { x = x0; break; } } } } 这个函数是把原子的Show_Font()显示汉字函数改了改,其实本质就是取得字模的差别,Show_Font()里通过读取W25Q128的相应地址来取得字模,这里我们自己建立了字模,直接显示即可。下面上主函数: #include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "lcd.h" #include "show.h" #include "graph.h" int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2 delay_init(168); //初始化延时函数 uart_init(115200); //初始化串口波特率为115200 LED_Init(); //初始化LED LCD_Init(); //初始化LCD FSMC接口 POINT_COLOR=RED; //画笔颜色:红色 Show_Graph(100,100,(u8*)jiong_64,64,0); Show_Graph(25,200,(u8*)str1,16,0); Show_Graph(75,200,(u8*)str2,16,0); Show_Graph(125,200,(u8*)str3,16,0); while(1); } 三、通过GBK码寻址显示汉字 上面我们是通过自己建立字模,来显示特定的几个汉字,但是在一个完整的系统里,可能需要大量的汉字来供我们使用。这里就要用到我们的GBK库了,通过对应汉字在这个库的偏移量,找到相应汉字的字模,并且显示出来。 大体的思路是,我打算用EEPROM存储GBK库,GBK库我们可以从网上随便找一个都行,这里我还是用原子的SYSTEM文件夹下面自带的GBK16这个库来做。因为探索者板载的24C02大小为2K字节,不足以存储常用的三种大小的库,所以选择一个中间大小。我们这里找到SD卡根目录下SYSTEM/FONT文件夹里的字库: 我们可以看到3个不同大小的GBK字库,和一个UNIGBK.BIN,这个文件一般用在FATFS文件系统时支持中文路径来使用的。如果不需要支持中文路径的话可以不加。GBK16的大小为749k字节,大于24C02的2K字节。!!!!方案错误,24C02大小不足以存储字库! 我们这里只能说一下步骤了(虽然实现不了,但是我想看看结果会是什么样。。): 1、基于FATFS文件系统,通过SD卡把GBK16这个库的文件读取出来,然后写入到EEROM里面。 2、编写显示汉字函数,其入口参数为每个汉字字符的GBK码。 3、调用显示函数,将要显示的汉字显示在LCD上面。 理论上讲,这三部有关文件的操作只在SD卡上运行,所以EEPROM可以不用移植到FATFS文件系统里面,我们读取SD卡上的数据,然后存入EEPROM当中即可。 首先FATFS文件管理,把SD卡里的文件读取出来,然后写入到24C02中,文件路径为: u8*const GBK16_PAT; 这里上一下相关程序: u8 updata_fontx(u16 x,u16 y,u8 size,u8 *fxpath) { u8 res,rval = 0; u16 bread; u32 flashaddr = 0,offset = 0; FIL* ftemp; u8* tempbuf; fupfont.upfont_OK = 0xFF; tempbuf = (u8*)mymalloc(SRAMIN,4096); if(tempbuf == NULL) rval = 1; ftemp = (FIL*)mymalloc(SRAMIN,sizeof(FIL)); if(ftemp == NULL) rval = 1; res = f_open(ftemp,(const TCHAR*)fxpath,FA_READ); if(res) rval = 2; printf("f_open的res的值为:%drn",res); if(rval == 0) { fupfont.gbk16_addr = EERPOM_ADDR + sizeof(fupfont); //字库开始地址 fupfont.gbk16_size = ftemp->fsize; //字库大小 flashaddr = fupfont.gbk16_addr ;//GBK16字库起始地址 while(res == FR_OK) { res = f_read(ftemp,tempbuf,4096,(UINT*)&bread); printf("bread的值为:%drn",bread); if(res != FR_OK) break; AT24CXX_Write(flashaddr + offset,tempbuf,4096); offset += bread; fupd_prog(x,y,size,ftemp->fsize,offset); //进度显示 fftemp->fsize具体每个文件的大小,我们可以掌握 if(bread != 4096)break; } f_close(ftemp); fupfont.upfont_OK = 0xAA; AT24CXX_Write(EERPOM_ADDR,(u8*)&fupfont,sizeof(fupfont)); } myfree(SRAMIN,ftemp); //释放内存 myfree(SRAMIN,tempbuf); //释放内存 return res; } 这里要说一下这个结构体,_up_font fupfont : //这个结构体使用关键字__packed取消了编译器自动优化结构体地址,所以这个结构体总共9字节大小! //我们把这个结构体存储到EEPROM中,即可知道字库是否更新,和存储字库地址 __packed typedef struct { u8 upfont_OK; // 设定这个值为0xAA时,更新字库成功!否则为0xFF u32 gbk16_addr; // GBK16字库的地址 u32 gbk16_size; // GBK16字库的大小 }_up_font; 这个结构体标注了字库地址,字库大小和是否更新标志位,因为我们加了__packed关键字,所以我们结构体变量占用了9字节空间。我们把这9字节空间放进24C02的首地址中,帮助我们标识字库基本信息。那么我们的字库数据就要放在这9字节数据后面,AT24CXX_Write(flashaddr + offset,tempbuf,4096);//flashaddr 即为9字节大小 至此,我们通过SD卡根据文件路径读取文件信息,并将信息写入24C02中,然后我们根据入口参数(一般为字符串)GBK码的大小,算出其偏移,根据偏移在GBK库中找到相应的字模读取出来,然后通过将其打印在LCD屏幕上。 因为打印字模数组的方法我们上面演示过了,所以我们直接上从24C02中,取出字模的函数: //这个函数其实就是读取到字符后,取出其GBK码,然后通过GBK码,找到其对应的字模数组。 //code:输入的字符,通过*运算,可以取其GBK码 //mat:通过GBK码,判断每个汉字的字模数据 void Get_Font_Mat(unsigned char* code,unsigned char* mat,u8 size) { unsigned char qh,ql; unsigned char i; unsigned long foffset; u8 csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数 qh = *code; ql = *(code+1); if(qh<0x81||ql<0x40||ql==0xff||qh==0xff)//非 常用汉字 { for(i=0;i } if(ql<0x7f)ql-=0x40;//注意! else ql-=0x41; qh-=0x81; foffset=((unsigned long)190*qh+ql)*csize; //得到字库中的字节偏移量 AT24CXX_Read(foffset+fupfont.gbk16_addr,mat,csize); } fupfont.gbk16_addr 就是刚才说的结构体大小,字模存储在这个大小后面,我们通过入口参数,算出偏移,然后用偏移+fupfont.gbk16_addr得到一个地址,从这个地址开始取出csize大小的字模,把它放到mat中去。至此,通过GBK寻址显示汉字的方法我们已经说完了。 |
|
|
|
只有小组成员才能发言,加入小组>>
3130 浏览 9 评论
2827 浏览 16 评论
3337 浏览 1 评论
8708 浏览 16 评论
3930 浏览 18 评论
9547浏览 3评论
884浏览 3评论
456浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
455浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2175浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-19 10:35 , Processed in 1.361795 second(s), Total 81, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191