105
1 微微微微微8.1 微微微微微微微微微 微微微微微微微微微微微微 微微 微微微 微微微微 一一, 1 微微微 微微 微微微微微 微微微微微 微微 微微微微微微 微微微微微微微微 ,一 一。 微微微微微微微微微微微微微微微微微微微微微微微微微微微微微微微微 微微微微微微微微 微微微微微微微微微微微微微微微微微微微 微微微微微微微微 微微微微微微微微微微微微微微微微微微微微微微微微微微8.1.1 微微微微 微 8 微 微微微微

8.1 串行通信的基本概念

  • Upload
    miriam

  • View
    147

  • Download
    2

Embed Size (px)

DESCRIPTION

第 8 章 串行接口. 8.1 串行通信的基本概念. 8.1.1 串行通信. 串行通信是将数据的各个位一位一位地,通过单条 1 位宽的传输线按顺序分时传送,即通信双方一次传输一个二进制位。串行通信与并行通信是两种基本的数据通信方式。. 发送方在发送前要将并行数据转成串行数据,接收方接收后要完成串行数据到并行数据的转换。. 与并行通信相比,串行通信的优势. 传输距离长,可达到数千公里. 长距离内串行数据传送速率会比并行数据传送速率快,串行通信的通信时钟频率较并行通信容易提高。. 抗干扰能力强,串行通信信号间的互相干扰完全可以忽略。. 费用低。. T. R. - PowerPoint PPT Presentation

Citation preview

Page 1: 8.1  串行通信的基本概念

1

微计算机系统

8.1 串行通信的基本概念

串行通信是将数据的各个位一位一位地,通过单条 1 位宽的传输线按顺序分时传送,即通信双方一次传输一个二进制位。串行通信与并行通信是两种基本的数据通信方式。 发送方在发送前要将并行数据转成串行数据发送方在发送前要将并行数据转成串行数据,接收方接收后要完成串行数据到并行数据的,接收方接收后要完成串行数据到并行数据的转换。转换。

8.1.1 串行通信

第 8 章 串行接口

Page 2: 8.1  串行通信的基本概念

2

微计算机系统

与并行通信相比,串行通信的优势

• 传输距离长,可达到数千公里传输距离长,可达到数千公里

• 长距离内串行数据传送速率会比并行数据传长距离内串行数据传送速率会比并行数据传送速率快,串行通信的通信时钟频率较并行送速率快,串行通信的通信时钟频率较并行通信容易提高。通信容易提高。

• 抗干扰能力强,串行通信信号间的互相干扰抗干扰能力强,串行通信信号间的互相干扰完全可以忽略。 完全可以忽略。

• 费用低。 费用低。

Page 3: 8.1  串行通信的基本概念

3

微计算机系统

8.1.2 串行通信方式

• 单工方式T R

• 半双工方式 T

RR

T

• 全双工方式 T

TR

R

Page 4: 8.1  串行通信的基本概念

4

微计算机系统8.1.3 波特率与收 / 发时钟

波特率波特率:单位时间内传送的二进制数据的位数,以位 / 秒( b/sb/s )表示,也称为数据位率。它是衡量串行它是衡量串行通信速率的重要指标通信速率的重要指标。。

收收 // 发时钟发时钟直接决定了通信线路上数据传输的速率,对于收 / 发双方之间数据传输的同步有十分重要的作用。

一般在发送端是由发送时钟的下降沿下降沿使送入移位寄存器的数据串行移位输出。而接收端则是在接收时钟的上升沿上升沿作用下将传输线上的数据逐位打入移位寄存器。

Page 5: 8.1  串行通信的基本概念

5

微计算机系统

为了提高串行通信的抗干扰能力,往往用多个时钟调制一个二进制数据,调制一个二进制数据的收 / 发时钟个数称为波特率系数波特率系数 nn。

收 / 发时钟频率与波特率之间的关系: 收收 // 发时钟频率发时钟频率 ==nn×× 波特率波特率一般 n取 1, 16, 32 和 64 等。对于异步通信,常采用 n=16 ;对于同步通信,则必须取 n =1 。

Page 6: 8.1  串行通信的基本概念

6

微计算机系统8.1.4 信号调制解调 原因:原因:如果数字信号直接在公用电话网的传输线上传送,高次谐波的衰减会很厉害,从而使信号到了接收端后将发生严重畸变和失真。

解决:解决:发送方使用调制器调制器( Modulator ),把要传送的数字信号数字信号调制转换为适合在线路上传输的音频音频模拟信号模拟信号;接收方则使用解调器解调器( Demodulator )从线路上测出这个模拟信号,并还原成数字信号。

Page 7: 8.1  串行通信的基本概念

7

微计算机系统调制方法:调制方法:按照调制技术的不同分为调频( FM )、调幅( AM )和调相( PM )三种,根据传输数字信号的变化规律去调整载波的频率、幅度或相位

Page 8: 8.1  串行通信的基本概念

8

微计算机系统8.1.5 信道复用时分多路复用时分多路复用 TDM(Time Division Multiplexing) ,就是将一条物理传输线路按时间分成若干时间片轮换地为多个信号所占用,每个时间片由复用的一个信号占用。

频分多路复用频分多路复用 FDM(Frequency Division Multiplexing) 就是利用频率调制原理,将要同时传送的多个信号进行频谱搬移,使它们互不重叠地占据信道频带的不同频率段,然后经发送器从同一信道上同时或不同时地发送出去。 计算机串行数据通信及其接口中使用时分多路复用计算机串行数据通信及其接口中使用时分多路复用系统。 系统。

Page 9: 8.1  串行通信的基本概念

9

微计算机系统8.1.6 串行通信基本方式

异步串行通信异步串行通信 在通信的数据流中,字符间异步,字符内部各位间同步。异步通信方式的“异步”主要体异步通信方式的“异步”主要体现在字符与字符之间通信没有严格的定时要求现在字符与字符之间通信没有严格的定时要求。然而,一旦传送开始,收 / 发双方则以预先约定的传输速率,在时钟的作用下,传送这个字符中的每一位。

Page 10: 8.1  串行通信的基本概念

10

微计算机系统

同步串行通信同步串行通信 数据流中的字符与字符之间和字符内部的位与位之间都同步。同步串行通信是以数据块(字符块)为信息单位传送,而每帧信息包括成百上千个字符,因此传送一旦开始,要求每帧传送一旦开始,要求每帧信息内部的每一位都要同步。信息内部的每一位都要同步。

Page 11: 8.1  串行通信的基本概念

11

微计算机系统8.2 异步串行通信协议

Page 12: 8.1  串行通信的基本概念

12

微计算机系统

比如 ASCII 字符 ‘ A’, 二进制是 0100 0001(8位 ) ,它们在起始位和 2 位停止位之间传送,并使用了 1 位奇校验位。

OutOut

0 1 0 0 0 0 0 1 0 0 1 1

