http://qsyang.yeah.net
现代微机原理与接口技术
1
8.1 串行通信的基本概念串行通信是将数据的各个位一位一位地,通过单条 1位宽的传输线按顺序分时传送,即通信双方一次传输一个二进制位。串行通信与并行通信是两种基本的数据通信方式。
发送方在发送前要将并行数据转成串行数据
,接收方接收后要完成串行数据到并行数据的转换。
8.1.1 串行通信第 8 章 串行接口
http://qsyang.yeah.net
现代微机原理与接口技术
2
与并行通信相比,串行通信的优势
传输距离长,可达到数千公里
长距离内串行数据传送速率会比并行数据传送速率快,串行通信的通信时钟频率较并行通信容易提高。
抗干扰能力强,串行通信信号间的互相干扰完全可以忽略。
费用低。
http://qsyang.yeah.net
现代微机原理与接口技术
3
8.1.2串行通信方式
单工方式 T R
半双工方式 T
RR
T
全双工方式 T
TR
R
http://qsyang.yeah.net
现代微机原理与接口技术
4
8.1.3 波特率与收 /发时钟波特率,单位时间内传送的二进制数据的位数,以位 /秒( b/s)表示,也称为数据位率。 它是衡量串行通信速率的重要指标 。
收 /发时钟 直接决定了通信线路上数据传输的速率
,对于收 /发双方之间数据传输的同步有十分重要的作用。
一般在发送端是由发送时钟的 下降沿 使送入移位寄存器的数据串行移位输出。而接收端则是在接收时钟的 上升沿 作用下将传输线上的数据逐位打入移位寄存器。
http://qsyang.yeah.net
现代微机原理与接口技术
5
为了提高串行通信的抗干扰能力,往往用多个时钟调制一个二进制数据,调制一个二进制数据的收 /发时钟个数称为 波特率系数 n。
收 /发时钟频率与波特率之间的关系:
收 /发时钟频率 =n× 波特率一般 n取 1,16,32和 64等。对于异步通信,常采用
n=16;对于同步通信,则必须取 n=1。
http://qsyang.yeah.net
现代微机原理与接口技术
6
8.1.4 信号调制解调原因,如果数字信号直接在公用电话网的传输线上传送,高次谐波的衰减会很厉害,从而使信号到了接收端后将发生严重畸变和失真。
解决,发送方使用 调制器 ( Modulator),把要传送的 数字信号 调制转换为适合在线路上传输的 音频模拟信号 ;接收方则使用 解调器 ( Demodulator)从线路上测出这个模拟信号,并还原成数字信号。
http://qsyang.yeah.net
现代微机原理与接口技术
7
调制方法,按照调制技术的不同分为调频(
FM)、调幅( AM)和调相( PM)三种,根据传输数字信号的变化规律去调整载波的频率
、幅度或相位
http://qsyang.yeah.net
现代微机原理与接口技术
8
8.1.5 信道复用时分多路复用 TDM(Time Division Multiplexing),就是将一条物理传输线路按时间分成若干时间片轮换地为多个信号所占用,每个时间片由复用的一个信号占用。
频分多路复用 FDM(Frequency Division
Multiplexing)就是利用频率调制原理,将要同时传送的多个信号进行频谱搬移,使它们互不重叠地占据信道频带的不同频率段,然后经发送器从同一信道上同时或不同时地发送出去。
计算机串行数据通信及其接口中使用时分多路复用系统。
http://qsyang.yeah.net
现代微机原理与接口技术
9
8.1.6 串行通信基本方式异步串行通信在通信的数据流中,字符间异步,字符内部各位间同步。 异步通信方式的,异步,主要体现在字符与字符之间通信没有严格的定时要求 。然而,一旦传送开始,收 /发双方则以预先约定的传输速率,在时钟的作用下,传送这个字符中的每一位。
http://qsyang.yeah.net
现代微机原理与接口技术
10
同步串行通信数据流中的字符与字符之间和字符内部的位与位之间都同步。同步串行通信是以数据块
(字符块)为信息单位传送,而每帧信息包括成百上千个字符,因此 传送一旦开始,要求每帧信息内部的每一位都要同步。
http://qsyang.yeah.net
现代微机原理与接口技术
11
8.2异步串行通信协议
http://qsyang.yeah.net
现代微机原理与接口技术
12
为了确保异步串行通信传输正确:
1)采用相反极性的起始位和停止位 /空闲位提供准确的时间基准
2)接收器在每位的中心采样,以获得最大的收 /发时钟频率偏差容限
3)接收器采用比传送波特率更高频率的时钟来控制采样时间,以提高采样的分辨能力和抗干扰能力。
http://qsyang.yeah.net
现代微机原理与接口技术
13
例题:
异步传输 7位 ASCII码,如果需要数据传输速率为 240字符 /秒,使用 1位奇偶校验位和 1位停止位,则:
1)波特率应该是多少?
2)有效数据位传输位是多少?
3)传输效率是多少?
答:
1)波特率是
(7位数据位 +1位起始位 +1位校验位 +1位停止位 )× 240
=2400b/s
2)有效数据位传输位是,7× 240=1680b/s
3)传输效率是,1680/2400=70%
http://qsyang.yeah.net
现代微机原理与接口技术
14
8.3 串行接口 RS-232C标准
8.3.1 串行通信系统数据终端设备 DTE——数据源和目的地数据通信设备 DCE——使数据符合线路要求
http://qsyang.yeah.net
现代微机原理与接口技术
15
引脚 代号 其他表示法 信号名 方向
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信号线
http://qsyang.yeah.net
现代微机原理与接口技术
16
8.3.3 常用的 RS-232C连接
1.使用 MODEM
http://qsyang.yeah.net
现代微机原理与接口技术
17
2.不使用 MODEM
http://qsyang.yeah.net
现代微机原理与接口技术
18
3,简单连接
4.最简单连接( 3线连接)
http://qsyang.yeah.net
现代微机原理与接口技术
19
8.3.4 电气特性
1.应保证电平在 ± (5~15)V之间对于数据线,逻辑,1” (MARK)= -3V~ - 15V
,
逻辑,0” (SPACE) = +3V~+15V
对于控制信号,接通状态( ON)即信号有效的电平 = +3V~15V
断开状态( OUT)即信号无效的电平 = - 3Ⅴ ~ - 15V。
http://qsyang.yeah.net
现代微机原理与接口技术
20
2.必须进行电平转换
RS-232C接口采用的是负逻辑,其逻辑电平与 TTL电平不一样,不能兼容。因此,为了实现与 TTL电路的连接,必须进行电平转换。
目前可以使用新型电平转换芯片 MAX232和
MAX232A(高速)双组 RS-232C发送 /接收器,
实现 TTL电平与 RS-232C电平双向转换。
http://qsyang.yeah.net
现代微机原理与接口技术
21
3.必须抗共模噪声干扰
RS-232C由于在发送器与接收器之间有公共信号地,不可能使用双端信号,因此共模噪声很容易引入信号系统中,且噪声幅度可高达好几伏,这是迫使 RS-232C使用较高传输电压的主要原因。另一个原因是为了补偿传输线上的信号衰减和沿线附加电平的影响。
http://qsyang.yeah.net
现代微机原理与接口技术
22
4.处理好最大传输速率和最大传输线长度的关系一般应用情况下,RS-232C的最高传输速率为
20Kb/s,最大传输线长度为 30m。
http://qsyang.yeah.net
现代微机原理与接口技术
23
8.3.5 机械特性
1,连接器
http://qsyang.yeah.net
现代微机原理与接口技术
24
http://qsyang.yeah.net
现代微机原理与接口技术
25
在通信速率低于 20Kb/s时,RS-232C所能直接连接的最大物理距离为 15m( 50ft)。
2,电缆长度使用特制的低电容电缆也能有效地提高电缆长度,
可以达到 150m( 500ft)甚至更多。
ft
N p F / f t
2 5 0 0 p F?L
RS-232C规定,若不使用 MODEM,则码元的畸变要小于 4%,驱动器的负载电容应该小于 2500pF,则单位
( 1ft)长度的电容值为 NpF的电缆的长度应该是:
http://qsyang.yeah.net
现代微机原理与接口技术
26
8.3.6 RS-232 的局限
RS-232C采用单端驱动、单端接收的单端双极性电路标准。仅用一条线路传输一种信号,根据该信号线上电平相对于公共的信号地电平的大小来决定逻辑的,1”和,0” 。
对于多条信号线来讲,它们的地线是公共的,这种共地传输方式,抗干扰能力很差。
尽管采用电平转换器来提高信号传输电平,但在较长距离时,由于电压损失,仍不可避免错误。
当信号穿过电磁干扰环境时,也可能因附加的干扰信号电平使发送的,0”变为,1”或,1”变为,0”。故其信号波特率不能过高,仅限在 20Kb/s以下,且距离不大于 15m。
http://qsyang.yeah.net
现代微机原理与接口技术
27
8.3.7 RS-485总线
1,RS-485接口标准是一种 平衡传输方式 的串行接口标准,这个标准的电气特性 对逻辑电平的定义是根据两条传输线之间的电位差值来决定的,当 AA'线的电平比 BB'线的电平高 200mⅤ 时表示逻辑,1”,当 AA'
线的电平比 BB'线的电平低 200mV时表示逻辑,0”。
http://qsyang.yeah.net
现代微机原理与接口技术
28
2,RS-485标准允许在电路中可有 32个发送器,和 32个接收器 。允许 一个发送器驱动多个负载设备,负载设备可以是驱动发送器、接收器或收发器组合单元
3,RS-485的共线电路结构是在 一对平衡传输线的两端都配置终端电阻,其发送器、接收器和组合收发器可挂在平衡传输线上的任何位置,实现在数据传输中多个驱动器和接收器共用同一传输线的多点应用。
4,由于 RS-485标准采用差动发送 /接收,因此 共模抑制比高、抗干扰能力强 ;
5,传输速率高,最大传输速率可达 10Mb/s(传送 15m)
,传输信号的摆幅小 ( 200mV);
6,传送距离远,采用双绞线,在不用 MODEM的情况下
,当 100Kb/s的传输速率时,可传送的距离为 1.2km,
http://qsyang.yeah.net
现代微机原理与接口技术
29
8.4 异步通信适配器
PC微机异步通信适配器是微机与微机
、微机与 MODEM及微机与外设之间进行异步通信的接口。其核心是 UART。
常见的 UART主要有 INS8250,PC16450和
PC16550。此外,还有带更大缓冲的 UART,
称为 PC16650和 PC16750。
http://qsyang.yeah.net
现代微机原理与接口技术
30
8.4.1 INS8250外部引脚
http://qsyang.yeah.net
现代微机原理与接口技术
31
1,并行数据 I/O及其控制线
D7~D0 8位双向三态数据线。
CS0,CS1和 CS2 片选线。
ADS 地址选通线 (锁存片选和内部寄存器选择 )
DISTR和 DISTR数据输入选通。 (读寄存器允许 )
DOSTR和 DOSTR数据输出选通。 (写寄存器允许 )
A0,A1和 A2 内部寄存器选择。
CSOUT 片选输出。( 为高表示该片被选中 )
DDIS 驱动器禁止。 (禁止处理器和 8250在数据线上的收发器动作 )
http://qsyang.yeah.net
现代微机原理与接口技术
32
2,串行数据 I/O线
SOUT 串行数据输出。
SIN 串行数据输入。
XTAL1 外部时钟输入端。
XTAL2 基准时钟信号输出端。
BAUDOUT工作时钟输出。
F工作时钟 =F基准时钟 ÷ 除数寄存器 =传送波特率 × 16
RCLK 接收时钟输入。 可和 BAUDOUT相接
http://qsyang.yeah.net
现代微机原理与接口技术
33
3.和 MODEM的握手信号线
RTS请求发送,输出线。
DSR数据设备就绪,输入线
DTR数据终端就绪,输出线。
RI振铃指示,输入线。
RLSD接收线路信号检测,输入线。
CTS清除发送,输入线。
http://qsyang.yeah.net
现代微机原理与接口技术
34
4.中断请求,复位输入及其他信号线
INTPRT 中断请求输出。
MR 主复位输入。
OUT1和 OUT2由用户指定的输出端。
MODEM控制寄存器的第二、第三位决定。
http://qsyang.yeah.net
现代微机原理与接口技术
35
8.4.2UART内部结构
http://qsyang.yeah.net
现代微机原理与接口技术
36
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位。
http://qsyang.yeah.net
现代微机原理与接口技术
37
1.线路控制寄存器 LCR
D7 D6 D5 D4 D3 D2 D1 D0
WLS0WLS1PEN STBEPSSPSBDLAB
字符长度选择
00——5位
01——6位
10——7位
11——8位停止位选择
0——1位
1——1.5位 (D1D0=00)
2位 (D1D0<>00)
奇偶校验允许奇偶校验选择
11——偶校验
01——奇校验附加奇偶标志位选择
0——不附加
1——附加 1位中止设置
1—中止
0—正常除数寄存器访问允许
0——禁止
1——允许
A2A1A0=011
http://qsyang.yeah.net
现代微机原理与接口技术
38
2.线路状态寄存器 LSR
D7 D6 D5 D4 D3 D2 D1 D0
DROEFE PEBITHRETSRE
接收缓冲区满接收重叠错接收奇偶错接收格式错(
无正确的停止位)
中止识别标志发送保持器空发送移位器空
FIFO中接收数据错误
(16550)
A2A1A0=101
http://qsyang.yeah.net
现代微机原理与接口技术
39
3.发送保持寄存器 THR
接收缓冲寄存器 RBR
D7 D0
CPU来的 8位数据并行进 THR
THR 低位到高位串行移位到 SOUT
引脚输出
……
D7 D0
接收移位寄存器发送移位寄存器
RBR低位到高位从
SIN引脚串行移位进来
8位数据并行进
CPU
发送方 接收方
DLAB=0,A2A1A0=000
http://qsyang.yeah.net
现代微机原理与接口技术
40
4.波特率除数锁存器这是一个软件控制的分频器,输出的工作时钟频率为 16倍的波特率。
除数寄存器值 = 基准时钟频率 ÷ ( 16× 波特率)
INS8250芯片输入的基准时钟频率为 1.8432MHz,若波特率为 4800b/s,则波特率除数为 0018H,DLH中应填
00H,DLL中应填 18H 。
思考题:
使用 INS8250异步传输 7位 ASCII码,如果需要数据传输速率为 240字符 /秒,使用 1位奇偶校验位和 1位停止位,波特率除数锁存器的值是多少?
注意,PC16550的基准时钟一般为 18.432MHz。
DLAB=1,A2A1A0=001(高 )或 000(低 )
http://qsyang.yeah.net
现代微机原理与接口技术
41
5.中断识别寄存器 IIR
D7 D6 D5 D4 D3 D2 D1 D0
IPID1ID20
未决中断指示
0-有
1-无中断类型标识超时中断
0-不超时
1-超时允许 64字节
FIFO(16750)
0-禁止
1-允许
FIFO使用指示
(16550)
01-允许 FIFO但不可用
11-允许 FIFO
A2A1A0=010(读)
http://qsyang.yeah.net
现代微机原理与接口技术
42
ID2 ID1 中断类型 优先权
1 1 接收出错 (重叠、奇偶错、格式错和中止 )
最高
1 0 接收缓冲器满 次高
0 1 发送保持器空 低
0 0 MODEM状态 (CTS,DSR,RI和
RLSD)改变最低
http://qsyang.yeah.net
现代微机原理与接口技术
43
6.中断允许寄存器 IER
D7 D6 D5 D4 D3 D2 D1 D0
I2EI1EI3E0
类型 2中断 (接收缓冲器满 )
1-允许
0-屏蔽类型 1
中断 (发送保持器空 )
1-允许
0-屏蔽类型 3
中断 (接收出错
)
1-允许
0-屏蔽进入低功耗模式
(16550)
进入睡眠模式
(16750)
DLAB=0,A2A1A0=001
I0E0
类型 0
中断
(MOD
EM状态改变 )
1-运行
0-屏蔽
http://qsyang.yeah.net
现代微机原理与接口技术
44
7.MODEM控制寄存器 MCR
A2A1A0=100
D7 D6 D5 D4 D3 D2 D1 D0
DTRRTSOUT10
数据终端就绪请求发送辅助输出
1
自动流量控制
(16750)
环路检测 (
内部自循环)
OUT20
辅助输出 2
,PC
用做中断
LOOP
注意这里的 OUTi位极性和 OUTi引脚相反。
http://qsyang.yeah.net
现代微机原理与接口技术
45
8.MODEM状态 寄存器 MSR
A2A1A0=110
D7 D6 D5 D4 D3 D2 D1 D0
CTS?DSRTERIRLSD
CTS
位发生改变
DSR
位发生改变收到
“振铃指示”
后沿
(下降沿
)
收到“
数传机就绪”
收到
“清除发送”
RLSDRI
RLS
D位发生改变
CTSDSR
收到
“振铃指示”
收到
“接收线载波检测
”
http://qsyang.yeah.net
现代微机原理与接口技术
46
9.FIFO控制寄存器 (FCR)
A2A1A0=010(写)
16550后才有
D7 D6 D5 D4 D3 D2 D1 D0
允许
FIF
O缓冲器工作清除接收
FIF
O缓冲器清除发送
FIF
O缓冲器允许 64
字节
FIFO
(16750)
保留 DM
A方式选择接收端中断触发器水平
(LS
B)
接收端中断触发器水平
(MS
B)
http://qsyang.yeah.net
现代微机原理与接口技术
47
触发器水平即是指示在中断产生之前,接收缓冲器应该装满多少个字节。
D7D6 触发器水平
00 1字节
01 4字节
10 8字节
11 12字节
http://qsyang.yeah.net
现代微机原理与接口技术
48
常用 UART比较
8250 16450 16550 16650 16750
FIFO - - 16字节 32字节 64字节超时检测 - - √ √ √
低功耗模式 - - √ √ √
睡眠模式 - - - - √
自动流量控制 - - - - √
临时寄存器 - √ √ √ √
http://qsyang.yeah.net
现代微机原理与接口技术
49
8.4.3 采用 UART的异步通信适配器硬件逻辑
1.PC机的串行口串口号 COM1 COM2 COM3 COM4
基地址 3F8 2F8 3E8 2E8
中断号 IRQ4 IRQ3 IRQ4 IRQ3
http://qsyang.yeah.net
现代微机原理与接口技术
50
2.PC机的串行口电路
http://qsyang.yeah.net
现代微机原理与接口技术
51
8.4.4 INS8250初始化
通过写除数寄存器 (端口 0和端口 1) 设置波特率
通过写线路控制寄存器(端口 3)设置通信数据格式。
通过写 MODEM控制寄存器 MCR(端口 4
)设置 MODEM控制字。
通过写中断允许寄存器(端口 1)设置中断允许控制字。
http://qsyang.yeah.net
现代微机原理与接口技术
52
mov dx,3fbh ; 线路控制寄存器地址
mov al,80h
out dx,al ; 使 DLAB=1,以便下面写除数; 寄存器
mov dx,3f8h ; 低位除数寄存器
mov al,0ch ; 9600波特率的除数低 8位
out dx,al
mov al,00
inc dx ; 高位除数寄存器
out dx,al
http://qsyang.yeah.net
现代微机原理与接口技术
53
mov al,00011011b ; 偶校验,1位停止位; 8位数据位
mov dx,3fbh ; 线路控制寄存器地址
out dx,al
mov al,03h ;
mov dx,3fch ; MODEM控制寄存器地址
out dx,al
mov al,0 ; 禁止中断
mov dx,3f9h ; 中断允许寄存器地址
out dx,al
http://qsyang.yeah.net
现代微机原理与接口技术
54
8.4.5 查询方式串行通信程序设计
1,查询方式发送 初始化 8250
读 LSR
D5=1?
发送一个字符发完?
结束
Y
Y
N
N
http://qsyang.yeah.net
现代微机原理与接口技术
55
2,查询方式接收 初始化 8250
读 LSR
D0=1?
接收一个字符收完?
结束
Y
Y
N
N
有错?
N
Y
错误处理
http://qsyang.yeah.net
现代微机原理与接口技术
56
1,通信中断初始化
8.4.6 中断方式串行通信程序设计
修改中断向量,按使用的端口 COM1或 COM2,
接管中断 0CH或中断 0BH。
确定 INS8250操作方式,设置中断允许寄存器相应位的允许或禁止,并允许中断操作(置 MCR
的 D3=1)。
确定起止式通信协议,设置通信波特率及数据帧传输格式。
开放通信中断,对 8259A中断控制器的屏蔽寄存器编程( OCW1),允许中断 IRQ4或 IRQ3。
http://qsyang.yeah.net
现代微机原理与接口技术
57
2,通信中断服务程序
首先读取中断识别寄存器,判断中断源,然后转向对应的处理子程序 。 判断中断源,应该按照中断优先级别次序进行 。
当中断识别寄存器 D2D1=11时,表明 接收出错中断
,需要再读取线路状态寄存器,分析错误原因,再进行错误处理 。
可能出现多个中断源同时引发中断 。 因此,每处理完一种中断源后,应继续读取中断识别寄存器,检测
D0是否为,0”,当 D0=0时,表明还有未决中断,应该继续分析中断源并进行中断处理 。
从中断程序返回的条件是中断识别寄存器的 D0=1。
http://qsyang.yeah.net
现代微机原理与接口技术
58
8.5 Win32串口编程(自学)
8.5.1 Win32串口编程方法
1,以文件方式打开串口使用 Win32 API中文件操作的有关函数来完成对串口的访问。
2,使用现有的 ActiveX控件实现现在一般使用的是微软公司的 MSComm控件,它是作为一个 OCX来提供的。
3,直接嵌入汇编法这种方法只能用在 Windows 98和 Windows 95操作系统下。在嵌入式汇编中,可直接对串口进行操作。
http://qsyang.yeah.net
现代微机原理与接口技术
59
( 1)应用 CreateFile()来打开串口
HANDLE CreateFile(
LPCTSTR lpFileName,// 文件名
DWORD dwDesiredAccess,// 存取模式
DWORD dwShareMode,// 共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes,// NULL
DWORD dwCreationDisposition,// 创建方法
DWORD dwFlagsAndAttributes,// 文件属性和标志
HANDLE hTemplateFile // 临时文件句柄
);
其中,lpFileName指定要打开的串口逻辑名,用字符串表示,
,COM1”表示串口 1,,COM2”表示串口 2。
由于串口是硬件,所以 dwCreationDisposition一般为
OPEN_EXISTING。
8.5.2以文件方式打开串口法
http://qsyang.yeah.net
现代微机原理与接口技术
60
( 2)初始化串口
BOOL SetupComm(
HANDLE hFile,// 通信设备句柄
DWORD dwInQueue,// 输入缓冲区大小
DWORD dwOutQueue // 输出缓冲区大小
);
( 3)关闭窗口
BOOL CloseHandle(
HANDLE hObject // 需要关闭的设备句柄
);
http://qsyang.yeah.net
现代微机原理与接口技术
61
( 4)串口配置
BOOL GetCommState(
HANDLE hFile,// 通信设备句柄
LPDCB lpDCB // 设备控制块
);
BOOL SetCommState(
HANDLE hFile,//通信设备句柄
LPDCB lpDCB //设备控制块
);
http://qsyang.yeah.net
现代微机原理与接口技术
62
http://qsyang.yeah.net
现代微机原理与接口技术
63
( 5)串口属性
BOOL GetCommProperties(
HANDLE hFile,//通信设备句柄
LPCOMMPROP lpCommProp // 通信属性结构
);
http://qsyang.yeah.net
现代微机原理与接口技术
64
( 6)读串口操作
BOOL ReadFile(
HANDLE hFile,// 设备句柄
LPVOID lpBuffer,// 数据缓冲
DWORD nNumberOfBytesToRead,// 读取的字节数
LPDWORD lpNumberOfBytesRead,// 实际读的字节数
LPOVERLAPPED lpOverlapped // overlapped结构
);
( 7)写串口操作
BOOL WriteFile(
HANDLE hFile,// 设备句柄
LPVOID lpBuffer,// 数据缓冲
DWORD nNumberOfBytesToWrite,// 写的字节数
LPDWORD lpNumberOfBytesWrite,// 实际写的字节数
LPOVERLAPPED lpOverlapped // overlapped结构
);
http://qsyang.yeah.net
现代微机原理与接口技术
65
( 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;
http://qsyang.yeah.net
现代微机原理与接口技术
66
异步 I/O操作可以用 GetOverlappedResult()函数来获得结果
BOOL GetOverlappedResult(
HANDLE hFile,// 设备句柄
LPOVERLAPPED lpOverlapped,// overlapped结构
LPDWORD lpNumberOfBytesTransferred,// 传送的字节数
BOOL bWait // 指定函数是否等待挂起的异步操作完成
);
异步 I/O的时候,Windows可以用 WaitForSingleObject()函数来检查事件对象。
DWORD WaitForSingleObject(
HANDLE hHandle,// 对象句柄
DWORD dwMilliseconds // 内部超时时间
);
http://qsyang.yeah.net
现代微机原理与接口技术
67
( 9)超时设置异步(重叠) I/O操作读写串口引入超时结构,在超时时间到的时候,如果读写还没结束,则读写会强行终止。异步时,强行终止的读写动作实际传输的字符数在 OVERLAPPED结构中返回。超时结构如下:
typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout; //两字符间的最大时间间隔
DWORD ReadTotalTimeoutMultiplier; //计算读操作总超时的超时系数
DWORD ReadTotalTimeoutConstant; //计算读操作总超时的超时常数
DWORD WriteTotalTimeoutMultiplier; //计算写操作总超时的超时系数
DWORD WriteTotalTimeoutConstant; //计算写操作总超时的超时常数
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
http://qsyang.yeah.net
现代微机原理与接口技术
68
总超时计算公式是:
总超时=超时系数 × 读或写字节数+超时常数
BOOL SetCommTimeouts(
HANDLE hFile,// 通信设备句柄
LPCOMMTIMEOUTS lpCommTimeouts // 超时结构 );
BOOL GetCommTimeouts(
HANDLE hFile,// 通信设备句柄
LPCOMMTIMEOUTS lpCommTimeouts // 超时结构 );
http://qsyang.yeah.net
现代微机原理与接口技术
69
( 10)通信状态和通信错误如果串口发生奇偶错误等错误的时候,I/O操作会终止。
如果程序要继续执行 I/O操作,就需要调用
ClearCommError()函数,该函数清除错误条件,并确定串口的通信状态:
BOOL ClearCommError(
HANDLE hFile,// 通信设备句柄
LPDWORD lpErrors,// 错误代码
LPCOMSTAT lpStat // communications结构
);
http://qsyang.yeah.net
现代微机原理与接口技术
70
错误代码
http://qsyang.yeah.net
现代微机原理与接口技术
71
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;
http://qsyang.yeah.net
现代微机原理与接口技术
72
( 11)通信事件
Windows有以下的通信事件:
http://qsyang.yeah.net
现代微机原理与接口技术
73
应用程序可用 SetCommMask()函数来建立事件掩模来监视指定通信资源上的事件。
BOOL SetCommMask(
HANDLE hFile,// 通信设备句柄
DWORD dwEvtMask // 事件掩模
);
http://qsyang.yeah.net
现代微机原理与接口技术
74
在用 SetCommMask()指定了有用的事件后,应用程序就调用 WaitCommEvent()函数来等带其中的一个事件发生。
BOOL WaitCommEvent(
HANDLE hFile,// 设备句柄
LPDWORD lpEvtMask,// 事件类型
LPOVERLAPPED lpOverlapped,// overlapped结构
);
http://qsyang.yeah.net
现代微机原理与接口技术
75
举例:
⑴,在中 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();
…… // 处理错误
}
http://qsyang.yeah.net
现代微机原理与接口技术
76
//检测打开串口操作是否成功
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);
http://qsyang.yeah.net
现代微机原理与接口技术
77
DCB dcb ; // 定义数据控制块结构
GetCommState(hCom,&dcb ) ; //读串口原来的参数设置
dcb.BaudRate =9600; // 9600的波特率
dcb.ByteSize =8; // 8位数据位
dcb.Parity = NOPARITY; // 无校验位
dcb.StopBits = ONESTOPBIT ; // 1位停止位
dcb.fBinary = TRUE ; // Win32中此位一定要位 TRUE
dcb.fParity = FALSE; // 不执行奇偶校验
SetCommState(hCom,&dcb ) ; //串口参数配置
// 上述的 COMMTIMEOUTS结构和 DCB都很重要,实际工作中需要仔细选择参数。
http://qsyang.yeah.net
现代微机原理与接口技术
78
⑶ 启动一个辅助线程,用于串口事件的处理。
Win32提供了两种线程,辅助线程 和 用户界面线程
。区别在于:辅助线程没有窗口,所以它没有自己的消息循环。但是辅助线程很容易编程,通常也很有用。
其次,我们使用辅助线程,主要用它来监视串口状态,
看有无数据到达、通信有无错误 ;而主线程则可专心进行数据处理、提供友好的用户界面等重要的工作。
hCommWatchThread= CreateThread(
(LPSECURITY_ATTRIBUTES) NULL,//安全属性
0,//初始化线程栈的大小,缺省为与主线程大小相同
(LPTHREAD_START_ROUTINE)CommWatchProc,//线程的全局函数
GetSafeHwnd(),//此处传入了主框架的句柄
0,
&dwThreadID );
ASSERT(hCommWatchThread!=NULL);
http://qsyang.yeah.net
现代微机原理与接口技术
79
⑷ 为辅助线程写一个全局函数,主要完成数据接收的工作。注意
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 ; //输入缓冲区有多少数据?
http://qsyang.yeah.net
现代微机原理与接口技术
80
if (dwLength > 0) {
BOOL fReadStat ;
fReadStat = ReadFile( hCom,
lpBuffer,
dwLength,
&dwBytesRead,
&READ_OS( npTTYInfo ) ); //读数据
// 注,在 CreareFile()时使用了 FILE_FLAG_OVERLAPPED,现在
ReadFile()也必须使用 LPOVERLAPPED结构,否则,函数会不正确地报告读操作已完成了,
使用 LPOVERLAPPED结构,ReadFile()立即返回,不必等待读操作完成,实现异步通信,此时,ReadFile()返回 FALSE,
GetLastError()返回 ERROR_IO_PENDING,
http://qsyang.yeah.net
现代微机原理与接口技术
81
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); //通知主线程,串口收到数据
}
}
}
http://qsyang.yeah.net
现代微机原理与接口技术
82
⑸,在主线程中放入发送命令。
BOOL fWriteStat ;
char szBuffer[count];
………… //准备好发送的数据,放在 szBuffer[]中
fWriteStat = WriteFile(hCom,
szBuffer,
dwBytesToWrite,
&dwBytesWritten,
&WRITE_OS( npTTYInfo ) ); //写数据
http://qsyang.yeah.net
现代微机原理与接口技术
83
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;
}
......................
http://qsyang.yeah.net
现代微机原理与接口技术
84
8.5.3使用 MSComm控件进行串口编程
⑴,在当前 Project中插入 MSComm控件
http://qsyang.yeah.net
现代微机原理与接口技术
85
http://qsyang.yeah.net
现代微机原理与接口技术
86
http://qsyang.yeah.net
现代微机原理与接口技术
87
http://qsyang.yeah.net
现代微机原理与接口技术
88
http://qsyang.yeah.net
现代微机原理与接口技术
89
http://qsyang.yeah.net
现代微机原理与接口技术
90
http://qsyang.yeah.net
现代微机原理与接口技术
91
http://qsyang.yeah.net
现代微机原理与接口技术
92
http://qsyang.yeah.net
现代微机原理与接口技术
93
http://qsyang.yeah.net
现代微机原理与接口技术
94
http://qsyang.yeah.net
现代微机原理与接口技术
95
⑵,在 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
Control\n");
return -1; // fail to create
}
http://qsyang.yeah.net
现代微机原理与接口技术
96
⑶,初始化串口
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);
http://qsyang.yeah.net
现代微机原理与接口技术
97
⑷,捕捉串口事项。
MSComm控件可以采用轮询或事件驱动的方法从端口获取数据。下面介绍事件驱动方法:有事件(如接收到数据)时通知程序。在程序中需要捕获并处理这些通讯事件。
在 MainFrm.h中:
protected:
afx_msg void OnCommMscomm();
DECLARE_EVENTSINK_MAP()
在 MainFrm.cpp中:
BEGIN_EVENTSINK_MAP(CMainFrame,CFrameWnd )
ON_EVENT(CMainFrame,ID_COMMCTRL,1,OnComm
Mscomm,VTS_NONE) //映射 ActiveX控件事件
END_EVENTSINK_MAP()
http://qsyang.yeah.net
现代微机原理与接口技术
98
⑸,串口读。
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控件
}
http://qsyang.yeah.net
现代微机原理与接口技术
99
⑸,串口写。
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)); // 发送数据
}
现代微机原理与接口技术
1
8.1 串行通信的基本概念串行通信是将数据的各个位一位一位地,通过单条 1位宽的传输线按顺序分时传送,即通信双方一次传输一个二进制位。串行通信与并行通信是两种基本的数据通信方式。
发送方在发送前要将并行数据转成串行数据
,接收方接收后要完成串行数据到并行数据的转换。
8.1.1 串行通信第 8 章 串行接口
http://qsyang.yeah.net
现代微机原理与接口技术
2
与并行通信相比,串行通信的优势
传输距离长,可达到数千公里
长距离内串行数据传送速率会比并行数据传送速率快,串行通信的通信时钟频率较并行通信容易提高。
抗干扰能力强,串行通信信号间的互相干扰完全可以忽略。
费用低。
http://qsyang.yeah.net
现代微机原理与接口技术
3
8.1.2串行通信方式
单工方式 T R
半双工方式 T
RR
T
全双工方式 T
TR
R
http://qsyang.yeah.net
现代微机原理与接口技术
4
8.1.3 波特率与收 /发时钟波特率,单位时间内传送的二进制数据的位数,以位 /秒( b/s)表示,也称为数据位率。 它是衡量串行通信速率的重要指标 。
收 /发时钟 直接决定了通信线路上数据传输的速率
,对于收 /发双方之间数据传输的同步有十分重要的作用。
一般在发送端是由发送时钟的 下降沿 使送入移位寄存器的数据串行移位输出。而接收端则是在接收时钟的 上升沿 作用下将传输线上的数据逐位打入移位寄存器。
http://qsyang.yeah.net
现代微机原理与接口技术
5
为了提高串行通信的抗干扰能力,往往用多个时钟调制一个二进制数据,调制一个二进制数据的收 /发时钟个数称为 波特率系数 n。
收 /发时钟频率与波特率之间的关系:
收 /发时钟频率 =n× 波特率一般 n取 1,16,32和 64等。对于异步通信,常采用
n=16;对于同步通信,则必须取 n=1。
http://qsyang.yeah.net
现代微机原理与接口技术
6
8.1.4 信号调制解调原因,如果数字信号直接在公用电话网的传输线上传送,高次谐波的衰减会很厉害,从而使信号到了接收端后将发生严重畸变和失真。
解决,发送方使用 调制器 ( Modulator),把要传送的 数字信号 调制转换为适合在线路上传输的 音频模拟信号 ;接收方则使用 解调器 ( Demodulator)从线路上测出这个模拟信号,并还原成数字信号。
http://qsyang.yeah.net
现代微机原理与接口技术
7
调制方法,按照调制技术的不同分为调频(
FM)、调幅( AM)和调相( PM)三种,根据传输数字信号的变化规律去调整载波的频率
、幅度或相位
http://qsyang.yeah.net
现代微机原理与接口技术
8
8.1.5 信道复用时分多路复用 TDM(Time Division Multiplexing),就是将一条物理传输线路按时间分成若干时间片轮换地为多个信号所占用,每个时间片由复用的一个信号占用。
频分多路复用 FDM(Frequency Division
Multiplexing)就是利用频率调制原理,将要同时传送的多个信号进行频谱搬移,使它们互不重叠地占据信道频带的不同频率段,然后经发送器从同一信道上同时或不同时地发送出去。
计算机串行数据通信及其接口中使用时分多路复用系统。
http://qsyang.yeah.net
现代微机原理与接口技术
9
8.1.6 串行通信基本方式异步串行通信在通信的数据流中,字符间异步,字符内部各位间同步。 异步通信方式的,异步,主要体现在字符与字符之间通信没有严格的定时要求 。然而,一旦传送开始,收 /发双方则以预先约定的传输速率,在时钟的作用下,传送这个字符中的每一位。
http://qsyang.yeah.net
现代微机原理与接口技术
10
同步串行通信数据流中的字符与字符之间和字符内部的位与位之间都同步。同步串行通信是以数据块
(字符块)为信息单位传送,而每帧信息包括成百上千个字符,因此 传送一旦开始,要求每帧信息内部的每一位都要同步。
http://qsyang.yeah.net
现代微机原理与接口技术
11
8.2异步串行通信协议
http://qsyang.yeah.net
现代微机原理与接口技术
12
为了确保异步串行通信传输正确:
1)采用相反极性的起始位和停止位 /空闲位提供准确的时间基准
2)接收器在每位的中心采样,以获得最大的收 /发时钟频率偏差容限
3)接收器采用比传送波特率更高频率的时钟来控制采样时间,以提高采样的分辨能力和抗干扰能力。
http://qsyang.yeah.net
现代微机原理与接口技术
13
例题:
异步传输 7位 ASCII码,如果需要数据传输速率为 240字符 /秒,使用 1位奇偶校验位和 1位停止位,则:
1)波特率应该是多少?
2)有效数据位传输位是多少?
3)传输效率是多少?
答:
1)波特率是
(7位数据位 +1位起始位 +1位校验位 +1位停止位 )× 240
=2400b/s
2)有效数据位传输位是,7× 240=1680b/s
3)传输效率是,1680/2400=70%
http://qsyang.yeah.net
现代微机原理与接口技术
14
8.3 串行接口 RS-232C标准
8.3.1 串行通信系统数据终端设备 DTE——数据源和目的地数据通信设备 DCE——使数据符合线路要求
http://qsyang.yeah.net
现代微机原理与接口技术
15
引脚 代号 其他表示法 信号名 方向
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信号线
http://qsyang.yeah.net
现代微机原理与接口技术
16
8.3.3 常用的 RS-232C连接
1.使用 MODEM
http://qsyang.yeah.net
现代微机原理与接口技术
17
2.不使用 MODEM
http://qsyang.yeah.net
现代微机原理与接口技术
18
3,简单连接
4.最简单连接( 3线连接)
http://qsyang.yeah.net
现代微机原理与接口技术
19
8.3.4 电气特性
1.应保证电平在 ± (5~15)V之间对于数据线,逻辑,1” (MARK)= -3V~ - 15V
,
逻辑,0” (SPACE) = +3V~+15V
对于控制信号,接通状态( ON)即信号有效的电平 = +3V~15V
断开状态( OUT)即信号无效的电平 = - 3Ⅴ ~ - 15V。
http://qsyang.yeah.net
现代微机原理与接口技术
20
2.必须进行电平转换
RS-232C接口采用的是负逻辑,其逻辑电平与 TTL电平不一样,不能兼容。因此,为了实现与 TTL电路的连接,必须进行电平转换。
目前可以使用新型电平转换芯片 MAX232和
MAX232A(高速)双组 RS-232C发送 /接收器,
实现 TTL电平与 RS-232C电平双向转换。
http://qsyang.yeah.net
现代微机原理与接口技术
21
3.必须抗共模噪声干扰
RS-232C由于在发送器与接收器之间有公共信号地,不可能使用双端信号,因此共模噪声很容易引入信号系统中,且噪声幅度可高达好几伏,这是迫使 RS-232C使用较高传输电压的主要原因。另一个原因是为了补偿传输线上的信号衰减和沿线附加电平的影响。
http://qsyang.yeah.net
现代微机原理与接口技术
22
4.处理好最大传输速率和最大传输线长度的关系一般应用情况下,RS-232C的最高传输速率为
20Kb/s,最大传输线长度为 30m。
http://qsyang.yeah.net
现代微机原理与接口技术
23
8.3.5 机械特性
1,连接器
http://qsyang.yeah.net
现代微机原理与接口技术
24
http://qsyang.yeah.net
现代微机原理与接口技术
25
在通信速率低于 20Kb/s时,RS-232C所能直接连接的最大物理距离为 15m( 50ft)。
2,电缆长度使用特制的低电容电缆也能有效地提高电缆长度,
可以达到 150m( 500ft)甚至更多。
ft
N p F / f t
2 5 0 0 p F?L
RS-232C规定,若不使用 MODEM,则码元的畸变要小于 4%,驱动器的负载电容应该小于 2500pF,则单位
( 1ft)长度的电容值为 NpF的电缆的长度应该是:
http://qsyang.yeah.net
现代微机原理与接口技术
26
8.3.6 RS-232 的局限
RS-232C采用单端驱动、单端接收的单端双极性电路标准。仅用一条线路传输一种信号,根据该信号线上电平相对于公共的信号地电平的大小来决定逻辑的,1”和,0” 。
对于多条信号线来讲,它们的地线是公共的,这种共地传输方式,抗干扰能力很差。
尽管采用电平转换器来提高信号传输电平,但在较长距离时,由于电压损失,仍不可避免错误。
当信号穿过电磁干扰环境时,也可能因附加的干扰信号电平使发送的,0”变为,1”或,1”变为,0”。故其信号波特率不能过高,仅限在 20Kb/s以下,且距离不大于 15m。
http://qsyang.yeah.net
现代微机原理与接口技术
27
8.3.7 RS-485总线
1,RS-485接口标准是一种 平衡传输方式 的串行接口标准,这个标准的电气特性 对逻辑电平的定义是根据两条传输线之间的电位差值来决定的,当 AA'线的电平比 BB'线的电平高 200mⅤ 时表示逻辑,1”,当 AA'
线的电平比 BB'线的电平低 200mV时表示逻辑,0”。
http://qsyang.yeah.net
现代微机原理与接口技术
28
2,RS-485标准允许在电路中可有 32个发送器,和 32个接收器 。允许 一个发送器驱动多个负载设备,负载设备可以是驱动发送器、接收器或收发器组合单元
3,RS-485的共线电路结构是在 一对平衡传输线的两端都配置终端电阻,其发送器、接收器和组合收发器可挂在平衡传输线上的任何位置,实现在数据传输中多个驱动器和接收器共用同一传输线的多点应用。
4,由于 RS-485标准采用差动发送 /接收,因此 共模抑制比高、抗干扰能力强 ;
5,传输速率高,最大传输速率可达 10Mb/s(传送 15m)
,传输信号的摆幅小 ( 200mV);
6,传送距离远,采用双绞线,在不用 MODEM的情况下
,当 100Kb/s的传输速率时,可传送的距离为 1.2km,
http://qsyang.yeah.net
现代微机原理与接口技术
29
8.4 异步通信适配器
PC微机异步通信适配器是微机与微机
、微机与 MODEM及微机与外设之间进行异步通信的接口。其核心是 UART。
常见的 UART主要有 INS8250,PC16450和
PC16550。此外,还有带更大缓冲的 UART,
称为 PC16650和 PC16750。
http://qsyang.yeah.net
现代微机原理与接口技术
30
8.4.1 INS8250外部引脚
http://qsyang.yeah.net
现代微机原理与接口技术
31
1,并行数据 I/O及其控制线
D7~D0 8位双向三态数据线。
CS0,CS1和 CS2 片选线。
ADS 地址选通线 (锁存片选和内部寄存器选择 )
DISTR和 DISTR数据输入选通。 (读寄存器允许 )
DOSTR和 DOSTR数据输出选通。 (写寄存器允许 )
A0,A1和 A2 内部寄存器选择。
CSOUT 片选输出。( 为高表示该片被选中 )
DDIS 驱动器禁止。 (禁止处理器和 8250在数据线上的收发器动作 )
http://qsyang.yeah.net
现代微机原理与接口技术
32
2,串行数据 I/O线
SOUT 串行数据输出。
SIN 串行数据输入。
XTAL1 外部时钟输入端。
XTAL2 基准时钟信号输出端。
BAUDOUT工作时钟输出。
F工作时钟 =F基准时钟 ÷ 除数寄存器 =传送波特率 × 16
RCLK 接收时钟输入。 可和 BAUDOUT相接
http://qsyang.yeah.net
现代微机原理与接口技术
33
3.和 MODEM的握手信号线
RTS请求发送,输出线。
DSR数据设备就绪,输入线
DTR数据终端就绪,输出线。
RI振铃指示,输入线。
RLSD接收线路信号检测,输入线。
CTS清除发送,输入线。
http://qsyang.yeah.net
现代微机原理与接口技术
34
4.中断请求,复位输入及其他信号线
INTPRT 中断请求输出。
MR 主复位输入。
OUT1和 OUT2由用户指定的输出端。
MODEM控制寄存器的第二、第三位决定。
http://qsyang.yeah.net
现代微机原理与接口技术
35
8.4.2UART内部结构
http://qsyang.yeah.net
现代微机原理与接口技术
36
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位。
http://qsyang.yeah.net
现代微机原理与接口技术
37
1.线路控制寄存器 LCR
D7 D6 D5 D4 D3 D2 D1 D0
WLS0WLS1PEN STBEPSSPSBDLAB
字符长度选择
00——5位
01——6位
10——7位
11——8位停止位选择
0——1位
1——1.5位 (D1D0=00)
2位 (D1D0<>00)
奇偶校验允许奇偶校验选择
11——偶校验
01——奇校验附加奇偶标志位选择
0——不附加
1——附加 1位中止设置
1—中止
0—正常除数寄存器访问允许
0——禁止
1——允许
A2A1A0=011
http://qsyang.yeah.net
现代微机原理与接口技术
38
2.线路状态寄存器 LSR
D7 D6 D5 D4 D3 D2 D1 D0
DROEFE PEBITHRETSRE
接收缓冲区满接收重叠错接收奇偶错接收格式错(
无正确的停止位)
中止识别标志发送保持器空发送移位器空
FIFO中接收数据错误
(16550)
A2A1A0=101
http://qsyang.yeah.net
现代微机原理与接口技术
39
3.发送保持寄存器 THR
接收缓冲寄存器 RBR
D7 D0
CPU来的 8位数据并行进 THR
THR 低位到高位串行移位到 SOUT
引脚输出
……
D7 D0
接收移位寄存器发送移位寄存器
RBR低位到高位从
SIN引脚串行移位进来
8位数据并行进
CPU
发送方 接收方
DLAB=0,A2A1A0=000
http://qsyang.yeah.net
现代微机原理与接口技术
40
4.波特率除数锁存器这是一个软件控制的分频器,输出的工作时钟频率为 16倍的波特率。
除数寄存器值 = 基准时钟频率 ÷ ( 16× 波特率)
INS8250芯片输入的基准时钟频率为 1.8432MHz,若波特率为 4800b/s,则波特率除数为 0018H,DLH中应填
00H,DLL中应填 18H 。
思考题:
使用 INS8250异步传输 7位 ASCII码,如果需要数据传输速率为 240字符 /秒,使用 1位奇偶校验位和 1位停止位,波特率除数锁存器的值是多少?
注意,PC16550的基准时钟一般为 18.432MHz。
DLAB=1,A2A1A0=001(高 )或 000(低 )
http://qsyang.yeah.net
现代微机原理与接口技术
41
5.中断识别寄存器 IIR
D7 D6 D5 D4 D3 D2 D1 D0
IPID1ID20
未决中断指示
0-有
1-无中断类型标识超时中断
0-不超时
1-超时允许 64字节
FIFO(16750)
0-禁止
1-允许
FIFO使用指示
(16550)
01-允许 FIFO但不可用
11-允许 FIFO
A2A1A0=010(读)
http://qsyang.yeah.net
现代微机原理与接口技术
42
ID2 ID1 中断类型 优先权
1 1 接收出错 (重叠、奇偶错、格式错和中止 )
最高
1 0 接收缓冲器满 次高
0 1 发送保持器空 低
0 0 MODEM状态 (CTS,DSR,RI和
RLSD)改变最低
http://qsyang.yeah.net
现代微机原理与接口技术
43
6.中断允许寄存器 IER
D7 D6 D5 D4 D3 D2 D1 D0
I2EI1EI3E0
类型 2中断 (接收缓冲器满 )
1-允许
0-屏蔽类型 1
中断 (发送保持器空 )
1-允许
0-屏蔽类型 3
中断 (接收出错
)
1-允许
0-屏蔽进入低功耗模式
(16550)
进入睡眠模式
(16750)
DLAB=0,A2A1A0=001
I0E0
类型 0
中断
(MOD
EM状态改变 )
1-运行
0-屏蔽
http://qsyang.yeah.net
现代微机原理与接口技术
44
7.MODEM控制寄存器 MCR
A2A1A0=100
D7 D6 D5 D4 D3 D2 D1 D0
DTRRTSOUT10
数据终端就绪请求发送辅助输出
1
自动流量控制
(16750)
环路检测 (
内部自循环)
OUT20
辅助输出 2
,PC
用做中断
LOOP
注意这里的 OUTi位极性和 OUTi引脚相反。
http://qsyang.yeah.net
现代微机原理与接口技术
45
8.MODEM状态 寄存器 MSR
A2A1A0=110
D7 D6 D5 D4 D3 D2 D1 D0
CTS?DSRTERIRLSD
CTS
位发生改变
DSR
位发生改变收到
“振铃指示”
后沿
(下降沿
)
收到“
数传机就绪”
收到
“清除发送”
RLSDRI
RLS
D位发生改变
CTSDSR
收到
“振铃指示”
收到
“接收线载波检测
”
http://qsyang.yeah.net
现代微机原理与接口技术
46
9.FIFO控制寄存器 (FCR)
A2A1A0=010(写)
16550后才有
D7 D6 D5 D4 D3 D2 D1 D0
允许
FIF
O缓冲器工作清除接收
FIF
O缓冲器清除发送
FIF
O缓冲器允许 64
字节
FIFO
(16750)
保留 DM
A方式选择接收端中断触发器水平
(LS
B)
接收端中断触发器水平
(MS
B)
http://qsyang.yeah.net
现代微机原理与接口技术
47
触发器水平即是指示在中断产生之前,接收缓冲器应该装满多少个字节。
D7D6 触发器水平
00 1字节
01 4字节
10 8字节
11 12字节
http://qsyang.yeah.net
现代微机原理与接口技术
48
常用 UART比较
8250 16450 16550 16650 16750
FIFO - - 16字节 32字节 64字节超时检测 - - √ √ √
低功耗模式 - - √ √ √
睡眠模式 - - - - √
自动流量控制 - - - - √
临时寄存器 - √ √ √ √
http://qsyang.yeah.net
现代微机原理与接口技术
49
8.4.3 采用 UART的异步通信适配器硬件逻辑
1.PC机的串行口串口号 COM1 COM2 COM3 COM4
基地址 3F8 2F8 3E8 2E8
中断号 IRQ4 IRQ3 IRQ4 IRQ3
http://qsyang.yeah.net
现代微机原理与接口技术
50
2.PC机的串行口电路
http://qsyang.yeah.net
现代微机原理与接口技术
51
8.4.4 INS8250初始化
通过写除数寄存器 (端口 0和端口 1) 设置波特率
通过写线路控制寄存器(端口 3)设置通信数据格式。
通过写 MODEM控制寄存器 MCR(端口 4
)设置 MODEM控制字。
通过写中断允许寄存器(端口 1)设置中断允许控制字。
http://qsyang.yeah.net
现代微机原理与接口技术
52
mov dx,3fbh ; 线路控制寄存器地址
mov al,80h
out dx,al ; 使 DLAB=1,以便下面写除数; 寄存器
mov dx,3f8h ; 低位除数寄存器
mov al,0ch ; 9600波特率的除数低 8位
out dx,al
mov al,00
inc dx ; 高位除数寄存器
out dx,al
http://qsyang.yeah.net
现代微机原理与接口技术
53
mov al,00011011b ; 偶校验,1位停止位; 8位数据位
mov dx,3fbh ; 线路控制寄存器地址
out dx,al
mov al,03h ;
mov dx,3fch ; MODEM控制寄存器地址
out dx,al
mov al,0 ; 禁止中断
mov dx,3f9h ; 中断允许寄存器地址
out dx,al
http://qsyang.yeah.net
现代微机原理与接口技术
54
8.4.5 查询方式串行通信程序设计
1,查询方式发送 初始化 8250
读 LSR
D5=1?
发送一个字符发完?
结束
Y
Y
N
N
http://qsyang.yeah.net
现代微机原理与接口技术
55
2,查询方式接收 初始化 8250
读 LSR
D0=1?
接收一个字符收完?
结束
Y
Y
N
N
有错?
N
Y
错误处理
http://qsyang.yeah.net
现代微机原理与接口技术
56
1,通信中断初始化
8.4.6 中断方式串行通信程序设计
修改中断向量,按使用的端口 COM1或 COM2,
接管中断 0CH或中断 0BH。
确定 INS8250操作方式,设置中断允许寄存器相应位的允许或禁止,并允许中断操作(置 MCR
的 D3=1)。
确定起止式通信协议,设置通信波特率及数据帧传输格式。
开放通信中断,对 8259A中断控制器的屏蔽寄存器编程( OCW1),允许中断 IRQ4或 IRQ3。
http://qsyang.yeah.net
现代微机原理与接口技术
57
2,通信中断服务程序
首先读取中断识别寄存器,判断中断源,然后转向对应的处理子程序 。 判断中断源,应该按照中断优先级别次序进行 。
当中断识别寄存器 D2D1=11时,表明 接收出错中断
,需要再读取线路状态寄存器,分析错误原因,再进行错误处理 。
可能出现多个中断源同时引发中断 。 因此,每处理完一种中断源后,应继续读取中断识别寄存器,检测
D0是否为,0”,当 D0=0时,表明还有未决中断,应该继续分析中断源并进行中断处理 。
从中断程序返回的条件是中断识别寄存器的 D0=1。
http://qsyang.yeah.net
现代微机原理与接口技术
58
8.5 Win32串口编程(自学)
8.5.1 Win32串口编程方法
1,以文件方式打开串口使用 Win32 API中文件操作的有关函数来完成对串口的访问。
2,使用现有的 ActiveX控件实现现在一般使用的是微软公司的 MSComm控件,它是作为一个 OCX来提供的。
3,直接嵌入汇编法这种方法只能用在 Windows 98和 Windows 95操作系统下。在嵌入式汇编中,可直接对串口进行操作。
http://qsyang.yeah.net
现代微机原理与接口技术
59
( 1)应用 CreateFile()来打开串口
HANDLE CreateFile(
LPCTSTR lpFileName,// 文件名
DWORD dwDesiredAccess,// 存取模式
DWORD dwShareMode,// 共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes,// NULL
DWORD dwCreationDisposition,// 创建方法
DWORD dwFlagsAndAttributes,// 文件属性和标志
HANDLE hTemplateFile // 临时文件句柄
);
其中,lpFileName指定要打开的串口逻辑名,用字符串表示,
,COM1”表示串口 1,,COM2”表示串口 2。
由于串口是硬件,所以 dwCreationDisposition一般为
OPEN_EXISTING。
8.5.2以文件方式打开串口法
http://qsyang.yeah.net
现代微机原理与接口技术
60
( 2)初始化串口
BOOL SetupComm(
HANDLE hFile,// 通信设备句柄
DWORD dwInQueue,// 输入缓冲区大小
DWORD dwOutQueue // 输出缓冲区大小
);
( 3)关闭窗口
BOOL CloseHandle(
HANDLE hObject // 需要关闭的设备句柄
);
http://qsyang.yeah.net
现代微机原理与接口技术
61
( 4)串口配置
BOOL GetCommState(
HANDLE hFile,// 通信设备句柄
LPDCB lpDCB // 设备控制块
);
BOOL SetCommState(
HANDLE hFile,//通信设备句柄
LPDCB lpDCB //设备控制块
);
http://qsyang.yeah.net
现代微机原理与接口技术
62
http://qsyang.yeah.net
现代微机原理与接口技术
63
( 5)串口属性
BOOL GetCommProperties(
HANDLE hFile,//通信设备句柄
LPCOMMPROP lpCommProp // 通信属性结构
);
http://qsyang.yeah.net
现代微机原理与接口技术
64
( 6)读串口操作
BOOL ReadFile(
HANDLE hFile,// 设备句柄
LPVOID lpBuffer,// 数据缓冲
DWORD nNumberOfBytesToRead,// 读取的字节数
LPDWORD lpNumberOfBytesRead,// 实际读的字节数
LPOVERLAPPED lpOverlapped // overlapped结构
);
( 7)写串口操作
BOOL WriteFile(
HANDLE hFile,// 设备句柄
LPVOID lpBuffer,// 数据缓冲
DWORD nNumberOfBytesToWrite,// 写的字节数
LPDWORD lpNumberOfBytesWrite,// 实际写的字节数
LPOVERLAPPED lpOverlapped // overlapped结构
);
http://qsyang.yeah.net
现代微机原理与接口技术
65
( 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;
http://qsyang.yeah.net
现代微机原理与接口技术
66
异步 I/O操作可以用 GetOverlappedResult()函数来获得结果
BOOL GetOverlappedResult(
HANDLE hFile,// 设备句柄
LPOVERLAPPED lpOverlapped,// overlapped结构
LPDWORD lpNumberOfBytesTransferred,// 传送的字节数
BOOL bWait // 指定函数是否等待挂起的异步操作完成
);
异步 I/O的时候,Windows可以用 WaitForSingleObject()函数来检查事件对象。
DWORD WaitForSingleObject(
HANDLE hHandle,// 对象句柄
DWORD dwMilliseconds // 内部超时时间
);
http://qsyang.yeah.net
现代微机原理与接口技术
67
( 9)超时设置异步(重叠) I/O操作读写串口引入超时结构,在超时时间到的时候,如果读写还没结束,则读写会强行终止。异步时,强行终止的读写动作实际传输的字符数在 OVERLAPPED结构中返回。超时结构如下:
typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout; //两字符间的最大时间间隔
DWORD ReadTotalTimeoutMultiplier; //计算读操作总超时的超时系数
DWORD ReadTotalTimeoutConstant; //计算读操作总超时的超时常数
DWORD WriteTotalTimeoutMultiplier; //计算写操作总超时的超时系数
DWORD WriteTotalTimeoutConstant; //计算写操作总超时的超时常数
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
http://qsyang.yeah.net
现代微机原理与接口技术
68
总超时计算公式是:
总超时=超时系数 × 读或写字节数+超时常数
BOOL SetCommTimeouts(
HANDLE hFile,// 通信设备句柄
LPCOMMTIMEOUTS lpCommTimeouts // 超时结构 );
BOOL GetCommTimeouts(
HANDLE hFile,// 通信设备句柄
LPCOMMTIMEOUTS lpCommTimeouts // 超时结构 );
http://qsyang.yeah.net
现代微机原理与接口技术
69
( 10)通信状态和通信错误如果串口发生奇偶错误等错误的时候,I/O操作会终止。
如果程序要继续执行 I/O操作,就需要调用
ClearCommError()函数,该函数清除错误条件,并确定串口的通信状态:
BOOL ClearCommError(
HANDLE hFile,// 通信设备句柄
LPDWORD lpErrors,// 错误代码
LPCOMSTAT lpStat // communications结构
);
http://qsyang.yeah.net
现代微机原理与接口技术
70
错误代码
http://qsyang.yeah.net
现代微机原理与接口技术
71
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;
http://qsyang.yeah.net
现代微机原理与接口技术
72
( 11)通信事件
Windows有以下的通信事件:
http://qsyang.yeah.net
现代微机原理与接口技术
73
应用程序可用 SetCommMask()函数来建立事件掩模来监视指定通信资源上的事件。
BOOL SetCommMask(
HANDLE hFile,// 通信设备句柄
DWORD dwEvtMask // 事件掩模
);
http://qsyang.yeah.net
现代微机原理与接口技术
74
在用 SetCommMask()指定了有用的事件后,应用程序就调用 WaitCommEvent()函数来等带其中的一个事件发生。
BOOL WaitCommEvent(
HANDLE hFile,// 设备句柄
LPDWORD lpEvtMask,// 事件类型
LPOVERLAPPED lpOverlapped,// overlapped结构
);
http://qsyang.yeah.net
现代微机原理与接口技术
75
举例:
⑴,在中 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();
…… // 处理错误
}
http://qsyang.yeah.net
现代微机原理与接口技术
76
//检测打开串口操作是否成功
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);
http://qsyang.yeah.net
现代微机原理与接口技术
77
DCB dcb ; // 定义数据控制块结构
GetCommState(hCom,&dcb ) ; //读串口原来的参数设置
dcb.BaudRate =9600; // 9600的波特率
dcb.ByteSize =8; // 8位数据位
dcb.Parity = NOPARITY; // 无校验位
dcb.StopBits = ONESTOPBIT ; // 1位停止位
dcb.fBinary = TRUE ; // Win32中此位一定要位 TRUE
dcb.fParity = FALSE; // 不执行奇偶校验
SetCommState(hCom,&dcb ) ; //串口参数配置
// 上述的 COMMTIMEOUTS结构和 DCB都很重要,实际工作中需要仔细选择参数。
http://qsyang.yeah.net
现代微机原理与接口技术
78
⑶ 启动一个辅助线程,用于串口事件的处理。
Win32提供了两种线程,辅助线程 和 用户界面线程
。区别在于:辅助线程没有窗口,所以它没有自己的消息循环。但是辅助线程很容易编程,通常也很有用。
其次,我们使用辅助线程,主要用它来监视串口状态,
看有无数据到达、通信有无错误 ;而主线程则可专心进行数据处理、提供友好的用户界面等重要的工作。
hCommWatchThread= CreateThread(
(LPSECURITY_ATTRIBUTES) NULL,//安全属性
0,//初始化线程栈的大小,缺省为与主线程大小相同
(LPTHREAD_START_ROUTINE)CommWatchProc,//线程的全局函数
GetSafeHwnd(),//此处传入了主框架的句柄
0,
&dwThreadID );
ASSERT(hCommWatchThread!=NULL);
http://qsyang.yeah.net
现代微机原理与接口技术
79
⑷ 为辅助线程写一个全局函数,主要完成数据接收的工作。注意
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 ; //输入缓冲区有多少数据?
http://qsyang.yeah.net
现代微机原理与接口技术
80
if (dwLength > 0) {
BOOL fReadStat ;
fReadStat = ReadFile( hCom,
lpBuffer,
dwLength,
&dwBytesRead,
&READ_OS( npTTYInfo ) ); //读数据
// 注,在 CreareFile()时使用了 FILE_FLAG_OVERLAPPED,现在
ReadFile()也必须使用 LPOVERLAPPED结构,否则,函数会不正确地报告读操作已完成了,
使用 LPOVERLAPPED结构,ReadFile()立即返回,不必等待读操作完成,实现异步通信,此时,ReadFile()返回 FALSE,
GetLastError()返回 ERROR_IO_PENDING,
http://qsyang.yeah.net
现代微机原理与接口技术
81
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); //通知主线程,串口收到数据
}
}
}
http://qsyang.yeah.net
现代微机原理与接口技术
82
⑸,在主线程中放入发送命令。
BOOL fWriteStat ;
char szBuffer[count];
………… //准备好发送的数据,放在 szBuffer[]中
fWriteStat = WriteFile(hCom,
szBuffer,
dwBytesToWrite,
&dwBytesWritten,
&WRITE_OS( npTTYInfo ) ); //写数据
http://qsyang.yeah.net
现代微机原理与接口技术
83
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;
}
......................
http://qsyang.yeah.net
现代微机原理与接口技术
84
8.5.3使用 MSComm控件进行串口编程
⑴,在当前 Project中插入 MSComm控件
http://qsyang.yeah.net
现代微机原理与接口技术
85
http://qsyang.yeah.net
现代微机原理与接口技术
86
http://qsyang.yeah.net
现代微机原理与接口技术
87
http://qsyang.yeah.net
现代微机原理与接口技术
88
http://qsyang.yeah.net
现代微机原理与接口技术
89
http://qsyang.yeah.net
现代微机原理与接口技术
90
http://qsyang.yeah.net
现代微机原理与接口技术
91
http://qsyang.yeah.net
现代微机原理与接口技术
92
http://qsyang.yeah.net
现代微机原理与接口技术
93
http://qsyang.yeah.net
现代微机原理与接口技术
94
http://qsyang.yeah.net
现代微机原理与接口技术
95
⑵,在 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
Control\n");
return -1; // fail to create
}
http://qsyang.yeah.net
现代微机原理与接口技术
96
⑶,初始化串口
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);
http://qsyang.yeah.net
现代微机原理与接口技术
97
⑷,捕捉串口事项。
MSComm控件可以采用轮询或事件驱动的方法从端口获取数据。下面介绍事件驱动方法:有事件(如接收到数据)时通知程序。在程序中需要捕获并处理这些通讯事件。
在 MainFrm.h中:
protected:
afx_msg void OnCommMscomm();
DECLARE_EVENTSINK_MAP()
在 MainFrm.cpp中:
BEGIN_EVENTSINK_MAP(CMainFrame,CFrameWnd )
ON_EVENT(CMainFrame,ID_COMMCTRL,1,OnComm
Mscomm,VTS_NONE) //映射 ActiveX控件事件
END_EVENTSINK_MAP()
http://qsyang.yeah.net
现代微机原理与接口技术
98
⑸,串口读。
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控件
}
http://qsyang.yeah.net
现代微机原理与接口技术
99
⑸,串口写。
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)); // 发送数据
}