基于cc936.c的外部flash的GBK与Unicode相互转换

链接:https://pan.baidu.com/s/1X9x-o6dDWBLpN-aTaMK-lg 
提取码:nyfo

文件自取

cc936.c里有两个87k的巨大数组,也就是GBK与Unicode的转换表,通过查表就可以得到转换之后的编码,但是由于数组太大了,每次下载程序都要多花一些时间,有些单片机甚至无法同时使用两个转换表。所以把两个转换表存到外部flash里就十分快乐了。

首先从文件系统fatfs里得到cc936.c,然后把这个c文件添加到自己的工程,再创建一个头文件cc936.h(其实不创建也可以),再把其中一个数组注释掉,修改ff_convert函数,还有另外一个函数我直接删掉了,然后再添加一个把数组写入flash的函数,就可以了。

cc936.h

#ifndef __CC936_H_
#define __CC936_H_

#include <stdio.h>
#include "flash.h"
#include <string.h>

/* This type MUST be 8-bit */
typedef unsigned char	BYTE;

/* These types MUST be 16-bit */
typedef short			SHORT;
typedef unsigned short	WORD;
typedef unsigned short	WCHAR;

/* These types MUST be 16-bit or 32-bit */
typedef int				INT;
typedef unsigned int	UINT;

/* These types MUST be 32-bit */
typedef long			LONG;
typedef unsigned long	DWORD;

void test(void);

#endif



由于这里stm32没办法同时装下两个数组,所以分开存储了

首先是Unicode-GBK的cc936.c,把uni2oem数组注释掉,然后修改添加以下代码,再调用test函数就OK了。

#define FONT_LIB_SIZE  87172

WCHAR ff_convert (	/* Converted code, 0 means conversion error */
	WCHAR	chr,	/* Character code to be converted */
	UINT	dir		/* 0: Unicode to OEM code, 1: OEM code to Unicode */
)
{
	const WCHAR *p;
	WCHAR c;
    uint8_t temp[2];
	int i, n, li, hi;
    int temp_addr;

	if (chr < 0x80) {	/* ASCII */
		c = chr;
	} else {
		if (dir) {		/* OEM code to unicode */
			temp_addr = FONT_LIB_CC936_OEM2UNI_ADDR;
			hi = FONT_LIB_SIZE / 4 - 1; 
		} else {		/* Unicode to OEM code */
			temp_addr = FONT_LIB_CC936_UNI2OEM_ADDR;
			hi = FONT_LIB_SIZE / 4 - 1; 
		}
		li = 0;
        
		for (n = 16; n; n--) {
			i = li + (hi - li) / 2;
            SPI_Flash_Read(temp, temp_addr + i*4, 2);
			if (chr == (temp[1]<<8 | temp[0])) break;
			if (chr > (temp[1]<<8 | temp[0]))
				li = i;
			else
				hi = i;
		}
        SPI_Flash_Read(temp, temp_addr + i*4 + 2, 2);
		c = n ? (temp[1]<<8 | temp[0]) : 0;
	}

	return c;
}



char temparray[4096];
void test(void)
{
    //printf("sizeof uni2oem = %d\r\n", sizeof uni2oem);
    printf("sizeof oem2uni = %d\r\n", sizeof oem2uni);
    int i = 0;
    int j = 0;
    for(i = 0; i < sizeof(oem2uni)/4096 + 1; i++)
    {
        SPI_Flash_Erase_Sector(FONT_LIB_CC936_OEM2UNI_ADDR / 4096 + i);
    }

    int offset = 0;
    int temp_addr = FONT_LIB_CC936_OEM2UNI_ADDR;
    
    for(j = 0; j < sizeof(oem2uni)/4096; j++)
    {
        memcpy(temparray, oem2uni + offset/2, sizeof(temparray));
        SPI_Flash_Write((u8 *)temparray, temp_addr + offset, sizeof(temparray));
        offset += sizeof(temparray);
        printf("write %d byte\r\n", offset);
    }
    for(i = 0, j = offset; j < sizeof(oem2uni); j+=2, i+=2)
    {
        temparray[i + 1] = (oem2uni[(j) / 2] >> 8) & 0xff;
        temparray[i] = oem2uni[(j) / 2] & 0xff;
    }
    SPI_Flash_Write((u8 *)temparray, temp_addr + offset, i);
    offset += i;
    printf("write %d byte\r\n", offset);
#if 0
uint8_t temp[2];
int temp_addr1;
temp_addr1 = FONT_LIB_CC936_OEM2UNI_ADDR;
for(int i = 0; i < FONT_LIB_SIZE / 2; i++)
{
    SPI_Flash_Read(temp, temp_addr1 + (i*2)*2, 2);
    if((temp[1]<<8 | temp[0]) == 0xb0a1)
    {
       
        printf("%d\r\n", i);
        return;
    }
}
#endif
    printf("\r\ntest: GBK: 0xb0a1\r\nUnicode = ");
    printf("%04x\r\n", ff_convert(0xb0a1, 1));
    
}

