6.1串行接口的一般概念:
单片机与外界进行信息交换称之为通讯。
8051单片机的通讯方式有两种:
并行通讯:数据的各位同时发送或接收。
串行通讯:数据一位一位顺序发送或接收。参看下图:
6.2串行通讯的方式
异步通讯:它用一个起始位表示字符的开始,用停止位表示字符的结束。其每帧的格式如下:
在一帧格式中,先是一个起始位0,然后是8个数据位,规定低位在前,高位在后,接下来是奇偶校验位(可以省略),最后是停止位1。用这种格式表示字符,则字符可以一个接一个地传送。
在异步通讯中,CPU与外设之间必须有两项规定,即字符格式和波特率。字符格式的规定是双方能够在对同一种0和1的串理解成同一种意义。原则上字符格式可以由通讯的双方自由制定,但从通用、方便的角度出发,一般还是使用一些标准为好,如采用ASCII标准。
波特率即数据传送的速率,其定义是每秒钟传送的二进制数的位数。例如,数据传送的速率是120字符/s,而每个字符如上述规定包含10数位,则传送波特率为1200波特。
同步通讯:在同步通讯中,每个字符要用起始位和停止位作为字符开始和结束的标志,占用了时间;所以在数据块传递时,为了提高速度,常去掉这些标志,采用同步传送。由于数据块传递开始要用同步字符来指示,同时要求由时钟来实现发送端与接收端之间的同步,故硬件较复杂。
通讯方向:在串行通讯中,把通讯接口只能发送或接收的单向传送方法叫单工传送;而把数据在甲乙两机之间的双向传递,称之为双工传送。在双工传送方式中又分为半双工传送和全双工传送。半双工传送是两机之间不能同时进行发送和接收,任一时该,只能发或者只能收信息。
l 8051单片机的串行接口结构
8051串行接口是一个可编程的全双工串行通讯接口。它可用作异步通讯方式(UART),与串行传送信息的外部设备相连接,或用于通过标准异步通讯协议进行全双工的8051多机系统也可以通过同步方式,使用TTL或CMOS移位寄存器来扩充I/O口。
8051单片机通过引脚RXD(P3.0,串行数据接收端)和引脚TXD(P3.1,串行数据发送端)与外界通讯。SBUF是串行口缓冲寄存器,包括发送寄存器和接收寄存器。它们有相同名字和地址空间,但不会出现冲突,因为它们两个一个只能被CPU读出数据,一个只能被CPU写入数据。
l 串行口的控制与状态寄存器
串行口控制寄存器SCON
它用于定义串行口的工作方式及实施接收和发送控制。字节地址为98H,其各位定义如下表:
l 串行口的控制与状态寄存器
串行口控制寄存器SCON
它用于定义串行口的工作方式及实施接收和发送控制。字节地址为98H,其各位定义如下表:
D7 D6 D5 D4 D3 D2 D1 D0
SM0 SM1 SM2 REN TB8 RB8 TI RI
SM0、SM1:串行口工作方式选择位,其定义如下:
SM0、SM1 工作方式 功能描述 波特率
0 0 方式0 8位移位寄存器 Fosc/12
0 1 方式1 10位UART 可变
1 0 方式2 11位UART Fosc/64或fosc/32
1 1 方式3 11位UART 可变
其中fosc为晶振频率
SM2:多机通讯控制位。
在方式0时,SM2一定要等于0。在方式1中,当(SM2)=1则只有接收到有效停止位时,RI才置1。在方式2或方式3当(SM2)=1且接收到的第九位数据RB8=0时,RI才置1。
REN:接收允许控制位。
由软件置位以允许接收,又由软件清0来禁止接收。
TB8: 是要发送数据的第9位。
在方式2或方式3中,要发送的第9位数据,根据需要由软件置1或清0。例如,可约定作为奇偶校验位,或在多机通讯中作为区别地址帧或数据帧的标志位。
RB8:接收到的数据的第9位。
在方式0中不使用RB8。在方式1中,若(SM2)=0,RB8为接收到的停止位。在方式2或方式3中,RB8为接收到的第9位数据。
TI: 发送中断标志。
在方式0中,第8位发送结束时,由硬件置位。在其它方式的发送停止位前,由硬件置位。TI置位既表示一帧信息发送结束,同时也是申请中断,可根据需要,用软件查询的方法获得数据已发送完毕的信息,或用中断的方式来发送下一个数据。TI必须用软件清0。
RI: 接收中断标志位。
在方式0,当接收完第8位数据后,由硬件置位。在其它方式中,在接收到停止位的中间时刻由硬件置位(例外情况见于SM2的说明)。RI置位表示一帧数据接收完毕,可用查询的方法获知或者用中断的方法获知。RI也必须用软件清0。
特殊功能寄存器PCON
D7 D6 D5 D4 D3 D2 D1 D0
SMOD GF1 GF0 PD IDL
SMOD: 串行口波特率加倍位。
SMOD=1:方式1和3时,波特率=定时器1溢出率/16;方式2波特率为Fosc/32。
SMOD=0:方式1和3时,波特率=定时器1溢出率/32;方式2波特率为Fosc/64。
GF1GF0:两个通用标志位。
PD,IDL:CHMOS器件的低功耗控制位。
6.4串行口的工作方式
8051单片机的全双工串行口可编程为4种工作方式,现分述如下:
方式0:为移位寄存器输入/输出方式。可外接移位寄存器以扩展I/O口,也可以外接同步输入/输出设备。8位串行数据者是从RXD输入或输出,TXD用来输出同步脉冲。
输出 串行数据从RXD引脚输出,TXD引脚输出移位脉冲。CPU将数据写入发送寄存器时,立即启动发送,将8位数据以fos/12的固定波特率从RXD输出,低位在前,高位在后。发送完一帧数据后,发送中断标志TI由硬件置位。
输入 当串行口以方式0接收时,先置位允许接收控制位REN。此时,RXD为串行数据输入端,TXD仍为同步脉冲移位输出端。当(RI)=0和(REN)=1同时满足时,开始接收。当接收到第8位数据时,将数据移入接收寄存器,并由硬件置位RI。
下面两图分别是方式0扩展输出和输入的接线图。
方式1:为波特率可变的10位异步通讯接口方式。发送或接收一帧信息,包括1个起始位0,8个数据位和1个停止位1。
输出 当CPU执行一条指令将数据写入发送缓冲SBUF时,就启动发送。串行数据从TXD引脚输出,发送完一帧数据后,就由硬件置位TI。
输入 在(REN)=1时,串行口采样RXD引脚,当采样到1至0的跳变时,确认是开始位0,就开始接收一帧数据。只有当(RI)=0且停止位为1或者(SM2)=0时,停止位才进入RB8,8位数据才能进入接收寄存器,并由硬件置位中断标志RI;否则信息丢失。所以在方式1接收时,应先用软件清零RI和SM2标志。
方式2: 为固定波特率的11位UART方式。它比方式1增加了一位可程控为1或0的第9位数据。
输出 发送的串行数据由TXD端输出一帧信息为11位,附加的第9位来自SCON寄存器的TB8位,用软件置位或复位。它可作为多机通讯中地址/数据信息的标志位,也可以作为数据的奇偶校验位。当CPU执行一条数据写入SUBF的指令时,就启动发送器发送。发送一帧信息后,置位中断标志TI。
输入 在(REN)=1时,串行口采样RXD引脚,当采样到1至0的跳变时,确认是开始位0,就开始接收一帧数据。在接收到附加的第9位数据后,当(RI)=0或者(SM2)=0时,第9位数据才进入RB8,8位数据才能进入接收寄存器,并由硬件置位中断标志RI;否则信息丢失。且不置位RI。再过一位时间后,不管上述条件时否满足,接收电路即行复位,并重新检测RXD上从1到0的跳变。
方式3: 为波特率可变的11位UART方式。除波特率外,其余与方式2相同。
6.5波特率选择
如前所述,在串行通讯中,收发双方的数据传送率(波特率)要有一定的约定。在8051串行口的四种工作方式中,方式0和2的波特率是固定的,而方式1和3的波特率是可变的,由定时器T1的溢出率控制。
方式0 :方式0的波特率固定为主振频率的1/12。
方式2 :方式2的波特率由PCON中的选择位SMOD来决定,可由下式表示:
波特率=2的SMOD次方除以64再乘一个fosc,也就是当SMOD=1时,波特率为1/32fosc,当SMOD=0时,波特率为1/64fosc
2SMOD /64* fosc
方式1和方式3:
定时器T1作为波特率发生器,其公式如下:
波特率= 定时器T1溢出率
T1溢出率=
T1计数率/产生溢出所需的周期数
式中T1计数率取决于它工作在定时器状态还是计数器状态。当工作于定时器状态时,T1计数率为fosc/12;当工作于计数器状态时,T1计数率为外部输入频率,此频率应小于fosc/24。产生溢出所需周期与定时器T1的工作方式、T1的预置值有关。
定时器T1工作于方式0:溢出所需周期数=8192-x
定时器T1工作于方式1:溢出所需周期数=65536-x
定时器T1工作于方式2:溢出所需周期数=256-x
因为方式2为自动重装入初值的8位定时器/计数器模式,所以用它来做波特率发生器最恰当。
当时钟频率选用11.0592MHZ时,取易获得标准的波特率,所以很多单片机系统选用这个看起来“怪”的晶振就是这个道理。
下表列出了定时器T1工作于方式2常用波特率及初值。
常用波特率 Fosc(MHZ) SMOD TH1初值
19200 11.0592 1 FDH
9600 11.0592 0 FDH
4800 11.0592 0 FAH
2400 11.0592 0 F4h
1200 11.0592 0 E8h
6.6串口初始化
(1)串行口波特率
通常情况下,使用单片机的串行口,选用的晶振比较固定,一般为6MHz,12MHz,11.0592MHz常用于和计算机通讯,选用的波特率也比较固定,串行口常用的波特率以及相应的设置见下表:
串口工作方式 波特率 Fosc=6MHz Fosc=12MHz Fosc=11.0592MHz
SMOD TMOD TH1 SMOD TMOD TH1 SMOD TMOD TH1
方式0 1M × × ×
方式2 375k187.5k 1 × × 1 × ×0 × ×
方式1或方式3 62500 1 20 FFH
19200 1 20 FDH
9600 0 20 FDH
4800 1 20 F3H 0 20 FAH
2400 1 20 F3H 1 20 F4H 0 20 F4H
1200 1 20 E6H 0 20 E6H 0 20 E8H
600 1 20 CCH 0 20 CCH 0 20 D0H
300 0 20 CCH 0 20 98H 0 20 A0H
137.5 1 20 1DH 0 20 1DH 1 20 2EH
110 0 10 72H 0 10 FEFFH 1 10 FEFFH
(2)初始化步骤
在使用串口之前,应该对它进行编程初始化,主要是设置产生波特率的定时器1、串口控制和中断控制。具体步骤如下:
① 确定定时器1的工作方式――编程TMOD寄存器。
② 计算定时器1的初值――装载TH1,TL1。
③ 启动定时器1――编程TCON中的TR1。
④ 确定串行口的控制――编程SCON。
⑤ 串行口在中断方式时,须开CPU中断和源中断――编程IE寄存器。
6.7硬件与电器图
6.8源代码(ASM&C51)
;发送与接收程序ASM
ORG 0000H
AJMP MAIN
ORG 0023H
AJMP UARTI;转串行中断服务程序
ORG 0030H
MAIN: MOV SP,#70H
MOV 25H,#00H
MOV R0,#30H;30H开始存数
MOV SCON,#50H;串口方式1,REN=1(允许串口接收数据)
MOV TMOD,#20H;定时器1作为波特率发生器,工作模式为2
MOV PCON,#00H;SMOD=0
MOV TH1,#0FDH
MOV TL1,#0FDH
SETB TR1;定时器开始计数
SETB EA
SETB ES
LOOP: LCALL FSAT;发送程序
LJMP LOOP
;串口中断接收程序
UARTI:
JB RI,recive;RI=1,本机接收中断,转接收程序,RI=0继续
CLR TI
SJMP ENDT
recive: CLR RI
MOV A,SBUF
MOV @R0,A
INC 25H;接收字节计数
RE1: INC R0
MOV A,R0
CJNE A,#5FH,ENDT ;超过50H从30H开始
MOV A,#30H
MOV R0,A
ENDT: RETI
;发送1234指令子程序
FSAT: CLR ES
CLR TI;先对TI进行软件复位
MOV A,#31H;将ASCII码A发送到串口去
MOV SBUF,A
JNB TI,$;如果TI为0说明发送没有完成,程序等待
CLR TI;先对TI进行软件复位
MOV A,#32H
MOV SBUF,A
JNB TI,$
CLR TI
MOV A,#33H
MOV SBUF,A
JNB TI,$
CLR TI
MOV A,#34H
MOV SBUF,A
JNB TI,$
SETB ES
lcall delay5ms
lcall delay5ms
lcall delay5ms
lcall delay5ms
lcall delay5ms
delay5ms:
MOV R4,#0FFH
DA222: MOV R5,#0FFH
DJNZ R5,$
DJNZ R4,DA222
RET
END
//(C51)
//这是一个单片机C51串口接收(中断)和发送例程,可以用来测试51单片机的中断接收
#include <reg51.h>
#include <string.h>
#define INBUF_LEN 4 //数据长度
unsigned char inbuf1[INBUF_LEN]={'a','b','4','2'};//发送缓冲区
unsigned char inbuf2[50];//接收缓冲区
unsigned char count3;
void init_serialcomm( void )
{
SCON = 0x50 ; //SCON: serail mode 1, 8-bit UART, enable
ucvr
TMOD |= 0x20 ; //TMOD: timer 1, mode 2, 8-bit reload
PCON |= 0x80 ; //SMOD=1;
TH1 = 0xFA ; //Baud:4800 fosc=11.0592MHz
IE |= 0x90 ; //Enable Serial Interrupt
TR1 = 1 ; // timer 1 run
}
//向串口发送一个字符
void send_char_com( unsigned char ch)
{
SBUF=ch;
while (TI== 0 );
TI= 0 ;
}
//向串口发送一个字符串,strlen为该字符串长度
void send_string_com( unsigned char *str, unsigned int strlen)
{
unsigned int k= 0 ;
do
{
send_char_com(*(str + k));
k++;
} while (k < strlen);
}
//串口接收中断函数
void serial () interrupt 4 using 3
{
if (RI) //RI==开始接收
{
unsigned char ch;
RI = 0 ; //软件RI=0
ch=SBUF;
if (ch> 50 )
{
count3= 0 ;
inbuf2[count3]=ch;
}
else
{
count3++;
inbuf2[count3]=ch;
}
}
}
main()
{
init_serialcomm(); //初始化串口
while ( 1 )
{
send_string_com(inbuf1,INBUF_LEN);
}
}
6.9 总结与其他知识
l 串口通信基本接线方法
目前较为常用的串口有9针串口(DB9)和25针串口(DB25),通信距离较近时(<12m),可以用电缆线直接连接标准RS232端口(RS422、RS485较远),若距离较远,需附加调制解调器(MODEM)。最为简单且常用的是三线制接法,即地、接收数据和发送数据三脚相连,本文只涉及到最为基本的接法,且直接用RS232相连。
1、DB9和DB25的常用信号脚说明
2、RS232C串口通信接线方法(三线制)
首先,串口传输数据只要有接收数据针脚和发送针脚就能实现:同一个串口的接收脚和发送脚直接用线相连,两个串口相连或一个串口和多个串口相连
同一个串口的接收脚和发送脚直接用线相连 对9针串口和25针串口,均是2与3直接相连;
两个不同串口(不论是同一台计算机的两个串口或分别是不同计算机的串口)
上面表格是对微机标准串行口而言的,还有许多非标准设备,如接收GPS数据或电子罗盘数据,只要记住一个原则:接收数据针脚(或线)与发送数据针脚(或线)相连,彼些交叉,信号地对应相接,就能百战百胜。
3、串口调试中要注意的几点:
不同编码机制不能混接,如RS232C不能直接与RS422接口相连,市面上专门的各种转换器卖,必须通过转换器才能连接;
线路焊接要牢固,不然程序没问题,却因为接线问题误事;
串口调试时,准备一个好用的调试工具,如串口调试助手、串口精灵等,有事半功倍之效果;
强烈建议不要带电插拨串口,插拨时至少有一端是断电的,否则串口易损坏。
l 串口连接线的制作方法
在电脑的使用中往往会遇到各种各样的连接线。这些连接线外观上好像都差不多,但内部结构完全不同并且不能混用。如果在使用中这些连接线坏了,往往很多使用者都不知道应该怎么办,下面就给出这些常见的连接线的连线方法以便于修理或查找故障。在介绍之前先对一些市场常用名词做出解释。现在所有的接头都可以分为公头和母头两大类。
公头:泛指所有针式的接头。
母头:泛指所有插槽式的接头。
所有接头的针脚有统一规定,在接头上都印好了的,连接时要注意查看。
在接线时没有提及的针脚都悬空不管。
下面给出串口,并口各针脚功能表以供高级用户维护电缆或接头时使用。
25针串口功能一览
针脚 功能
2 发送数据(TXD)
3 接收数据 (RXD)
4 发送请求 (RTS)
5 发送清除 (CTS)
6 数据准备好 (DSR)
7 信号地 (GND)
8 载波检测 (DCD)
20 数据终端准备好 (DTR)
22 振铃指示 (RI)
9针串口功能一览表
针脚 功能
1 载波检测 (DCD)
2 接收数据 (RXD)
3 发送数据(TXD)
4 数据终端准备好 (DTR)
5 信号地 (GND)
6 数据准备好 (DSR)
7 发送请求 (RTS)
8 发送清除 (CTS)
9 振铃指示 (RI)
串口联机线的连接方法
串口联机线主要用于直接把两台电脑的com口连接。比较早一点的AT架构的电脑的串口有为9针,和25针两种,现在的ATX架构的电脑两个串口全部是9针。于是联机线就分为3种(9针对9针串口联机线,9针对25针串口联机线,25针对25针串口联机线)这些直接电缆连接线可以互换的连线方法如下表:
串口连机线一览
9针对9针串口连接
9针母头 9针母头
2 —— 3
3 —— 2
4 —— 6
5 —— 5
6 —— 4
7 —— 8
8 —— 7
25针对25针串口连接
25针母头 25针母头
2 —— 3
3 —— 2
4 —— 5
5 —— 4
6 —— 20
7 —— 7
20 —— 6
9针对25针串口连接
9针母头 25针母头
2 —— 2
3 —— 3
4 —— 6
5 —— 7
6 —— 20
7 —— 5
8 —— 4
串口转接线
这种转接线适用于9针串口和25针串口的转换。
首先,根据需要(9转25或25转9)选择两个转接头。选择方法如下:
9针转25针(9针公头,25针母头)。25针转9针(25针公头,9针母头)。然后使用尽量短的带屏蔽的多芯连接线。连接方法如下表
串口转接线一览
9针接头 25针接头
1 —— 8
2 —— 3
3 —— 2
4 —— 20
5 —— 7
6 —— 6
7 —— 4
8 —— 5
9 —— 22
6.10 如何通过DG3000实现串口通讯?
由于DG3000仿真过程中占用了串口,所以是不能通过硬件进行仿真。不过我们完全可以通过模拟软件来观察结果。方法如下:
例如:我们打开汇编程序界面如下:
然后,点击Target 1 右键,选择:
跳出下面窗口,我们选择如下,然后确定:
然后点击编译:
再点击开始仿真:
出现下面界面:
然后,我们打开:
调出Serial Window #1 ,界面如下:
然后全速运行程序 :
可以观察 Serial Window #1,显示如下:
其中1234就是串口发出的数据。
同样调试C程序也是一个原理,你可以试试。有问题可以咨询我们技术部。我们后面还有综合试验来试验串口通讯。
|