先出先出 后出后出D7D7D0D0

Page 13: 8.1  串行通信的基本概念

13

微计算机系统为了确保异步串行通信传输正确:为了确保异步串行通信传输正确:11 )采用相反极性的起始位和停止位)采用相反极性的起始位和停止位 // 空闲位提供准空闲位提供准确的时间基准确的时间基准 22 )接收器在每位的中心采样,以获得最大的收)接收器在每位的中心采样,以获得最大的收 // 发发时钟频率偏差容限时钟频率偏差容限 33 )接收器采用比传送波特率更高频率的时钟来控制)接收器采用比传送波特率更高频率的时钟来控制采样时间,以提高采样的分辨能力和抗干扰能力。采样时间,以提高采样的分辨能力和抗干扰能力。

Page 14: 8.1  串行通信的基本概念

14

微计算机系统例题: 异步传输 7 位 ASCII 码,如果需要数据传输速率为 240 字符 / 秒,使用 1 位奇偶校验位和 1 位停止位,则:11 )波特率应该是多少?)波特率应该是多少?22 )有效数据位传输位是多少?)有效数据位传输位是多少?33 )传输效率是多少?)传输效率是多少?答:11 )波特率是)波特率是 (7(7 位数据位位数据位 +1+1 位起始位位起始位 +1+1 位校验位位校验位 +1+1 位停止位位停止位 )×)×240240 =2400b/s=2400b/s22 )有效数据位传输位是 :)有效数据位传输位是 : 7×240=1680b/s7×240=1680b/s33 )传输效率是:)传输效率是: 1680/2400=70%1680/2400=70%

Page 15: 8.1  串行通信的基本概念

15

微计算机系统8.3 串行接口 RS-232C 标准8.3.1 串行通信系统

数据终端设备数据终端设备 DTEDTE—— 数据源和目的地

数据通信设备数据通信设备 DCEDCE—— 使数据符合线路要求

Page 16: 8.1  串行通信的基本概念

16

微计算机系统

引脚 代号 其他表示法 信号名 方向1 AA( 101

)PG 保护地 设备地

2 BA( 103)

TxD, SD 发送数据 DTE→DCE

3 BB( 104)

RxD 接收数据 DCE→DTE

4 CA( 105)

RTS, RS 请求发送 DTE→DCE

5 CB( 106)

CTS, CS 允许 /清除发送

DCE→DTE

6 CC( 108)

DSR,MR DCE就绪 DCE→DTE

7 AB( 102)

SG 信号地 信号公共地

8 CF( 109)

RLSD, DCD

接收线路信号检测 DCE→DTE

20 CD( 108.2)

DTR DTE就绪 DTE→DCE

22 CE( 125)

RI 振铃指示 DCE→DTE

8.3.2 常用的 RS-232C 信号线

Page 17: 8.1  串行通信的基本概念

17

微计算机系统8.3.3 常用的 RS-232C 连接

1. 使用 MODEM

Page 18: 8.1  串行通信的基本概念

18

微计算机系统2. 不使用 MODEM

Page 19: 8.1  串行通信的基本概念

19

微计算机系统3. 简单连接

4. 最简单连接( 3 线连接)

Page 20: 8.1  串行通信的基本概念

20

微计算机系统8.3.4 电气特性

1. 应保证电平在 ±±(5~15)V 之间

对于数据线:对于数据线:逻辑“ 1” (MARK)= -3V~ - 15V,

逻辑“ 0” (SPACE) = +3V~+15V对于控制信号:对于控制信号:接通状态( ON )即信号有效

的电平 = +3V~15V断开状态( OUT )即信号无效

的电平 = - 3 ~ Ⅴ - 15V 。

Page 21: 8.1  串行通信的基本概念

21

微计算机系统

2. 必须进行电平转换 RS-232CRS-232C 接口采用的是负逻辑,其逻辑电平接口采用的是负逻辑,其逻辑电平与与 TTLTTL 电平不一样,不能兼容。因此,为了实电平不一样,不能兼容。因此,为了实现与现与 TTLTTL 电路的连接,必须进行电平转换。电路的连接,必须进行电平转换。 目前可以使用新型电平转换芯片目前可以使用新型电平转换芯片 MAX232MAX232 和和MAX232AMAX232A (高速)双组(高速)双组 RS-232CRS-232C 发送发送 // 接收器接收器,实现,实现 TTLTTL 电平与电平与 RS-232CRS-232C 电平双向转换。电平双向转换。

Page 22: 8.1  串行通信的基本概念

22

微计算机系统

3. 必须抗共模噪声干扰

RS-232C 由于在发送器与接收器之间有公共信号地,不可能使用双端信号,因此共模噪声很容易引入信号系统中,且噪声幅度可高达好几伏,这是迫使 RS-232C 使用较高传输电压的主要原因。另一个原因是为了补偿传输线上的信号衰减和沿线附加电平的影响。

Page 23: 8.1  串行通信的基本概念

23

微计算机系统4. 处理好最大传输速率和最大传输线长度的关系

一般应用情况下, RS-232C 的最高传输速率为20Kb/s ,最大传输线长度为 30m 。

Page 24: 8.1  串行通信的基本概念

24

微计算机系统8.3.5 机械特性

1. 连接器

Page 25: 8.1  串行通信的基本概念

25

微计算机系统

Page 26: 8.1  串行通信的基本概念

26

微计算机系统

在通信速率低于 20Kb/s 时, RS-232C 所能直接连接的最大物理距离为 15m ( 50ft )。

2. 电缆长度

使用特制的低电容电缆也能有效地提高电缆长度,可使用特制的低电容电缆也能有效地提高电缆长度,可以达到以达到 150m150m (( 500ft500ft )甚至更多。)甚至更多。

ft NpF/ft2500pFL

RS-232CRS-232C 规定,若不使用规定,若不使用 MODEMMODEM ,则码元的畸变,则码元的畸变要小于要小于 4%4% ,驱动器的负载电容应该小于,驱动器的负载电容应该小于 2500pF2500pF ,则,则单位(单位( 1ft1ft )长度的电容值为)长度的电容值为 NpFNpF 的电缆的长度应该是的电缆的长度应该是::

Page 27: 8.1  串行通信的基本概念

27

微计算机系统8.3.6 RS-232 的局限• RS-232CRS-232C 采用单端驱动、单端接收的单端双极性电路采用单端驱动、单端接收的单端双极性电路

标准。仅用一条线路传输一种信号,根据该信号线上标准。仅用一条线路传输一种信号,根据该信号线上电平相对于公共的信号地电平的大小来决定逻辑的“电平相对于公共的信号地电平的大小来决定逻辑的“1”1” 和“和“ 0” 0” 。。

• 对于多条信号线来讲,它们的地线是公共的,这种共对于多条信号线来讲,它们的地线是公共的,这种共地传输方式,抗干扰能力很差。地传输方式,抗干扰能力很差。

