完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我写了大半天的程序,从像素位置显示字符串函数开始一点点调试改来的,我这里只做了32*32的字体实现,可以参考本程序,实现12,16,24等字体的这个功能,先看一下使用说明: 我封装出来的函数: // x:0-14,y:0-24,单位是每个字32像素的个数,改造成LCD1525这样的屏幕,我的屏幕是480*800,总共显示15x25个汉字(类似带字库的LCD12864屏幕那样的显示方式),支持自动换行,屏幕上下自动循环,字母串自动补充空格实现对齐显示,不然汉字的一半刚好显示在屏幕结尾时候,是会乱码的 void myShow_String_15x25LCD(u8 x,u8 y,u8*str,u32 color) 主函数中这样调用后 显示效果: 可以看到当字符串中字母串是奇数个的时候,我是把它添加了空格的,这样每个汉字始终是在正确的位置上,其次屏幕底部自动换行到屏幕顶部了,实现了我们需要的功能。 所以只要我们给这个函数一个很长很长的字符串,比如在做记事本这类软件时候,从sd卡文本文件里面读取到任意长(里面用的是u16的类型,那么最大读取文本长度可能不能太大,一般而言几千字符没问题,那就一部分一部分的读呗就可以了)的字符串,然后给这个函数就能自动换行,自动上下屏幕循环显示了,不需要我们自己手动去费尽心思考虑显示位置,何时换行,对齐等等问题 核心.c代码我直接贴出来,免得去csdn下载 我是在正点原子的教程汉字显示实验改的,如果需要完整工程可以找我要,也可以自己去原子那儿下载,然后把这个.C和.h文件替换掉即可: text.h text.h #ifndef __TEXT_H__ #define __TEXT_H__ #include "fontupd.h" // //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //ALIENTEK STM32H7开发板 //汉字显示 驱动代码 //正点原子@ALIENTEK //技术论坛:www.openedv.com //创建日期:2018/8/2 //版本:V1.0 //版权所有,盗版必究。 //Copyright(C) 广州市星翼电子科技有限公司 2014-2024 //All rights reserved // void Get_HzMat(unsigned char *code,unsigned char *mat,u8 size); //得到汉字的点阵码 void Show_Font(u16 x,u16 y,u8 *font,u8 size,u8 mode); //在指定位置显示一个汉字 void Show_Str(u16 x,u16 y,u16 width,u16 height,u8*str,u8 size,u8 mode); //在指定位置显示一个字符串 void Show_Str_Mid(u16 x,u16 y,u8*str,u8 size,u8 len); // x:0-14,y:0-24,单位是每个字32像素的个数,改造成LCD12864这样的屏幕,总共显示15x25个汉字 void myShow_String_15x25LCD(u8 x,u8 y,u8*str,u32 color); #endif text.c #include "sys.h" #include "fontupd.h" #include "w25qxx.h" #include "lcd.h" #include "text.h" #include "string.h" #include "usart.h" #include "malloc.h" // //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //ALIENTEK STM32H7开发板 //汉字显示 驱动代码 //正点原子@ALIENTEK //技术论坛:www.openedv.com //创建日期:2018/8/2 //版本:V1.0 //版权所有,盗版必究。 //Copyright(C) 广州市星翼电子科技有限公司 2014-2024 //All rights reserved // //code 字符指针开始 //从字库中查找出字模 //code 字符串的开始地址,GBK码 //mat 数据存放地址 (size/8+((size%8)?1:0))*(size) bytes大小 //size:字体大小 void Get_HzMat(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); 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; //得到字库中的字节偏移量 switch(size) { case 12: W25QXX_Read(mat,foffset+ftinfo.f12addr,csize); break; case 16: W25QXX_Read(mat,foffset+ftinfo.f16addr,csize); break; case 24: W25QXX_Read(mat,foffset+ftinfo.f24addr,csize); break; case 32: W25QXX_Read(mat,foffset+ftinfo.f32addr,csize); break; } } //显示一个指定大小的汉字 //x,y :汉字的坐标 //font:汉字GBK码 //size:字体大小 //mode:0,正常显示,1,叠加显示 void Show_Font(u16 x,u16 y,u8 *font,u8 size,u8 mode) { u8 temp,t,t1; u16 y0=y; u8 dzk[128]; u8 csize=(size/8+((size%8)?1:0))*(size); //得到字体一个字符对应点阵集所占的字节数 if(size!=12&&size!=16&&size!=24&&size!=32)return; //不支持的size Get_HzMat(font,dzk,size); //得到相应大小的点阵数据 for(t=0;t temp=dzk[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; } } } } u16 myGetLengthOfStr(u8*str) { u16 n=0; while(*str!=0)//数据未结束 { ++str; ++n; } return n; } u16 myGetNumSpaceInsetFromStr(u8*str) { u16 n=0; u16 cntSpace=0; while(*str!=0)//数据未结束 { if(*str>0x80) // 是汉字 { str=str+2; if(n%2==1) // 如果n是奇数个英文字符 { cntSpace++; } n=0; } else { str++; n++; } } return cntSpace; } // 函数作用:把一个字符串里面连续的英文字符变成偶数个,且存放在新的空间,方便后面的液晶显示函数 // 比如"你abc好a它b"->"你abc 好a 它b ",如果本来就是偶数个,那就不需要填充空格了 u8*myStr2StrHaveSpace(u8*str) { u16 nStr=myGetNumSpaceInsetFromStr(str); u8* p=mymalloc(SRAMEX,myGetLengthOfStr(str)+nStr+1);// 最后一个填' |