学习目标:
- 学习字、字节、位、字长
- 编码方式(ASCII码、扩展ASCII码、Unicode符号集、UTF-8、GBK/GB2312/GB18030)
- 串口通讯
提示:这里可以添加学习目标
主要内容:
1. 字、字节、位
1.1 位(bit)
英文bit,英文”比特“,表示二进制位,是计算机内部存储的最小单元。一个二进制位只可以表示0和1两种状态(21);两个二进制位可以表示00、01、10、11四种(22)状态。
2.2 字节(byte)
字节来自英文Byte,音译为“拜特”,习惯上用大写的“B”表示。
字节是计算机数据处理的基本单位。计算机中以字节为单位存储和处理信息,一个字节由八个二进制位构成(1byye = 8 bit)。八位二进制数的最小值00000000,最大的值为11111111;通常1个字节可以存入一个ASCII码(ASCII码详情),2个字节可以存放一个汉字国标码。
2.3 字
计算机进行数据处理时,一次存取、加工和传送的数据长度称为字(word)。一个字通常由一个或多个(一般是字节的整数位)字节构成。
在计算机的运算器、控制器中,通常都是以字为单位进行传送的。字出现在不问的地址其含义是不相同。例如,送往控制器去的字是指令,而送往运算器去的字就是一个数。
在计算机中作为一个整体被存取、传送、处理的二进制数字符串叫做一个字或单元,每个字中二进制位数的长度,称为字长。一个字由若干个字节组成,不同的计算机系统的字长是不同的,常见的有8位、16位、32位、64位等,字长越长,计算机一次处理的信息位就越多,精度就越高,字长是计算机性能的一个重要指标。目前主流微机都是32位机。
注意字与字长的区别,字是单位,而字长是指标,指标需要用单位去衡量。正象生活中重量与公斤的关系,公斤是单位,重量是指标,重量需要用公斤加以衡量。
2.4 字长
计算机的每个字所包含的位数称为字长。根据计算机的不同,字长有固定的和可变的两种。固定字长,即字长度不论什么情况都是固定不变的;可变字长,则在一定范围内,其长度是可变的。
计算的字长是指它一次可处理的二进创数字的数目。计算机处理数据的速率,自然和它一次能加工的位数以及进行运算的快慢有关。如果一台计算机的字长是另一台计算机的两倍,即使两台计算机的速度相同,在相同的时间内,前者能做的工作是后者的两倍。
一般地,大型计算机的字长为32―64位,小型计算机为12―32位,而微型计算机为4一16位。字长是衡量计算机性能的一个重要因素。
2. 编码方式(ASCII码、扩展ASCII码、Unicode符号集、UTF-8、GBK/GB2312/GB18030)
2.1 ASCII码
这是美国在19世纪60年代的时候为了建立英文字符和二进制的关系时制定的编码规范,它能表示128个字符,其中包括英文字符、阿拉伯数字、西文字符以及32个控制字符。它用一个字节来表示具体的字符,但它只用后7位来表示字符(2^7=128),最前面的一位统一规定为0。
2.2 扩展的ASCII码
原本的ASCII码对于英文语言的国家是够用了,但是欧洲国家的一些语言会有拼音,这时7个字节就不够用了。因此一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。比如,法语中的é的编码为130(二进制10000010)。这样一来,这些欧洲国家使 用的编码体系,可以表示最多256个符号。但这时问题也出现了:不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。比如,130在法语编码 中代表了é,在希伯来语编码中却代表了字母Gimel (ג),在俄语编码中又会代表另一个符号。但是不管怎样,所有这些编码方式中,0—127表示的符号是一样的,不一样的只是128—255的这一段。这个问题就直接促使了Unicode编码的产生。
2.3 Unicode符号集
正如上一节所说,世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。而Unicode就是这样一种编码:它包含了世界上所有的符号,并且每一个符号都是独一无二的。比如,U+0639表示阿拉伯字母Ain,U+0041表示英语的大写字母A,U+4E25表示汉字“严”。具体的符号对应表,可以查询unicode.org,或者专门的汉字对应表 。很多人都说Unicode编码,但其实Unicode是一个符号集(世界上所有符号的符号集),而不是一种新的编码方式。
但是正因为Unicode包含了所有的字符,而有些国家的字符用一个字节便可以表示,而有些国家的字符要用多个字节才能表示出来。即产生了两个问题:第一,如果有两个字节的数据,那计算机怎么知道这两个字节是表示一个汉字呢?还是表示两个英文字母呢?第二,因为不同字符需要的存储长度不一样,那么如果Unicode规定用2个字节存储字符,那么英文字符存储时前面1个字节都是0,这就大大浪费了存储空间。
上面两个问题造成的结果是:1)出现了unicode的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示unicode。2)unicode在很长一段时间内无法推广,直到互联网的出现。
2.4 UTF-8
互联网的普及,强烈要求出现一种统一的编码方式。UTF-8就是在互联网上使用最广的一种unicode的实现方式。其他实现方式还包括UTF-16和UTF-32,不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。
UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8的编码规则很简单,只有两条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
2.5 GBK/GB2312/GB18030
GBK和GB2312都是针对简体字的编码,只是GB2312只支持六千多个汉字的编码,而GBK支持1万多个汉字编码。而GB18030是用于繁体字的编码。汉字存储时都使用两个字节来储存。
详细请参考(字符编码)
3. 串口通讯(RS232)
3.1 RS232接口
3.2 针脚定义
| 编号| | 名称| 缩写|
- 1 Data Carrier Detect /数据载波监测 DCD
- 2 Received Data /接收数据 RxD
- 3 Transmitted Data/发送数据 TxD
- 4 Data Terminal Ready/数据终端就绪 DTR
- 5 Ground/接地 GND
- 6 Data Set Ready/数据集就绪 DSR
- 7 Request To Send/请求发送 RTS
- 8 Clear To Send/允许发送 CTS
- 9 Ring Indicator/振铃提示 RI
3.2 RS232电气信号
-
RS232接收-发送端的电信号是相对于公共地线(GND)的电压信号。当电压差值在+3V ~ +
15V之间表示逻辑“0”,当电压差值在-3V ~ -15V之间表示逻辑“1”,电压差值在-3V ~
+3V之间没有定义。3V是最小的可检测电压信号,实际使用时期望电压差的绝对值在5V ~ 15V之间,即:发送数据时,发送端驱动器输出正电压信号+5V ~ +15V,表示逻辑“0”;负电压信号-5V ~
-15V表示逻辑1。接收数据时,只要是检测到大于3V的电信号,即将其视为有效信号。 数据传输涉及的第一个概念是波特率。我们知道串行通信的传输是一位接着一位的,其传输单位为:位(bit)。因此,波特率的定义就是在单位时间内传输的位的个数。国际公用的单位时间为秒(s),因此波特率的单位为:bit/s(b/s),也写作bps(bitper second)。 -
波特率有一定的选择范围(并非任意值),常见的波特率有:9600,38400,56000,115200等。还有很多其它的值,通信双方约定好相同的波特率即可。
RS232是一种点对点的通信,其数据帧由起始位、数据位、校验位、停止位四部分组成。
- 起始位:长度1,数据值等于逻辑0,表示开始发送数据;
- 数据位:长度8或7,表示实际发送的数据;
- 校验位:长度0(无校验)或1(奇校验或偶校验);
- 停止位:长度1、1.5或者2,数据值等于逻辑1,表示数据帧发送结束;
- 假设某RS232通信设置数据位=7,奇校验,停止位=2,则帧和逻辑值如下图所示:
串口通讯中串口发送的内容智能是二进制即字节,所以我们在使用中需要将字符进行编码如”utf-8“。
import serial
try:
#端口,GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等
portx="COM1"
#波特率,标准值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
bps=9600
#超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)
timex=5
# 打开串口,并得到串口对象
ser=serial.Serial(portx,bps,timeout=timex)
# 写数据
data = "string" #字符类型
result=ser.write('data'.encode("utf-8"))
print("写总字节数:",result)
ser.close()#关闭串口
except Exception as e:
print("---异常---:",e)