• 尽管采用电平转换器来提高信号传输电平,但在较长尽管采用电平转换器来提高信号传输电平,但在较长距离时,由于电压损失,仍不可避免错误。距离时,由于电压损失,仍不可避免错误。

• 当信号穿过电磁干扰环境时,也可能因附加的干扰信当信号穿过电磁干扰环境时,也可能因附加的干扰信号电平使发送的“号电平使发送的“ 00”” 变为“变为“ 11”” 或“或“ 11”” 变为“变为“ 00”” 。故其信号波特率不能过高,仅限在。故其信号波特率不能过高,仅限在 20Kb/s20Kb/s 以下以下,且距离不大于,且距离不大于 15m15m 。。

Page 28: 8.1  串行通信的基本概念

28

微计算机系统8.3.7 RS-485 总线1. RS-485 接口标准是一种平衡传输方式平衡传输方式的串行接口标

准,这个标准的电气特性对逻辑电平的定义是根据两对逻辑电平的定义是根据两条传输线之间的电位差值来决定的条传输线之间的电位差值来决定的,当 AA' 线的电平比 BB' 线的电平高 200mⅤ 时表示逻辑“ 1” ,当AA' 线的电平比 BB' 线的电平低 200mV 时表示逻辑“ 0” 。

Page 29: 8.1  串行通信的基本概念

29

微计算机系统2. RS-485 标准允许在电路中可有 3232 个发送器个发送器,和 3232 个个

接收器接收器。允许一个发送器驱动多个负载设备一个发送器驱动多个负载设备,负载设备可以是驱动发送器、接收器或收发器组合单元

3. RS-485 的共线电路结构是在一对平衡传输线的两端都一对平衡传输线的两端都配置终端电阻配置终端电阻,其发送器、接收器和组合收发器可挂在平衡传输线上的任何位置,实现在数据传输中多个驱动器和接收器共用同一传输线的多点应用。

4. 由于 RS-485 标准采用差动发送 / 接收,因此共模抑制共模抑制比高、抗干扰能力强比高、抗干扰能力强;

5.5. 传输速率高传输速率高,最大传输速率可达 10Mb/s (传送 15m),传输信号的摆幅小传输信号的摆幅小( 200mV );

6.6. 传送距离远传送距离远,采用双绞线,在不用 MODEM 的情况下,当 100Kb/s 的传输速率时,可传送的距离为 1.2km ,

Page 30: 8.1  串行通信的基本概念

30

微计算机系统

8.4 异步通信适配器 PC 微机异步通信适配器是微机与微机、微机与 MODEM 及微机与外设之间进行异步通信的接口。其核心是 UART 。

常见的 UART 主要有 INS8250INS8250 、 PC16450PC16450和 PC16550PC16550 。此外,还有带更大缓冲的 UART ,称为 PC16650PC16650 和 PC16750PC16750 。

Page 31: 8.1  串行通信的基本概念

31

微计算机系统8.4.1 INS8250 外部引脚

Page 32: 8.1  串行通信的基本概念

32

微计算机系统1. 并行数据 I/O 及其控制线

• D7~D0 8 位双向三态数据线。• CS0, CS1 和 CS2 片选线。• ADS 地址选通线 ( 锁存片选和内部寄存器选择锁存片选和内部寄存器选择 )

• DISTR 和 DISTR 数据输入选通。 ( 读寄存器允许读寄存器允许 ) • DOSTR 和 DOSTR 数据输出选通。 ( 写寄存器允许写寄存器允许 ) • A0, A1 和 A2 内部寄存器选择。 • CSOUT 片选输出。(为高表示该片被选中为高表示该片被选中)) • DDIS 驱动器禁止。 ( 禁止处理器和禁止处理器和 82508250 在在

数据线上的收发器动作数据线上的收发器动作 )

Page 33: 8.1  串行通信的基本概念

33

微计算机系统2. 串行数据 I/O 线

• SOUT 串行数据输出。 • SIN 串行数据输入。 • XTAL1 外部时钟输入端。 • XTAL2 基准时钟信号输出端。 • BAUDOUT 工作时钟输出。

FF 工作时钟工作时钟 ==FF 基准时钟基准时钟 ÷÷ 除数寄存器除数寄存器 == 传送波特率传送波特率 ×16×16

• RCLK 接收时钟输入。可和 BAUDOUT 相接

Page 34: 8.1  串行通信的基本概念

34

微计算机系统3. 和 MODEM 的握手信号线

• RTS 请求发送,输出线。

• DSR 数据设备就绪,输入线 • DTR 数据终端就绪,输出线。 • RI 振铃指示,输入线。 • RLSD 接收线路信号检测,输入线。

• CTS 清除发送,输入线。

Page 35: 8.1  串行通信的基本概念

35

微计算机系统

4. 中断请求,复位输入及其他信号线

• INTPRT 中断请求输出。 • MR 主复位输入。

• OUT1 和 OUT2 由用户指定的输出端。 MODEM 控制寄存器的第二、第三位决定。

Page 36: 8.1  串行通信的基本概念

36

微计算机系统8.4.2UART 内部结构

Page 37: 8.1  串行通信的基本概念

37

微计算机系统

DLAB A2A1A0 被访问的寄存器0 000 接收缓冲寄存器 ( 读 ) ,发送保持寄存器

( 写 )0 001 中断允许寄存器1 000 波特率除数寄存器 ( 低字节 ) 1 001 波特率除数寄存器 ( 高字节 )X 010 中断识别寄存器 ( 读 ) , FIFO 控制器 ( 写 ) X 011 线路控制寄存器 X 100 MODEM 控制寄存器X 101 线路状态寄存器X 110 MODEM 状态寄存器X 111 Scratch 寄存器

DLAB 是线路控制寄存器的 D7 位。

Page 38: 8.1  串行通信的基本概念

38

微计算机系统

1. 线路控制寄存器 LCR

D7 D6 D5 D4 D3 D2 D1 D0

WLS0WLS1PEN STBEPSSPSBDLAB

字符长度选择字符长度选择00——500——5 位位01——601——6 位位10——710——7 位位11——811——8 位位停止位选择停止位选择

0——10——1 位位1——1.51——1.5 位位 (D1D0=00(D1D0=00 )) 22 位位 (D1D0<>00)(D1D0<>00)

奇偶校奇偶校验允许验允许

奇偶校奇偶校验选择验选择

11——11—— 偶校验偶校验01——01—— 奇校验奇校验

附加奇偶标志附加奇偶标志位选择位选择0——0—— 不附加不附加1——1—— 附加附加 11位位

中止设置中止设置1—1— 中止中止0—0— 正常正常

除数寄存器除数寄存器访问允许访问允许0——0—— 禁止禁止1——1—— 允许允许

A2A1A0=011

Page 39: 8.1  串行通信的基本概念

39

微计算机系统

2. 线路状态寄存器 LSR

D7 D6 D5 D4 D3 D2 D1 D0

