潘多拉开发板STM32L475之LCD与GBK(含GB2312)字体显示

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/euxnijuoh/article/details/100087977

一、GBK字体的内码获取

#include <stdio.h>
#include <stdint.h>

int main(void)
{

    uint8_t *str="国";                 //一个中文字体占2个字节
    uint8_t p,q;
    p=*str;                                 //获取国字内码的前一个字节
    q=*(++str);                          //获取国字内码的前一个字节
    printf("%.2X,%.2X\r\n",p,q);//打印GBK字体内码
    return 0;
}

           

用原子哥开发的内码软件查看国字的内码如下:

                               

国字打印的内码原子哥的内码查询软件是一样的。

每个 GBK 码由 2 个字节组成,第一个字节为 0X81~0XFE,第二个字节分为两部分,一是 0X40~0X7E,二是 0X80~0XFE。其中与 GB2312 相同的区域,字完全相同。

二、根据内码LCD显示点阵库

在LCD上显示“我为中华之崛起而读书”9个字体,先获取它们的内码,如下所示,

#include <stdio.h>
#include <stdint.h>
#include <string.h>

int main(void)
{

    uint8_t *str="为中华之崛起而读书";
    uint8_t i;

    for(i=0;i<(strlen(str)/2);i++)
    {
      printf("%#.2X,%#.2X\r\n",*(str+i*2),*(str+(i*2+1)));
    }

    return 0;
}

“为中华之崛起而读书”的内码如下所示,

              

用“PCtoLCD2002.exe”软件获取“为中华之崛起而读书”的点阵库,如下图所示,

在数组或者内存中以以下方式存储,

                                  Flash地址或EEPROM地址(74个字节)--1个字体的点阵库内存大小

内码高字节1Byte

内码低字节1Byte

字体点阵库72Byte(假设字体为24*24)

定义一个数组,把内码和字体点阵库放在一起,如下图所示,

const uint8_t font[]={
0xCE,0xAA,/*"为"的内码高位和低位*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x02,0x00,0x80,0x04,0x00,0x80,0x08,0x10,0x80,0x10,0x0C,0x80,0x30,0x0E,0x80,0x60,0x00,0x81,0xC0,0x00,0x87,0x00,0x00,0xBC,0x00,0x7F,0xF0,0x00,0x3E,0x88,0x00,0x20,0x88,0x08,0x00,0x84,0x08,0x00,0x86,0x08,0x00,0x83,0x04,0x00,0x81,0x86,0x00,0x80,0x06,0x00,0x80,0x1C,0x00,0xFF,0xF8,0x00,0xFE,0x00,0x00,0x80,0x00,0x00,0x00,0x00,/*"为",0*
    
0xD6,0xD0,/*"中"的内码高位和低位*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0x00,0x03,0xFE,0x00,0x02,0x04,0x00,0x02,0x04,0x00,0x02,0x04,0x00,0x02,0x04,0x00,0x02,0x04,0x00,0x02,0x04,0x00,0x7F,0xFF,0xFE,0x22,0x04,0x0C,0x02,0x04,0x00,0x02,0x04,0x00,0x02,0x04,0x00,0x02,0x04,0x00,0x02,0x04,0x00,0x02,0x04,0x00,0x03,0xFF,0x00,0x03,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"中",1*/
    
0xBB,0xAA,/*"华"的内码高位和低位*/
0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x40,0x80,0x00,0x80,0x80,0x03,0x00,0x80,0x06,0x0E,0x80,0x1B,0xFC,0x80,0x70,0x00,0x80,0x20,0x20,0x80,0x00,0x20,0x80,0x00,0x40,0x80,0x00,0x47,0xFE,0x7F,0xF4,0x84,0x3F,0xF8,0x80,0x01,0x08,0x80,0x03,0x08,0x80,0x02,0x08,0x80,0x04,0x08,0x80,0x0C,0x08,0x80,0x18,0x08,0x80,0x08,0x08,0x80,0x00,0xF8,0x80,0x00,0x00,0x00,0x00,0x00,0x00,/*"华",2*/
    
0xD6,0xAE,/*"之"的内码高位和低位*/
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x18,0x01,0x00,0x10,0x01,0x00,0x20,0x01,0x00,0x20,0x01,0x00,0x60,0x01,0x00,0x90,0x01,0x01,0x10,0x21,0x02,0x08,0x11,0x06,0x08,0x1D,0x0C,0x0C,0x01,0x18,0x0C,0x01,0x30,0x0C,0x01,0x60,0x0C,0x01,0xC0,0x0C,0x01,0x80,0x0C,0x01,0x80,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,/*"之",3*/
    
0xE1,0xC8,/*"崛"的内码高位和低位*/
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0xC0,0x02,0x00,0x40,0x00,0x00,0x80,0x7F,0xFF,0x80,0x00,0x00,0x80,0x00,0x01,0x02,0x03,0xFF,0xCC,0x00,0x00,0x30,0x00,0x01,0xE0,0x3F,0xFE,0x00,0x24,0x00,0x08,0x24,0x7C,0xF8,0x24,0x44,0x88,0x24,0x04,0x08,0x24,0x04,0x08,0x24,0xFF,0xF8,0x24,0x04,0x08,0x24,0x04,0x08,0x3E,0x7E,0x08,0x3E,0x46,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,/*"崛",4*/
    
0xC6,0xF0,/*"起"的内码高位和低位*/
0x00,0x00,0x00,0x00,0x40,0x02,0x00,0x40,0x1C,0x04,0x47,0xE0,0x04,0x4F,0x40,0x04,0x40,0x20,0x04,0x40,0x10,0x7F,0xFF,0xF8,0x24,0x7F,0xF8,0x04,0x42,0x08,0x04,0x42,0x0C,0x04,0xC6,0x04,0x00,0x40,0x04,0x08,0x00,0x04,0x08,0x7F,0xE4,0x08,0x40,0x26,0x08,0x40,0x26,0x08,0x40,0x26,0x08,0x40,0x26,0x08,0x40,0x26,0x0F,0xE0,0x26,0x00,0x03,0xE4,0x00,0x00,0x00,0x00,0x00,0x00,/*"起",5*/

0xB6,0xF8,/*"而"的内码高位和低位*/
0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0xFF,0xFC,0x10,0x80,0x00,0x10,0x80,0x00,0x10,0x80,0x00,0x10,0x80,0x00,0x10,0xFF,0xF8,0x13,0x80,0x00,0x1C,0x80,0x00,0x18,0x80,0x00,0x10,0x80,0x00,0x10,0xFF,0xF8,0x10,0x80,0x08,0x10,0x80,0x04,0x10,0x80,0x04,0x10,0x80,0x06,0x11,0xFF,0xFC,0x30,0x80,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"而",6*/

0xB6,0xC1,/*"读"的内码高位和低位*/
0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x20,0x40,0x00,0x18,0x7F,0xF8,0x0C,0x40,0x08,0x00,0x00,0x10,0x01,0x00,0x20,0x09,0x00,0xC2,0x09,0x08,0x82,0x09,0x44,0x84,0x09,0x27,0x84,0x09,0x30,0x88,0x09,0x00,0x98,0x7F,0x00,0xB0,0x09,0x7F,0xE0,0x09,0x3E,0x90,0x09,0x00,0x90,0x09,0x00,0x88,0x09,0x60,0x8C,0x01,0x80,0x86,0x01,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,/*"读",7*/

0xCA,0xE9,/*"书"的内码高位和低位*/
0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x02,0x08,0x00,0x02,0x08,0x00,0x02,0x08,0x00,0x02,0x08,0x00,0x02,0x08,0x00,0x42,0x08,0x01,0x3F,0xFF,0xFE,0x02,0x08,0x00,0x02,0x08,0x00,0x02,0x08,0x00,0x02,0x08,0x00,0x02,0x08,0x00,0x02,0x18,0x20,0x23,0xF8,0x10,0x12,0x08,0x18,0x1C,0x08,0x18,0x0E,0x0F,0xF0,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00/*"书",8*/
}

