完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
在屏幕上显示字符我之前就在做好了,之前只是可以显示。这两天把显示部分做了些修改。
修改如下 1.加了换行 2.字体大小大小的适应,如果以后换了字体简单修改后就可以用了 3.显示内容过多时自动换行 4.字距 行距的控制 5.加入了个显示控制结构体,方便做参数修改, 6.增加了print参数的单独配置函数 先声明 开发板 德飞莱STM32系列尼莫M3S 1.TFTLCD屏幕的配置是引用开发板的汉字显示程序 2.串口指令是参照“C语言中文网中的51单片机教程” 3.flash SPI也是借鉴开发板程序做了大量修改来符合自己的程序。。 在屏幕上显示字符的前提 1.最重要的当然是要有TFTLCD屏幕啦并且配置好参数,还有有个LCD显存地址设置函数 还有窗口设置函数 2.还有就是字库了,一般使用点阵字库,网上有字库生成工具, 3.把字库写到flash芯片。 4flash 要有个 读取指定个数的函数, 下面看代码 在这里插入代码片 #include “text.h” extern struct { u16 backC; ///底色 u16 pen; ///画笔颜色 }LCD_Colour; InitLcdPrintTypedef PrintInit; uint32_t CN_PYL; uint32_t CH_PYL; /*--------------------print参数初始化--------------------*/ void InitPrint(){ PrintInit.backC = LCD_Colour.backC; ; //底色 PrintInit.pen = LCD_Colour.pen; //字体颜色颜色 PrintInit.Print_X = 1; //起始打印位置 X方向 PrintInit.Print_Y = 2; //起始打印位置 Y方向 PrintInit.size_H = 32; //字体大小 高度 PrintInit.size_L = 32; //字体大小 宽度 PrintInit.Word_Spacing = 1; //字距 PrintInit.Line_Spacing = 1; //行距 PrintInit.Word_Wrap = 1; //自动换行 //计数中文字符要读取的点阵字节数 CN_PYL = ((uint32_t)PrintInit.size_H * (uint32_t)PrintInit.size_L)/8; //计数英文字符要读取的点阵字节数 CH_PYL = ((uint32_t)PrintInit.size_H * (uint32_t)PrintInit.size_L)/16; } /*--------------------print字体颜色配置--------------------*/ void ConfigPrintColour(uint16_t Print_backC, uint16_t Print_pen) { PrintInit.backC = Print_backC; PrintInit.pen = Print_pen; } /*--------------------print起始打印位置--------------------*/ void ConfigPrintSite(uint16_t Print_X, uint16_t Print_Y) { PrintInit.Print_X = Print_X; PrintInit.Print_Y = Print_Y; } /*--------------------print字体大小配置--------------------*/ void ConfigPrintSize(uint8_t size_H, uint8_t size_L) { PrintInit.size_H = size_H; PrintInit.size_L = size_L; CN_PYL = ((uint32_t)PrintInit.size_H * (uint32_t)PrintInit.size_L) / 8; CH_PYL = ((uint32_t)PrintInit.size_H * (uint32_t)PrintInit.size_L) / 16; } /*--------------------print行距字距配置--------------------*/ void ConfigPrintSpacing(uint8_t Word_Spacing, uint8_t Line_Spacing) { PrintInit.Word_Spacing = Word_Spacing; PrintInit.Line_Spacing = Line_Spacing; } /*--------------------print自动换行配置--------------------*/ void ConfigPrintWord_Wrap(uint8_t Word_Wrap) { PrintInit.Word_Wrap = Word_Wrap; } /*--------------------打印字体点阵--------------------*/ void LCD_CharDot(uint8_t *dot, uint8_t c) { uint8_t p = 0x01; //像素点控制, KS_GRAM; //LCD RAM入口 /*汉字打印*/ if (c 》 1) { p = 0x80; //这与点阵字体的存储方式有关 //打印点阵行控制 for (uint8_t i = PrintInit.size_H; i 》 0; i--) { //打印点阵列控制 for(uint8_t j = PrintInit.size_L / 8; j 》 0; j--){ while (p) { if(*dot&p) W_GRAM = PrintInit.pen; //字体打印 else W_GRAM = PrintInit.backC; //底色打印 p = p 》》 1; } p = 0x80; dot++; } } } /*英文打印*/ else { for (uint8_t i = PrintInit.size_H; i 》 0; i--) { for(uint8_t j = PrintInit.size_L / 16; j 》 0; j--){ while (p) { if(*dot&p) W_GRAM = PrintInit.pen; //字体打印 else W_GRAM = PrintInit.backC; //底色打印 p = p 《《 1; } p = 0x01; dot++; } } } } /*-----------------在LCD屏上打印字符串-----------------*/ void LCD_print(uint8_t *string) { uint8_t dot[128]; //临时存储 用来存储从Flash中读出的字符点阵数据 uint8_t GBK_H, GBK_L; //GBK编码 高字节 和低字节 uint32_t GBK; //字符点阵在flash中的地址 uint16_t x = PrintInit.Print_X; //字符打印位置控制 X方向 uint16_t y = PrintInit.Print_Y; //字符打印位置控制 Y方向 while (*string!=‘ ’) { GBK_H = *string; if(*string==‘n’){ x = PrintInit.Print_X; y = y + (PrintInit.Line_Spacing + PrintInit.size_H) - 1; } else{ /*汉字*/ if (GBK_H 》 0x80) { GBK_L = *(++string); GBK_H -= 0x81; if (GBK_L 》 0x7f) GBK_L -= 0x41; else GBK_L -= 0x40; //计算所打印的字符在Flash字库存储的位置 GBK = ((uint32_t)190 * GBK_H + GBK_L) * CN_PYL+ (uint32_t)CH_PYL * 96 ; //从Flash字库中读取字符点阵存放到dot数组中 FLASH_Read_Data(dot, GBK, CN_PYL); //设置打印窗口 LCD_Window(x, x + PrintInit.size_L - 1, y, y + PrintInit.size_H - 1); LCD_X_Y(x, y); //设置打印起始地址 LCD_CharDot(dot, 2); //打印字符 //调整字距字距 x = x + (PrintInit.size_L - 1 + PrintInit.Word_Spacing); //检测本行是否无法显示所有内容,判断是否要自动换 if ((239 - x 《 PrintInit.size_L || x 》= 239) && PrintInit.Word_Wrap) { 行 x = PrintInit.Print_X; y = y + (PrintInit.Line_Spacing + PrintInit.size_H) - 1; } } /*英文*/ else { /*---------ASCII码一共有128个可以显示出来的只有96个字库里也只有这96个--------*/ GBK = (GBK_H-0x20)* CH_PYL; //计算所打印的字符在Flash字库存储的位置 FLASH_Read_Data(dot, GBK, CH_PYL); //ASCII码一共有128个可以显示出来的只有96个字库里也只有这96个 LCD_Window(x, x + PrintInit.size_L / 2 - 1, y, y + PrintInit.size_H -1); LCD_X_Y(x, y); LCD_CharDot(dot, 1); x = x + (PrintInit.size_L / 2 + PrintInit.Word_Spacing)-1; if ((239 - x 《 (PrintInit.size_L/2) || x 》= 239) && PrintInit.Word_Wrap) { x = PrintInit.Print_X; y = y + (PrintInit.Line_Spacing + PrintInit.size_H) - 1; } } } string++; } } } } 下面是头文件 #ifndef __TEXT_H #define __TEXT_H #include “stm32f10x.h” #include “tft.h” #include “usart.h” typedef struct { uint16_t backC; //底色 uint16_t pen; //字体颜色颜色 uint16_t Print_X; //起始打印位置 X方向 uint16_t Print_Y; //起始打印位置 Y方向 uint8_t size_H; //字体大小 高度 uint8_t size_L; //字体大小 宽度 uint8_t Word_Spacing; //字距 uint8_t Line_Spacing; //行距 uint8_t Word_Wrap; //自动换行 }InitLcdPrintTypedef; void InitPrint(); //print参数初始化 void ConfigPrintColour(uint16_t backC, uint16_t pen); //print字体颜色配置 void ConfigPrintSite(uint16_t Print_X, uint16_t Print_Y); //print起始打印位置 void ConfigPrintSize(uint8_t size_H, uint8_t size_L); //print字体大小配置 void ConfigPrintSpacing(uint8_t Word_Spacing, uint8_t Line_Spacing); //print行距字距配置 void ConfigPrintWord_Wrap(uint8_t Word_Wrap); //print自动换行配置 1:自动换行 0:不自动换行 void LCD_CharDot(uint8_t *dot, uint8_t c); //打印字体点阵 void LCD_print(uint8_t *string); //在LCD屏上打印字符串 #endif 下面开始代码讲解 为了以后方便使用我写了5个print配置函数,因为有的时候不一定全部参数都会配置,所以做了单独配置的函数。 GBK字库地址的计算: GBK汉字的编码方式 第一个字节为 0x81~0xFE 称为汉字的区码 第二字节为两部分 1:0x40~0x7E 2:0x80~0xFE 称为汉字的位码 这就是汉字的区位码 接下来就是怎么把区位码转换成我们下载到Flash中字库的地址,首先我们要弄清楚几个问题 1.一个汉字的点阵集是多少个字节,如 3232的汉字 3232/8=128字节 英文的话 16*32/8=64字节 2.字库的点阵集是连续下载到Flash里的(我的字库ASCII和GBK是连着的,我先下载的ASCII接着下载GBK) 3.ASCII可以在屏幕上显示的只有96个字符 先判断第一个字节 若小于等于0x80,则编码为ASCII,说明是英文字符 英文字符因为前面32个是控制字符所以 ASCII字库的起始编码为0x20 uint32_t CH_PYL; //英文字符要读取的点阵字节数 uint32_t GBK; //字符点阵在flash中的地址 uint8_t GBK_H, GBK_L; //GBK编码 高字节 和低字节 uint8_t *string //要显示的字符 GBK_H = *string; if (GBK_H 《=0x80) GBK = (GBK_H-0x20)* CH_PYL; 若第一个字节大于0x80说明编码为GBK第一个字节和第二个字节组成区位码 第一个字节减去0x81就是我们字库的正确区码 然后判断第二个字节 如果小于0x7f则减去0x40,如大于0x7f则减去0x41。 uint32_t CH_PYL; //英文字符要读取的点阵字节数 uint32_t GBK; //字符点阵在flash中的地址 uint8_t GBK_H, GBK_L; //GBK编码 高字节 和低字节 uint8_t *string //要显示的字符 GBK_H = *string; //第一个字节 if (GBK_H 》 0x80) { GBK_L = *(++string); //第二个字节 GBK_H -= 0x81; if (GBK_L 》 0x7f) GBK_L -= 0x41; else GBK_L -= 0x40; GBK = ((uint32_t)190 * GBK_H + GBK_L) * CN_PYL+ (uint32_t)CH_PYL * 96 ; //计算所打印的字符在Flash字库存储的位置 为什么高位要*190:因为GBK一个区有190个位,为什么减去0x41:因为0x400x7E与0x800xFE空了个0x7f,+ (uint32_t)CH_PYL * 96是为什么:因为GBK字库紧随ASCII其后,ascii在flash的起始地址为0x00 最后 我认为这次汉字显示中有难度的是: 1.怎么把字库下载到flash中 下载ASCII时没问题 但下GBK时非常容易中断,32*32的GBK字库文件有3MB大 2.字库区位码转换成flash中的地址,我在网上看了好多资料。 3.这只是我的笔记。 |
|
|
|
只有小组成员才能发言,加入小组>>
4508个成员聚集在这个小组
加入小组3334 浏览 0 评论
航顺(HK)联合电子发烧友推出“近距离体验高性能Cortex-M3,免费申请价值288元评估板
4262 浏览 1 评论
4289 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 00:48 , Processed in 0.448681 second(s), Total 45, Slave 38 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号