stm32 utf8转unicode gb2312,通过ec20功放播放语音

stm32 utf8转unicode gb2312


由于我需要通过json接收平台下发 的文字,通过移远电子EC600 ec20 模块播放。
但是由于平台下发的是UTF8格式,EC600 通信模块只执行 unicode或者gbk,所以需要转化一下。

首先将utf8转为unicode,这时候将内容处理可以直接给模块使用
比如平台下发 “1响严严”
utf8内容为 “\x31\xE5\x93\x8D\xE4\xB8\xA5\xE4\xB8\xA5”
在这里插入图片描述
unicode 格式为 “003154CD4E254E25”(16进制)

AT+QTTS=1,“003154CD4E254E25” 这时候其实可以播放,当然也可以继续转为GBK,需要查表字库,字库大小40k左右

1、将Utf8 – Unicode

/**
 * @brief utf8编码转unicode字符集(usc4),最大支持4字节utf8编码,(4字节以上在中日韩文中为生僻字)
 * @param *utf8 utf8变长编码字节集1~4个字节
 * @param *unicode utf8编码转unicode字符集结果,最大4个字节,返回的字节序与utf8编码序一致
 * @return length 0:utf8解码异常,others:本次utf8编码长度
 */

#define PARSE_ERROR -1
uint8_t UTF8ToUnicode(uint8_t* utf8, uint32_t* unicode) {
    const uint8_t lut_size = 3;
    const uint8_t length_lut[] = { 2, 3, 4 };
    const uint8_t range_lut[] = { 0xE0, 0xF0, 0xF8 };
    const uint8_t mask_lut[] = { 0x1F, 0x0F, 0x07 };

    uint8_t length = 0;
    uint8_t b = *(utf8 + 0);
    uint32_t i = 0;

    if (utf8 == NULL) {
        *unicode = 0;
        return PARSE_ERROR;
    }
    // utf8编码兼容ASCII编码,使用0xxxxxx 表示00~7F
    if (b < 0x80) {
        *unicode = b;
        return 1;
    }
    // utf8不兼容ISO8859-1 ASCII拓展字符集
    // 同时最大支持编码6个字节即1111110X
    if (b < 0xC0 || b > 0xFD) {
        *unicode = 0;
        return PARSE_ERROR;
    }
    for (i = 0; i < lut_size; i++) {
        if (b < range_lut[i]) {
            *unicode = b & mask_lut[i];
            length = length_lut[i];
            break;
        }
    }
    // 超过四字节的utf8编码不进行解析
    if (length == 0) {
        *unicode = 0;
        return PARSE_ERROR;
    }
    // 取后续字节数据
    for (i = 1; i < length; i++) {
        b = *(utf8 + i);
        // 多字节utf8编码后续字节范围10xxxxxx~10111111
        if (b < 0x80 || b > 0xBF) {
            break;
        }
        *unicode <<= 6;
        // 00111111
        *unicode |= (b & 0x3F);
    }
    // 长度校验
    return (i < length) ? PARSE_ERROR : length;
}

2、将Unicode–gbk

可以直接查表获得。gbk前一部分是和ascII重叠,中文部分采用查表,速度最快。

const unsigned short mb_uni2gb_table[20902] =
{
.....
0xd9df,0xfd97,0xfd98,0xfd99,0xfd9a,0xfd9b
};

改写接口,将字符串分段解析成gbk编码,并保存,

int ucode_gbk() {
    // 严 utf8 E4 B8 A5

    uint32_t buffer;
    //uint8_t utf8[] = "\xE4\xB8\xA5";
    //uint8_t utf8[] = "\xE5\x93\x8D";
    uint8_t utf8[] = "\x31\xE5\x93\x8D\xE4\xB8\xA5\xE4\xB8\xA5";

    int utf8_max_len = strlen(utf8);

    uint16_t utf16[2] = { 0 };//暂存 unicode编码
    uint8_t len;//转换临时长度

    uint8_t unicode_buf[1024] = "";
    int step = 0;
    int unicode_buf_len = 0;//每次返回的长度
    int unicode_buf_step = 0;//输出的数组的位置

    while (step < utf8_max_len)
    {
        buffer = 0;
        len = UTF8ToUnicode((utf8 + step), &buffer);
        if (len == PARSE_ERROR)
            break;

        //unicode_buf_len = unicodetochar(buffer, unicode_buf + unicode_buf_step);//整数 转成16进制数组,默认2位
        //unicode_buf_len = UnicodetoASCII(buffer, unicode_buf + unicode_buf_step);//整数 转成16进制数组
        
        UnicodeToUTF16(buffer, utf16);
        if ((utf16[0]- 0x4e00)< sizeof(mb_uni2gb_table)/sizeof(mb_uni2gb_table[0]))
        {
            buffer = mb_uni2gb_table[utf16[0] - 0x4e00];  //查表获取
            unicode_buf_len = UnicodetoASCII(buffer, unicode_buf + unicode_buf_step);  // 
        }
        else
        {
            *(unicode_buf + unicode_buf_step) = utf16[0] & 0xff;
            unicode_buf_len = 1;
        }
        unicode_buf_step += unicode_buf_len;
        step += len;

    }

    printf("\r\n%s", unicode_buf);
    return 0;
}

https://download.csdn.net/download/cubmonk/83801457
代码

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值