DROEFE PEBITHRETSRE

接收接收缓冲缓冲区满区满

接收接收重叠重叠错错

接收接收奇偶奇偶错错

接收接收格式格式错(错(无正无正确的确的停止停止位)位)

中止中止识别识别标志标志

发送发送保持保持器空器空

发送发送移位移位器空器空

FIFOFIFO 中中接收数据接收数据错误错误 ((1616550550))

A2A1A0=101

Page 40: 8.1  串行通信的基本概念

40

微计算机系统3. 发送保持寄存器 THR 接收缓冲寄存器 RBR

D7 D0

CPU 来的 8 位数据并行进 THR

THR低位到低位到高位串高位串行移位行移位到到 SOUSOUTT 引脚引脚输出输出

……D7 D0

接收移位寄存器发送移位寄存器

RBR低位到低位到高位从高位从 SSININ 引脚引脚串行移串行移位进来位进来

8 位数据并行进CPU

发送方 接收方

DLAB=0 , A2A1A0=000

Page 41: 8.1  串行通信的基本概念

41

微计算机系统4. 波特率除数锁存器

这是一个软件控制的分频器,输出的工作时钟频率为 16 倍的波特率。

除数寄存器值 除数寄存器值 = = 基准时钟频率基准时钟频率 ÷÷ (( 16×16× 波特波特率)率) INS8250INS8250 芯片输入的基准时钟频率为芯片输入的基准时钟频率为 1.8432MHz1.8432MHz ,若,若波特率为波特率为 4800b/s4800b/s ,则波特率除数为,则波特率除数为 0018H0018H ,, DLHDLH 中中应填应填 00H00H ,, DLLDLL 中应填中应填 18H 18H 。。

思考题: 使用 INS8250 异步传输 7 位 ASCII 码,如果需要数据传输速率为 240 字符 / 秒,使用 1 位奇偶校验位和 1 位停止位,波特率除数锁存器的值是多少?

注意:注意: PC16550PC16550 的基准时钟一般为的基准时钟一般为 18.432MHz18.432MHz 。。

DLAB=1, A2A1A0=001( 高高 ) 或 000( 低低 )

Page 42: 8.1  串行通信的基本概念

42

微计算机系统

5. 中断识别寄存器 IIR

D7 D6 D5 D4 D3 D2 D1 D0

IPID1ID20

未决未决中断中断指示指示0-0- 有有1-1- 无无

中断中断类型类型标识标识

超时中断超时中断0-0- 不超时不超时1-1- 超时超时

允许允许 6464 字节字节FIFO(FIFO(1675016750))0-0- 禁止禁止1-1- 允许允许

FIFOFIFO 使使用指示用指示((1655016550))01-01- 允许允许 FIFOFIFO 但不可但不可用用11-11- 允许允许 FIFOFIFO

A2A1A0=010 (读)

Page 43: 8.1  串行通信的基本概念

43

微计算机系统

ID2 ID1 中断类型 优先权1 1 接收出错 ( 重叠、奇偶错、格式错和

中止 )最高

1 0 接收缓冲器满 次高0 1 发送保持器空 低0 0 MODEM 状态 (CTS 、 DSR 、 RI

和 RLSD) 改变最低

Page 44: 8.1  串行通信的基本概念

44

微计算机系统

6. 中断允许寄存器 IER

D7 D6 D5 D4 D3 D2 D1 D0

I2EI1EI3E0

类型类型 22中断中断 ((接收缓接收缓冲器满冲器满 ))1-1- 允许允许0-0- 屏蔽屏蔽

类型类型 11中断中断 ((发送保发送保持器空持器空))1-1- 允许允许0-0- 屏蔽屏蔽

类型类型 33中断中断 ((接收出接收出错)错)1-1- 允许允许0-0- 屏蔽屏蔽

进入低进入低功耗模功耗模式式 ((1651655050))

进入睡进入睡眠模式眠模式((1675016750))

DLAB=0 , A2A1A0=001

I0E0

类型类型 00中断中断 ((MODMODEMEM 状状态改变态改变))1-1- 运运行行0-0- 屏屏蔽蔽

Page 45: 8.1  串行通信的基本概念

45

微计算机系统

7.MODEM 控制寄存器 MCR

A2A1A0=100

D7 D6 D5 D4 D3 D2 D1 D0

DTRRTSOUT10

数据数据终端终端就绪就绪

请求请求发送发送

辅助辅助输出输出11

自动流自动流量控制量控制((1675016750))

环路环路检测检测(( 内内部自部自循环循环))

OUT20

辅助辅助输出输出22 ,, PPCC 用用做中做中断断

LOOP

注意这里的注意这里的 OUTiOUTi 位极性和位极性和 OUTiOUTi 引脚相反。引脚相反。

Page 46: 8.1  串行通信的基本概念

46

微计算机系统

8.MODEM 状态寄存器 MSR

A2A1A0=110

D7 D6 D5 D4 D3 D2 D1 D0

CTSDSRTERIRLSD

CTSCTS位发位发生改生改变变

DSRDSR位发位发生改生改变变

收到收到“振“振铃指铃指示”示”后沿后沿(下(下降沿降沿))

收到“收到“数传机数传机就绪”就绪”

收到收到“清“清除发除发送”送”

RLSDRI

RLSRLSDD 位位发生发生改变改变

CTSDSR

收到收到“振“振铃指铃指示”示”

收到收到“接“接收线收线载波载波检测检测””

Page 47: 8.1  串行通信的基本概念

47

微计算机系统

9.FIFO 控制寄存器 (FCR)A2A1A0=010 (写) 1616550550 后才有后才有D7 D6 D5 D4 D3 D2 D1 D0

允许允许FIFFIFOO 缓缓冲器冲器工作工作

清除清除接收接收FIFFIFOO 缓缓冲器冲器

清除清除发送发送FIFFIFOO 缓缓冲器冲器

允许允许 6644 字节字节FIFOFIFO((1675016750))

保留保留 DMDMAA 方方式选式选择择

接收接收端中端中断触断触发器发器水平水平(LS(LSB)B)

接收接收端中端中断触断触发器发器水平水平(MS(MSB)B)

Page 48: 8.1  串行通信的基本概念

48

微计算机系统

触发器水平即是指示在中断产生之前,接收缓冲器应该装满多少个字节。

D7D6 触发器水平00 1 字节01 4 字节10 8 字节11 12 字节

Page 49: 8.1  串行通信的基本概念

49

微计算机系统

常用 UART 比较8250 16450 16550 16650 16750

FIFO - - 16 字节

32 字节

64 字节

超时检测 - -- √√ √√ √√

低功耗模式 - -- √√ √√ √√

睡眠模式 - -- -- -- √√

自动流量控制 - -- -- -- √√

临时寄存器 - √√ √√ √√ √√

Page 50: 8.1  串行通信的基本概念

50

微计算机系统