然后是GBK-Unicode,把oem2uni数组注释掉,然后修改添加以下代码,再调用test函数就OK了。

#define FONT_LIB_SIZE  87172

WCHAR ff_convert (	/* Converted code, 0 means conversion error */
	WCHAR	chr,	/* Character code to be converted */
	UINT	dir		/* 0: Unicode to OEM code, 1: OEM code to Unicode */
)
{
	const WCHAR *p;
	WCHAR c;
    uint8_t temp[2];
	int i, n, li, hi;
    int temp_addr;

	if (chr < 0x80) {	/* ASCII */
		c = chr;
	} else {
		if (dir) {		/* OEM code to unicode */
			temp_addr = FONT_LIB_CC936_OEM2UNI_ADDR;
			hi = FONT_LIB_SIZE / 4 - 1; 
		} else {		/* Unicode to OEM code */
			temp_addr = FONT_LIB_CC936_UNI2OEM_ADDR;
			hi = FONT_LIB_SIZE / 4 - 1; 
		}
		li = 0;
		for (n = 16; n; n--) {
			i = li + (hi - li) / 2;
            SPI_Flash_Read(temp, temp_addr + i*4, 2);
			if (chr == (temp[1]<<8 | temp[0])) break;
			if (chr > (temp[1]<<8 | temp[0]))
				li = i;
			else
				hi = i;
		}
        SPI_Flash_Read(temp, temp_addr + i*4 + 2, 2);
		c = n ? (temp[1]<<8 | temp[0]) : 0;
	}

	return c;
}



char temparray[4096];
void test(void)
{
    printf("sizeof oem2uni = %d\r\n", sizeof uni2oem);
    //printf("sizeof uni2oem = %d\r\n", sizeof uni2oem / 4 - 1);
    int i = 0;
    int j = 0;
    for(i = 0; i < sizeof(uni2oem)/4096 + 1; i++)
    {
        SPI_Flash_Erase_Sector(FONT_LIB_CC936_UNI2OEM_ADDR / 4096 + i);
    }

    int offset = 0;
    int temp_addr = FONT_LIB_CC936_UNI2OEM_ADDR;
    
    for(j = 0; j < sizeof(uni2oem)/4096; j++)
    {
        memcpy(temparray, uni2oem + offset/2, sizeof(temparray));
        SPI_Flash_Write((u8 *)temparray, temp_addr + offset, sizeof(temparray));
        offset += sizeof(temparray);
        printf("write %d byte\r\n", offset);
    }
    for(i = 0, j = offset; j < sizeof(uni2oem); j+=2, i+=2)
    {
        temparray[i + 1] = (uni2oem[(j) / 2] >> 8) & 0xff;
        temparray[i] = uni2oem[(j) / 2] & 0xff;
    }
    SPI_Flash_Write((u8 *)temparray, temp_addr + offset, i);
    offset += i;
    printf("write %d byte\r\n", offset);
#if 0
uint8_t temp[2];
int temp_addr1;
temp_addr1 = FONT_LIB_CC936_UNI2OEM_ADDR;
for(int i = 0; i < FONT_LIB_SIZE / 2; i++)
{
    SPI_Flash_Read(temp, temp_addr1 + (i*2)*2, 2);
    if((temp[1]<<8 | temp[0]) == 0x554a)
    {
       
        printf("%d\r\n", i);
        return;
    }
}
#endif
    printf("\r\ntest: Unicode: 0x554a\r\nGBK = ");
    printf("%04x\r\n", ff_convert(0x554a, 0));
    
}

里边的存储地址根据实际情况修改,后续就可以在自己的程序里通过ff_convert函数来进行转换了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值