//==============================================================================//

把字体通过函数作为实参传进来,获取实参字体的内码,然后扫描font数组中的每一个字体的内码,如果内码相等,则送到LCD上显示,如果不相等,则往下扫描,直到内码相等跳出或者把数组的所有内码扫描完匹配结束。

void displayGB2312(u16 x, u16 y, const u8 * ch, u8 size, u8 fontNum, u8 mode)
{
    u32  t, dataBit;
    char temp;
    uint8_t high,low,i;
    uint16_t k;
    u16 y0 = y;
      
    for(i = 0; i < fontNum; i++){ //fontNum为字体个数
              high = *(ch+i*2);        //high为高字节内码
          low  = *(ch+(i*2+1));      //low为低字节内码
            
                for(k = 0;k < sizeof(font);k+=((sizeof(font)-2*fontNum)/fontNum+2))//预扫描所有字体的内码
                {
                        if((font[k] == high)&&((font[k+1] == low)))//内码的判断
                        {
                                for(t = k+2; t < (k+((sizeof(font)-2*fontNum)/fontNum+2)); t++)//16-->32,24-->48,36-->72
                                {                                                      
                                        temp = font[t];    //得到点阵数据 
                                        for(dataBit = 0; dataBit < 8; dataBit++)
                                        {
                                            if(temp & 0x80)
                                            {
                                                LCD_Draw_ColorPoint(x, y, POINT_COLOR);
                                            }else if(mode==0){
                                                LCD_Draw_ColorPoint(x, y, BACK_COLOR);
                                            }
                                            temp <<= 1;
                                            y++;
                                            if((y - y0) == size)
                                            {
                                                    y = y0;
                                                    x++;
                                                    break;
                                            }
                                        }       
                                }
                                break;//内码相等,送给LCD显示,并结束扫描,继续下一个字体的内码扫描
                            }
                }                
        }
}

//=================================================================================//

main函数实现如下:

#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "lcd.h"
#include "font.h"
#include "key.h"
#include "rtc.h"

int main(void)
{
    HAL_Init();
    SystemClock_Config();  //初始化系统时钟为80M
    delay_init(80);                 //初始化延时函数80M系统时钟
    uart_init(115200);           //初始化串口,波特率为115200

    LED_Init();                     //初始化LED
    LCD_Init();                     //初始化LCD
    KEY_Init();
    RTC_Init();

    while(1)
    { 
            POINT_COLOR = RED;  //字体颜色
            BACK_COLOR = WHITE;   //字体背景颜色

            displayGB2312(10, 100, (uint8_t*)"为中华之崛起而读书",24, 9, 0);//x=10,y=100,24字体大小,9为字体个数
    }
}

//==================================================================================//

在LCD上显示如下图所示,

                                                

                                

由于是晚上,液晶屏和字体比较小,在上图没有看到字体在LCD上显示,下图会看到字体显示。

谢谢!光临......

                                  

猜你喜欢

转载自blog.csdn.net/euxnijuoh/article/details/100087977