8.4.3 采用 UART 的异步通信适配器硬件逻辑

1.PC 机的串行口

串口号 COM1 COM2 COM3 COM4

基地址 3F8 2F8 3E8 2E8

中断号 IRQ4 IRQ3 IRQ4 IRQ3

Page 51: 8.1  串行通信的基本概念

51

微计算机系统2.PC 机的串行口电路

Page 52: 8.1  串行通信的基本概念

52

微计算机系统8.4.4 INS8250 初始化

1.通过写除数寄存器(端口 0 和端口 1 )设置波特率

2.通过写线路控制寄存器(端口 3 )设置通信数据格式。

3.通过写 MODEM 控制寄存器 MCR (端口 4)设置 MODEM 控制字。

4.通过写中断允许寄存器(端口 1 )设置中断允许控制字。

Page 53: 8.1  串行通信的基本概念

53

微计算机系统

mov dx,3fbh ;线路控制寄存器地址线路控制寄存器地址mov al,80hout dx,al ;使使 DLAB=1DLAB=1 ,以便下面写除,以便下面写除数数

;寄存器寄存器mov dx,3f8h ;低位除数寄存器低位除数寄存器mov al,0ch ; 96009600 波特率的除数低波特率的除数低 88 位位out dx,almov al,00inc dx ;高位除数寄存器高位除数寄存器out dx,al

Page 54: 8.1  串行通信的基本概念

54

微计算机系统

mov al, 00011011b ;偶校验、偶校验、 11 位停止位停止位位

;; 88 位数据位位数据位mov dx,3fbh ;线路控制寄存器地址线路控制寄存器地址out dx,almov al,03h ;mov dx,3fch ; MODEMMODEM控制寄存器地址控制寄存器地址out dx,almov al,0 ;禁止中断禁止中断mov dx,3f9h ;中断允许寄存器地址中断允许寄存器地址out dx,al

Page 55: 8.1  串行通信的基本概念

55

微计算机系统8.4.5 查询方式串行通信程序设计1. 查询方式发送 初始化 8250

读 LSR

D5=1?

发送一个字符

发完?

结束

Y

Y

N

N

Page 56: 8.1  串行通信的基本概念

56

微计算机系统2. 查询方式接收 初始化 8250

读 LSR

D0=1?

接收一个字符

收完?

结束

Y

Y

N

N

有错?N

Y

错误处理

Page 57: 8.1  串行通信的基本概念

57

微计算机系统

1. 通信中断初始化8.4.6 中断方式串行通信程序设计

• 修改中断向量,修改中断向量,按使用的端口 COM1 或 COM2,接管中断 0CH 或中断 0BH 。

• 确定确定 INS8250INS8250 操作方式,操作方式,设置中断允许寄存器相应位的允许或禁止,并允许中断操作(置 MCR的 D3=1 )。

• 确定起止式通信协议确定起止式通信协议,设置通信波特率及数据帧传输格式。

• 开放通信中断开放通信中断,对 8259A 中断控制器的屏蔽寄存器编程( OCW1 ),允许中断 IRQ4 或 IRQ3 。

Page 58: 8.1  串行通信的基本概念

58

微计算机系统2. 通信中断服务程序

•首先读取中断识别寄存器首先读取中断识别寄存器,判断中断源,然后转向对应的处理子程序。判断中断源,应该按照中断优先级别次序进行。

•当中断识别寄存器 D2D1=11 时,表明接收出错中接收出错中断,需要再读取线路状态寄存器断,需要再读取线路状态寄存器,分析错误原因,再进行错误处理。

•可能出现多个中断源同时引发中断。因此,每处理因此,每处理完一种中断源后,应继续读取中断识别寄存器,检测完一种中断源后,应继续读取中断识别寄存器,检测D0D0 是否为“是否为“ 0”0” ,,当 D0=0 时,表明还有未决中断,应该继续分析中断源并进行中断处理。

•从中断程序返回的条件是中断识别寄存器的从中断程序返回的条件是中断识别寄存器的 D0=1D0=1。

Page 59: 8.1  串行通信的基本概念

59

微计算机系统8.5 Win32 串口编程(自学)8.5.1 Win32 串口编程方法1.1. 以文件方式打开串口以文件方式打开串口

使用 Win32 API 中文件操作的有关函数来完成对串口的访问。

2.2. 使用现有的使用现有的 ActiveXActiveX 控件实现控件实现现在一般使用的是微软公司的 MSComm 控件,它是作为一个 OCX 来提供的。

3.3. 直接嵌入汇编法直接嵌入汇编法这种方法只能用在 Windows 98 和 Windows 95 操作系统下。在嵌入式汇编中,可直接对串口进行操作。

Page 60: 8.1  串行通信的基本概念

60

微计算机系统

