LTDC-DMA2D显示屏显示-编码标准(三)
一、字符编码
由于计算机只能识别0和1,文字也只能以0和1的形式在计算机里存储,所以我们需要对文字进行编码才能让计算机处理,编码的过程就是规定特定的01数字串来表示特定的文字,最简单的字符编码例子是ASCII码。
ASCII码(0~255)
在程序设计中使用ASCII编码表约定了一些控制字符、英文及数字。它们在存储器中,本质也是二进制数,只是我们约定这些二进制数可以表示某些特殊意义。
ASCII码分为两部分:
第一部分是控制字符或通讯专用字符(编码0~31)
它们并没有特定的图形显示,但会根据不同的应用程序,而对文本显示有不同的影响。
十进制 十六进制 缩写/字符 解释 0 0 NUL(null) 空字符 1 1 SOH(start of headline) 标题开始 2 2 STX (start of text) 正文开始 3 3 ETX (end of text) 正文结束 4 4 EOT (end of transmission) 传输结束 5 5 ENQ (enquiry) 请求 6 6 ACK (acknowledge) 收到通知 7 7 BEL (bell) 响铃 8 8 BS (backspace) 退格 9 9 HT (horizontal tab) 水平制表符 10 0A LF (NL line feed, new line) 换行键 11 0B VT (vertical tab) 垂直制表符 12 0C FF (NP form feed, new page) 换页键 13 0D CR (carriage return) 回车键 14 0E SO (shift out) 不用切换 15 0F SI (shift in) 启用切换 16 10 DLE (data link escape) 数据链路转义 17 11 DC1 (device control 1) 设备控制1 18 12 DC2 (device control 2) 设备控制2 19 13 DC3 (device control 3) 设备控制3 20 14 DC4 (device control 4) 设备控制4 21 15 NAK (negative acknowledge) 拒绝接收 22 16 SYN (synchronous idle) 同步空闲 23 17 ETB (end of trans. block) 传输块结束 24 18 CAN (cancel) 取消 25 19 EM (end of medium) 介质中断 26 1A SUB (substitute) 替补 27 1B ESC (escape) 换码(溢出) 28 1C FS (file separator) 文件分割符 29 1D GS (group separator) 分组符 30 1E RS (record separator) 记录分离符 31 1F US (unit separator) 单元分隔符 第二部分是包括空格、阿拉伯数字、标点符号、大小写英文字母以及“DEL(删除控制)”(32~127)
除最后一个DEL符号外,都能以图形的方式来表示,它们属于传统文字书写系统的一部分。
十进制 十六进制 缩写/字符 十进制 十六进制 缩写/字符 32 20 (space)空格 80 50 P 33 21 ! 81 51 Q 34 22 " 82 52 R 35 23 # 83 53 S 36 24 $ 84 54 T 37 25 % 85 55 U 38 26 & 86 56 V 39 27 ' 87 57 W 40 28 ( 88 58 X 41 29 ) 89 59 Y 42 2A * 90 5A Z 43 2B + 91 5B [ 44 2C , 92 5C \ 45 2D - 93 5D ] 46 2E . 94 5E ^ 47 2F / 95 5F _ 48 30 0 96 60 ` 49 31 1 97 61 a 50 32 2 98 62 b 51 33 3 99 63 c 52 34 4 100 64 d 53 35 5 101 65 e 54 36 6 102 66 f 55 37 7 103 67 g 56 38 8 104 68 h 57 39 9 105 69 i 58 3A : 106 6A j 59 3B ; 107 6B k 60 3C < 108 6C l 61 3D = 109 6D m 62 3E > 110 6E n 63 3F ? 111 6F o 64 40 @ 112 70 p 65 41 A 113 71 q 66 42 B 114 72 r 67 43 C 115 73 s 68 44 D 116 74 t 69 45 E 117 75 u 70 46 F 118 76 v 71 47 G 119 77 w 72 48 H 120 78 x 73 49 I 121 79 y 74 4A J 122 7A z 75 4B K 123 7B { 76 4C L 124 7C | 77 4D M 125 7D } 78 4E N 126 7E ~ 79 4F O 127 7F DEL (delete) 删除 第三部分(128~255)
ASCII扩展字符集,方便其他国家进行改进,至此基本存储单位Byte(char)能表示的编号都被用完了。
中文编码
以中文编码直接对方块字进行编码,一个汉字使用一个号码。由于汉字非常多,常用字就有6000多个,如果像ASCII编码表那样只使用1个字节最多只能表示256个汉字,所以我们使用2个字节来编码。
GB2312标准
我国首先定义的是GB2312标准。它把ASCII码表127号之后的扩展字符集直接取消掉,并规定小于127的编码按原来ASCII标准解释字符。当2个大于127的字符连在一起时,就表示1个汉字,第1个字节使用 (0xA1-0xFE) 编码,第2个字节使用(0xA1-0xFE)编码,这样的编码组合起来可以表示了7000多个符号,其中包含6763个汉字。在这些编码里,我们还把数学符号、罗马字母、日文假名等都编进表中,就连原来在ASCII里原本就有的数字、标点以及字母也重新编了2个字节长的编码,这就是平时在输入法里可切换的“全角”字符,而标准的ASCII码表中127号以下的就被称为“半角”字符。
如何与ASCII码兼容?
第1字节 第2字节 表示的字符 说明 0x68 0x69 (hi) 两个字节的值都小于127(0x7F),使用ASCII解码 0xB0 0xA1 (啊) 两个字节的值都大于127(0x7F),使用GB2312解码 区位码
在GB2312编码的实际使用中,有时会用到区位码的概念。GB2312编码对所收录字符进行了“分区”处理,共94个区,每区含有94个位,共8836个码位。而区位码实际是GB2312编码的内部形式,它规定对收录的每个字符采用两个字节表示,第一个字节为“高字节”,对应94个区;第二个字节为“低字节”,对应94个位。所以它的区位码范围是:0101-9494。为兼容ASCII码,区号和位号分别加上0xA0偏移就得到GB2312编码。在区位码上加上0xA0偏移,可求得GB2312编码范围:0xA1A1-0xFEFE,其中汉字的编码范围为0xB0A1-0xF7FE,第一字节0xB0-0xF7(对应区号:16-87),第二个字节0xA1-0xFE(对应位号:01-94)。
在keil5中可以改变编码的形式:
GBK编码
GB2312并没有包含很多生僻字,所以在GB2312的基础上又增加了14240个新汉字(包括Big5中的所有汉字)和符号。不再要求第2个字节的编码值必须大于127,只要第1个字节大于127就表示这是一个汉字的开始,这样就做到兼容ASCII和GB2312标准了。总体编码范围为8140-FEFE。
第1字节 第2字节 第3字节 表示的字符 说明 0x68(<7F) 0xB0(>7F) 0xA1(>7F) (h啊) 第1个字节小于127,使用ASCII解码,每2个字节大于127,直接使用GBK解码,兼容GB2312 0xB0(>7F) 0xA1(>7F) 0x68(<7F) (啊h) 第1个字节大于127,直接使用GBK码解释,第3个字节小于127,使用ASCII解码 0xB0(>7F) 0x56(<7F) 0x68(<7F) (癡h) 第1个字节大于127,第2个字节虽然小于127,直接使用GBK解码,第3个字节小于127,使用ASCII解码 GB18030
GB18030的编码使用4个字节,它利用前面标准中的第2个字节未使用的“0x30-0x39”编码表示扩充四字节的后缀,兼容GBK、GB2312及ASCII标准。
GB18030-2000主要在GBK基础上增加了“CJK(中日韩)统一汉字扩充A”的汉字。加上前面GBK的内容,GB18030-2000一共规定了27533个汉字(包括部首、部件等)的编码,还有一些常用非汉字符号。
GB18030-2005的主要特点是在GB18030-2000基础上增加了“CJK(中日韩)统一汉字扩充B”的汉字。增加了42711个汉字和多种我国少数民族文字的编码(如藏、蒙古、傣、彝、朝鲜、维吾尔文等)。加上前面GB18030-2000的内容,一共收录了70244个汉字。
各个标准比对:
GB2312、GBK及GB18030是汉字的国家标准编码,新版向下兼容旧版,各个标准简要说明见下表,目前比较流行的是GBK编码,因为每个汉字只占用2个字节,而且它编码的字符已经能满足大部分的需求,但国家要求一些产品必须支持GB18030标准。
想要更深刻的了解访问:导航菜单 - 千千秀字
Unicode
关于Unicode:Unicode – The World Standard for Text and Emoji
由于各个国家或地区都根据使用自己的文字系统制定标准,同一个编码在不同的标准里表示不一样的字符,各个标准互不兼容,而又没有一个标准能够囊括所有的字符,即无法用一个标准表达所有字符。国际标准化组织(ISO)为解决这一问题,它舍弃了地区性的方案,重新给全球上所有文化使用的字母和符号进行编号,对每个字符指定一个唯一的编号(ASCII中原有的字符编号不变),这些字符的号码从0x000000到0x10FFFF,该编号集被称为Universal Multiple-Octet Coded Character Set,简称UCS,也被称为Unicode。最新版的Unicode标准还包含了表情符号(聊天软件中的部分emoji表情)。
Unicode字符集只是对字符进行编号,但具体怎么对每个字符进行编码,Unicode并没指定,因此也衍生出了如下几种unicode编码方案(Unicode Transformation Format)。
UTF-32
编码时,它直接对Unicode字符集里的每个字符都用4字节来表示,转换方式很简单,直接将字符对应的编号数字转换为4字节的二进制数。由于UTF-32把每个字符都用要4字节来存储,因此UTF-32不兼容ASCII编码,也就是说ASCII编码的文件用UTF-32标准来打开会成为乱码。
缺点是浪费存储空间,大量常用字符的编号只需要2个字节就能表示。其次,在存储的时候需要指定字节顺序,是高位字节存储在前(大端格式),还是低位字节存储在前(小端格式)。
字符 GBK编码 Unicode编号 UTF-32编码 A 0x41 0x0000 0041 大端格式0x0000 0041 啊 0xB0A1 0x0000 554A 大端格式0x0000 554A UTF-16
针对UTF-32的缺点,人们改进出了UTF-16的编码方式,它采用2字节或4字节的变长编码方式(UTF-32定长为4字节)。对Unicode字符编号在0到65535的统一用2个字节来表示,将每个字符的编号转换为2字节的二进制数,即从0x0000到0xFFFF。
由于Unicode字符集在0xD800-0xDBFF这个区间是没有表示任何字符的,所以UTF-16就利用这段空间,对Unicode中编号超出0xFFFF的字符,利用它们的编号做某种运算与该空间建立映射关系,从而利用该空间表示4字节扩展。
UTF-16解码时,按两个字节去读取,如果这两个字节不在0xD800到0xDFFF范围内,那就是双字节编码的字符,以双字节进行解析,找到对应编号的字符。如果这两个字节在0xD800到 0xDFFF之间,那它就是四字节编码的字符,以四字节进行解析,找到对应编号的字符。
UTF-16编码的优点是相对UTF-32节约了存储空间,缺点是仍不兼容ASCII码,仍有大小端格式问题。