( 1 )应用 CreateFile() 来打开串口HANDLE CreateFile(

LPCTSTR lpFileName, // // 文件名文件名 DWORD dwDesiredAccess, // // 存取模式存取模式 DWORD dwShareMode, // // 共享模式共享模式 LPS

ECURITY_ATTRIBUTES lpSecurityAttributes, // NULL// NULL DWORD dwCreationDisposition, // // 创建方法创建方法

DWORD dwFlagsAndAttributes, // // 文件属性文件属性和标志和标志 HANDLE hTemplateFile // // 临时文件临时文件句柄句柄 );

其中, lpFileName 指定要打开的串口逻辑名,用字符串表示,“ COM1” 表示串口 1 ,“ COM2” 表示串口 2 。 由于串口是硬件,所以 dwCreationDisposition 一般为 OPEN_EXISTING 。

8.5.2 以文件方式打开串口法

Page 61: 8.1  串行通信的基本概念

61

微计算机系统

( 2 )初始化串口BOOL SetupComm(

HANDLE hFile, // 通信设备句柄DWORD dwInQueue, // 输入缓冲区大小 DWORD dwOutQueue // 输出缓冲区大小

);

( 3 )关闭窗口BOOL CloseHandle(

HANDLE hObject // 需要关闭的设备句柄 );

Page 62: 8.1  串行通信的基本概念

62

微计算机系统

( 4 )串口配置BOOL GetCommState(

HANDLE hFile, // 通信设备句柄LPDCB lpDCB // 设备控制块

);

BOOL SetCommState( HANDLE hFile, // 通信设备句柄LPDCB lpDCB //设备控制块

);

Page 63: 8.1  串行通信的基本概念

63

微计算机系统

Page 64: 8.1  串行通信的基本概念

64

微计算机系统( 5 )串口属性BOOL GetCommProperties(

HANDLE hFile, // 通信设备句柄 LPCOMMPROP lpCommProp // 通信属性结构 );

Page 65: 8.1  串行通信的基本概念

65

微计算机系统( 6 )读串口操作BOOL ReadFile(

HANDLE hFile, // 设备句柄 LPVOID lpBuffer, // 数据缓冲 DWORD nNumberOfBytesToRead, // 读取的字节数 LPDWORD lpNumberOfBytesRead, // 实际读的字节

数 LPOVERLAPPED lpOverlapped // overlappe

d结构 ); ( 7 )写串口操作BOOL WriteFile(

HANDLE hFile, // 设备句柄 LPVOID lpBuffer, // 数据缓冲 DWORD nNumberOfBytesToWrite, // 写的字节数 LPDWORD lpNumberOfBytesWrite, // 实际写的字节

数 LPOVERLAPPED lpOverlapped // overlappe

d结构 );

Page 66: 8.1  串行通信的基本概念

66

微计算机系统( 8 )异步 I/O 操作异步(重叠) I/O操作是指应用程序可以在后台读或写数据,而在前台做其他事情。要异步操作,需要使用,这首先要 CreateFile() 函数的 dwFlagAndAttributes 参数中使用 FILE_FLAG_OVERLAPPED 标识,读写串口必须指定 OVERLAPPED结构:

typedef struct _OVERLAPPED { ULONG_PTR Internal; // 操作系统保留ULONG_PTR InternalHigh; // 操作系统保留 DWORD Offset; // 文件传输的初始位置DWORD OffsetHigh; // 文件传输的高位字HANDLE hEvent; // I/O操作完成后触发的事

件} OVERLAPPED;

Page 67: 8.1  串行通信的基本概念

67

微计算机系统

异步 I/O操作可以用 GetOverlappedResult() 函数来获得结果BOOL GetOverlappedResult(

HANDLE hFile, // 设备句柄 LPOVERLAPPED lpOverlapped, // overlapped

结构 LPDWORD lpNumberOfBytesTransferred, // 传送的字

节数 BOOL bWait // 指定函数是否等待挂起的异步操作

完成 );

异步 I/O 的时候, Windows 可以用 WaitForSingleObject() 函数来检查事件对象。DWORD WaitForSingleObject(

HANDLE hHandle, // 对象句柄 DWORD dwMilliseconds // 内部超时时间

);

Page 68: 8.1  串行通信的基本概念

68

微计算机系统( 9 )超时设置异步(重叠) I/O操作读写串口引入超时结构,在超时时间到的时候,如果读写还没结束,则读写会强行终止。异步时,强行终止的读写动作实际传输的字符数在 OVERLAPPED结构中返回。超时结构如下:typedef struct _COMMTIMEOUTS {

DWORD ReadIntervalTimeout; // 两字符间的最大时间间隔

DWORD ReadTotalTimeoutMultiplier; // 计算读操作总超时的超时系数

DWORD ReadTotalTimeoutConstant; // 计算读操作总超时的超时常数

DWORD WriteTotalTimeoutMultiplier; // 计算写操作总超时的超时系数

DWORD WriteTotalTimeoutConstant; // 计算写操作总超时的超时常数} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

Page 69: 8.1  串行通信的基本概念

69

微计算机系统

总超时计算公式是:总超时=超时系数 × 读或写字节数+超时常数BOOL SetCommTimeouts(

HANDLE hFile, // 通信设备句柄 LPCOMMTIMEOUTS lpCommTimeouts // 超时结构 );

BOOL GetCommTimeouts( HANDLE hFile, // 通信设备句

柄 LPCOMMTIMEOUTS lpCommTimeouts // 超时结构 );

Page 70: 8.1  串行通信的基本概念

70

微计算机系统

////1处 //// 以重叠方式接收指定字符,看函数是否读取成功 fReadStat=ReadFile(hCom,lpBlock,dwLength,&dwLength,&osRead); if(!fReadStat) { file:// 属重叠方式操作在后台进行的情况 ... if(GetLastError()==ERROR_IO_PENDING) {////2处 file:// 等待 1s, 若接收事件处于信号态,说明重叠方式操作完成,超时 ...////3处 if(WaitForSingleObject(osRead.hEvent,1000)==WAIT_TIMEOUT) dwLength=0; } else dwLength=0;// 异常情况 }

Page 71: 8.1  串行通信的基本概念

71

微计算机系统

( 10 )通信状态和通信错误如果串口发生奇偶错误等错误的时候, I/O操作会终止。如果程序要继续执行 I/O操作,就需要调用 ClearCommError() 函数,该函数清除错误条件,并确定串口的通信状态:BOOL ClearCommError(

HANDLE hFile, // 通信设备句柄 LPDWORD lpErrors, // 错误代码 LPCOMSTAT lpStat // communications结构

);

Page 72: 8.1  串行通信的基本概念

72

微计算机系统 错误代码

Page 73: 8.1  串行通信的基本概念

73

微计算机系统

typedef struct _COMSTAT { DWORD fCtsHold : 1; // 是否等待CTS 信号DWORD fDsrHold : 1; // 是否等待DSR 信号DWORD fRlsdHold : 1; // 是否等待RLSD 信号DWORD fXoffHold : 1; // 收到 XOFF 字符后发送是否等

待DWORD fXoffSent : 1; // 发送完 XOFF 字符后发送是否等

待DWORD fEof : 1; // EOF 字符送出DWORD fTxim : 1; // 字符是否正等待被发送DWORD fReserved : 25; // 系统保留DWORD cbInQue; // 串口接收的字符数DWORD cbOutQue; // 串口发送的字符数

} COMSTAT, *LPCOMSTAT;

Page 74: 8.1  串行通信的基本概念

74

微计算机系统( 11 )通信事件Windows 有以下的通信事件:

Page 75: 8.1  串行通信的基本概念

75

微计算机系统

应用程序可用 SetCommMask() 函数来建立事件掩模来监视指定通信资源上的事件。

BOOL SetCommMask( HANDLE hFile, // 通信设备句柄DWORD dwEvtMask // 事件掩模

);

Page 76: 8.1  串行通信的基本概念

76

微计算机系统

在用 SetCommMask() 指定了有用的事件后,应用程序就调用 WaitCommEvent() 函数来等带其中的一个事件发生。

BOOL WaitCommEvent( HANDLE hFile, // 设备句柄 LPDWORD lpEvtMask, // 事件类型 LPOVERLAPPED lpOverlapped, // overlapped

结构);

Page 77: 8.1  串行通信的基本概念

77

微计算机系统举例:⑴.在中 MainFrm.cpp 定义全局变量HANDLE      hCom; // 准备打开的串口的句柄HANDLE      hCommWatchThread ;// 辅助线程的全局函数⑵.打开串口,设置串口hCom =CreateFile( “COM2”, GENERIC_READ | GENERIC_WRITE, // 允许读写

0,            // 此项必须为 0    NULL,          // no security attrs    OPEN_EXISTING,      // 设置产生方式    FILE_FLAG_OVERLAPPED, // 使用异步通信    NULL );if(hCom==INVALID_HANDLE_VALUE){

dwError = GetLastError();…… // 处理错误

}

Page 78: 8.1  串行通信的基本概念

78

微计算机系统// 检测打开串口操作是否成功 ASSERT(hCom!=INVALID_HANDLE_VALUE); // 设置事件驱动的类型SetCommMask(hCom, EV_RXCHAR|EV_TXEMPTY ); // 设置输入、输出缓冲区的大小SetupComm( hCom, 1024,512) ; // 清干净输入、输出缓冲区PurgeComm( hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); // 定义超时结构,填写该结构,并设置超时COMMTIMEOUTS TimeOuts;TimeOuts.ReadIntervalTimeouts = 1000;TimeOuts.ReadTotalTimeMultiolier = 500;TimeOuts.ReadTotalTimeConstant = 5000;TimeOuts.WriteTotalTimeMultiolier = 500;TimeOuts.WriteTotalTimeConstant = 5000; SetCommTimerouts(hCom,&TimeOuts);

Page 79: 8.1  串行通信的基本概念

79

微计算机系统

DCB      dcb ; // 定义数据控制块结构GetCommState(hCom, &dcb ) ; // 读串口原来的参数设置dcb.BaudRate =9600; // 9600 的波特率dcb.ByteSize =8; // 8 位数据位dcb.Parity = NOPARITY; // 无校验位dcb.StopBits = ONESTOPBIT ; // 1 位停止位dcb.fBinary = TRUE ; // Win32 中此位一定要位 TRUEdcb.fParity = FALSE; // 不执行奇偶校验SetCommState(hCom, &dcb ) ; // 串口参数配置// 上述的 COMMTIMEOUTS 结构和 DCB 都很重要,实际工作中需要仔细选择参数。

Page 80: 8.1  串行通信的基本概念

80

微计算机系统⑶启动一个辅助线程,用于串口事件的处理。 Win32 提供了两种线程,辅助线程辅助线程和用户界面线程用户界面线程。区别在于:辅助线程没有窗口,所以它没有自己的消息循环。但是辅助线程很容易编程,通常也很有用。其次,我们使用辅助线程,主要用它来监视串口状态,主要用它来监视串口状态,看有无数据到达、通信有无错误看有无数据到达、通信有无错误;而主线程则可专心进行数据处理、提供友好的用户界面等重要的工作。

hCommWatchThread= CreateThread((LPSECURITY_ATTRIBUTES) NULL, // 安全属性

    0,// 初始化线程栈的大小,缺省为与主线程大小相同    (LPTHREAD_START_ROUTINE)CommWatchProc, // 线程的全局函数    GetSafeHwnd(), // 此处传入了主框架的句柄    0,

&dwThreadID );   ASSERT(hCommWatchThread!=NULL);

Page 81: 8.1  串行通信的基本概念

81

微计算机系统⑷ 为辅助线程写一个全局函数,主要完成数据接收的工作。注意OVERLAPPED 结构的使用,以及怎样实现了异步通信。

UINT CommWatchProc(HWND hSendWnd){   DWORD dwEvtMask=0 ;// 设置要监视的事件   SetCommMask( hCom, EV_RXCHAR|EV_TXEMPTY );  // 等待串口通信事件的发生  WaitCommEvent( hCom, &dwEvtMask, os );   // 检测返回的 dwEvtMask ,知道发生了什么串口事件:   if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR){ // 缓冲区中有数据到达   COMSTAT ComStat ; DWORD dwLength;   ClearCommError(hCom, &dwErrorFlags, &ComStat ) ;   dwLength = ComStat.cbInQue ; // 输入缓冲区有多少数据?

Page 82: 8.1  串行通信的基本概念

82

微计算机系统

   if (dwLength > 0) { BOOL fReadStat ;      fReadStat = ReadFile( hCom,

lpBuffer ,dwLength, &dwBytesRead,

    &READ_OS( npTTYInfo ) ); //// 读数据读数据

// // 注注 :: 在在 CreareFile()CreareFile() 时使用了时使用了 FILE_FLAG_OVERLAPPED,FILE_FLAG_OVERLAPPED, 现现在在 ReadFile()ReadFile() 也必须使用也必须使用 LPOVERLAPPEDLPOVERLAPPED 结构结构 .. 否则否则 ,, 函数会函数会不正确地报告读操作已完成了不正确地报告读操作已完成了 ..  使用  使用 LPOVERLAPPEDLPOVERLAPPED 结构结构 , ReadFile(), ReadFile() 立即返回立即返回 ,, 不必等待不必等待读操作完成读操作完成 ,, 实现异步通信实现异步通信 .. 此时此时 , ReadFile(), ReadFile() 返回返回 FALSE, GetLaFALSE, GetLastError()stError() 返回返回 ERROR_IO_PENDING. ERROR_IO_PENDING.

Page 83: 8.1  串行通信的基本概念

83

微计算机系统if (!fReadStat){   if (GetLastError() == ERROR_IO_PENDING){     while(!GetOverlappedResult(

hCom,       &READ_OS( npTTYInfo ),

& dwBytesRead, TRUE ) ){

       dwError = GetLastError();       if(dwError == ERROR_IO_INCOMPLETE)

continue ; // 缓冲区数据没有读完,继续       …… ……         ::PostMessage((HWND)hSendWnd,

WM_NOTIFYPROCESS,0,0); // 通知主线程,串口收到数据  

} }}

Page 84: 8.1  串行通信的基本概念

84

微计算机系统

⑸.在主线程中放入发送命令。BOOL    fWriteStat ; char szBuffer[count];   ………… // 准备好发送的数据,放在 szBuffer[] 中

fWriteStat = WriteFile(hCom, szBuffer, dwBytesToWrite,

       &dwBytesWritten, &WRITE_OS( npTTYInfo ) ); // 写数据

Page 85: 8.1  串行通信的基本概念

85

微计算机系统

int err=GetLastError();if (!fWriteStat) {

   if(GetLastError() == ERROR_IO_PENDING){     while(!GetOverlappedResult(

hCom, &WRITE_OS( npTTYInfo ),

          &dwBytesWritten, TRUE ) ) {

       dwError = GetLastError();       if(dwError == ERROR_IO_INCOMPLETE){           // 还没有结束        dwBytesSent += dwBytesWritten;

continue; }

     ......................

Page 86: 8.1  串行通信的基本概念

86

微计算机系统8.5.3 使用 MSComm 控件进行串口编程⑴.在当前 Project 中插入 MSComm 控件

Page 87: 8.1  串行通信的基本概念

87

微计算机系统

Page 88: 8.1  串行通信的基本概念

88

微计算机系统

Page 89: 8.1  串行通信的基本概念

89

微计算机系统

Page 90: 8.1  串行通信的基本概念

90

微计算机系统

Page 91: 8.1  串行通信的基本概念

91

微计算机系统

Page 92: 8.1  串行通信的基本概念

92

微计算机系统

Page 93: 8.1  串行通信的基本概念

93

微计算机系统

Page 94: 8.1  串行通信的基本概念

94

微计算机系统

Page 95: 8.1  串行通信的基本概念

95

微计算机系统

Page 96: 8.1  串行通信的基本概念

96

微计算机系统

Page 97: 8.1  串行通信的基本概念

97

微计算机系统

⑵.在 MainFrm.h 中加入 MSComm 控件:protected:   CMSComm m_ComPort;

在 Mainfrm.cpp::OnCreare() 中:DWORD style=WS_VISIBLE|WS_CHILD;   if (!m_ComPort.Create(

NULL,style,CRect(0,0,0,0),this,ID_COMMCTRL)

){TRACE0("Failed to create OLE Communications C

ontrol\n");return -1;    // fail to create

   }

Page 98: 8.1  串行通信的基本概念

98

微计算机系统⑶. 初始化串口m_ComPort.SetCommPort(1);    // 选择 COM?m_ComPort. SetInBufferSize(1024); // 设置输入缓冲区的字节数m_ComPort. SetOutBufferSize(512); // 设置输入缓冲区的字节数

if(!m_ComPort.GetPortOpen()) // 打开串口m_ComPort.SetPortOpen(TRUE);

m_ComPort.SetInputMode(1); // 设置输入方式为二进制方式m_ComPort.SetSettings("9600,n,8,1"); // 设置波特率等参数

m_ComPort.SetRThreshold(1); // 为 1 表示有一个字符引发一个事件m_ComPort.SetInputLen(0);

Page 99: 8.1  串行通信的基本概念

99

微计算机系统

⑷.捕捉串口事项。MSComm 控件可以采用轮询或事件驱动的方法从端口获取

数据。下面介绍事件驱动方法:有事件(如接收到数据)时通知程序。在程序中需要捕获并处理这些通讯事件。

在 MainFrm.h 中:protected:afx_msg void OnCommMscomm();DECLARE_EVENTSINK_MAP()

在 MainFrm.cpp 中:BEGIN_EVENTSINK_MAP(CMainFrame,CFrameWnd )   

ON_EVENT(CMainFrame,ID_COMMCTRL,1,OnCommMscomm,VTS_NONE) // 映射 ActiveX 控件事件END_EVENTSINK_MAP()

Page 100: 8.1  串行通信的基本概念

100

微计算机系统⑸.串口读。void CMainFrame::OnCommMscomm(){VARIANT vResponse;    int k; if(m_commCtrl.GetCommEvent()==2) {       

k=m_commCtrl.GetInBufferCount(); // 接收到的字符数目if(k>0) {

vResponse=m_commCtrl.GetInput(); // 读SaveData(k,

(unsigned char*) vResponse.parray->pvData);} // 接收到字符, MSComm 控件发送事件

}   …… // 处理其他 MSComm 控件}

Page 101: 8.1  串行通信的基本概念

101

微计算机系统

⑸.串口写。void CMainFrame::OnCommSend() {

…… // 准备需要发送的命令,放在 TxData[] 中CByteArray array;array.RemoveAll();array.SetSize(Count);for(i=0;i<Count;i++)

array.SetAt(i, TxData[i]);   m_ComPort.SetOutput(COleVariant(array)); // 发送数据}

Page 102: 8.1  串行通信的基本概念

102

微计算机系统8.5.4 编写串行通信类(组件)

TCustomComm = class(TComponent) private FHandle: THandle; FDCB: TDCB; FDeviceName: string; FEvent: TSimpleEvent; FCriticalSection: TCriticalSection; FReadTimeout: Integer; FWriteTimeout: Integer; FReadBufSize: Integer; FWriteBufSize: Integer; FMonitorEvents: TCommEventTypes; FBaudRate: TBaudRate; FParity: TParity; FStopbits: TStopbits; FDatabits: TDatabits; FEventThread: TCommEventThread; FEventChars: TCommEventChars; FOptions: TCommOptions; FFlowControl: TFlowControl; FOnBreak: TNotifyEvent; FOnCts: TNotifyEvent; FOnDsr: TNotifyEvent; FOnError: TCommErrorEvent; FOnRing: TNotifyEvent; FOnRlsd: TNotifyEvent; FOnRxChar: TCommRxCharEvent; FOnRxFlag: TNotifyEvent; FOnTxEmpty: TNotifyEvent;

Page 103: 8.1  串行通信的基本概念

103

微计算机系统procedure TCommEventThread.Execute;var Overlapped: TOverlapped; WaitEventResult: Boolean;begin FillChar(Overlapped, Sizeof(Overlapped), 0); Overlapped.hEvent := FEvent.Handle; while (not Terminated) do // 此线程在后台不断查询串口事件 begin {if the function returns FALSE and the GetLastError function returns ERROR_IO_PENDING, indicating that the operation is executing in the background} WaitEventResult := WaitCommEvent(FCommHandle, FEventMask, @Overlapped); if (GetLastError = ERROR_IO_PENDING) then WaitEventResult := (FEvent.WaitFor(INFINITE) = wrSignaled); {time-out interval never elapses,Until WaitCommEvent=True } if WaitEventResult then {WaitCommEvent=True} begin Synchronize(DoOnSignal); // 事件处理由主线程处理 FEvent.ResetEvent; end; end; PurgeComm(FCommHandle, PurgeReadWrite);end;

Page 104: 8.1  串行通信的基本概念

104

微计算机系统function TCustomComm.Write(var Buf; Count: Integer): Integer;var Overlapped: TOverlapped; ErrorCode: Integer;begin Lock; try FillChar(Overlapped, Sizeof(Overlapped), 0); Overlapped.hEvent := FEvent.Handle; if not WriteFile(FHandle, Buf, Count, dWord(Result), @Overlapped) and (GetLastError <> ERROR_IO_PENDING) then begin ErrorCode := GetLastError; RaiseCommError(sWriteError, ErrorCode); end; if FEvent.WaitFor(FWriteTimeout) <> wrSignaled then Result := -1 // 超时而事件为非通知状态,则操作失败 else begin GetOverlappedResult(Handle, Overlapped, dWord(Result), False); FEvent.ResetEvent; end; finally Unlock; end;end;

Page 105: 8.1  串行通信的基本概念

105

微计算机系统function TCustomComm.Read(var Buf; Count: Integer): Integer;var Overlapped: TOverlapped; ErrorCode: Integer;begin Lock; try FillChar(Overlapped, Sizeof(Overlapped), 0); Overlapped.hEvent := FEvent.Handle; if not ReadFile(FHandle, Buf, Count, dWord(Result), @Overlapped) and (GetLastError <> ERROR_IO_PENDING) then begin ErrorCode := GetLastError; RaiseCommError(sReadError, ErrorCode); end; if FEvent.WaitFor(FReadTimeout) <> wrSignaled then Result := -1 else begin GetOverlappedResult(Handle, Overlapped, dWord(Result), False); FEvent.ResetEvent; end; finally Unlock; end;end;