第6节 串行通信进一步讨论
推荐给好友
打印
加入收藏
更新于2008-07-25 19:36:53

前面几个章节介绍了串行通信的基本知识、串行通信编程的基本方法。本节将介绍一些串行通信的其他功能和扩展使用。

7.6.1 唤醒功能

关于唤醒功能(Wake-up feature) ,这里作概要介绍。在一个典型的多处理器系统中,软件协议通常在消息的开始判断地址。唤醒功能允许无关的MCU忽略消息的剩余部分,同时禁止这些MCU接收器的标志(和中断)处理,直到数据线返回到空闲状态。SCI接收器可以被一串包含10个(或11个)1的空闲字符串唤醒。发送器软件必须在发送连续消息的间隙提供必须的空闲字符串,并保证空闲字符串不在消息中出现。还有一种将休眠中的MCU唤醒的办法:使MCU接收到的字符的最高位为1。
WAKE=0,RxD上的空闲状态能够清RWU位并唤醒SCI。起始帧(或每个帧)中包含地址信息,所有的接收器计算出该地址信息,与所包含地址相匹配的接收器处理接下来的数据帧。其它接收器置RWU位为1,并返回到就绪状态,直到再次在RxD上出现空闲状态。

WAKE=1,当一个帧的msb位为逻辑1时清RWU位并唤醒SCI。msb位为逻辑1的帧作为地址帧(包含地址信息),所有的接收器计算出该地址信息,与所包含地址相匹配的接收器处理接下来的数据帧。其它接收器置RWU位为1,并返回到就绪状态,直到再次在RxD上出现地址帧。

HC08系列单片机的SCI接收器具有唤醒功能。这个功能在多处理器系统中非常有用,暂时没有工作的微处理器可以处于休眠状态以节省电力,需要工作时再由主机将其唤醒。

1.唤醒
一旦接收器进入睡眠,要响应对它寻址的信息需要一个过程。这就是唤醒过程。有两种方法可以唤醒睡眠中的接收器。一个是只有空闲就唤醒,这就是空闲线唤醒。要选择这种方法,软件需要清除一个寄存器SCC1中的WAKE位。另一个是地址标志唤醒。软件通过设置控制寄存器SCC1中的WAKE位进行选择。
如果唤醒过程是自动的,那么应用程序如何知道接收器已经唤醒?唤醒后,接收缓冲区会变满,会置位状态标志SCRF。这可以通过中断(典型)或轮询接收缓冲区满标志来检测。具体决定取决于配置。

2.空闲线唤醒
如果SCI系统使用空闲线唤醒,就需要建立一个协议。例如,前面几个字节表示想要触发的接收器的地址。接收器软件确认信息是其他接收器时,就会使接收器重新进入睡眠,这通过置位SCC2寄存器的RWU位来实现。接收器会在下一次接收线空闲时再次被唤醒。当信息相对较长(大于10个字节)时可以使用空闲线唤醒。注意,每个信息之间需要用一个空闲时(比一帧时间长1个位)来分隔。
如果应用程序不检测空闲线,就无法得知接收器是否已经被唤醒了。程序可以通过轮询或有配置产生的中断来检测空闲线。在任何一种情况下,它都可以知道什么时候空闲线激活了,什么时候一个字节移入接收移位寄存器了。

3.地址标志唤醒
最高位(MSB)为1的一个字符会唤醒所有使能地址标志唤醒的接收器。这个字符可以看作是一个地址字符。因此,数据字符的MSB应该是0。可以使用下面的协议类型。每个计数器软件在唤醒后读地址字符,并将它与本机地址进行比较。如果匹配,接收器就读其余的信息字节。如果地址不匹配,接收器就可以重新进入睡眠。由于单独的信息每个字节需要1个位,因此在信息较短时,适合使用地址标志唤醒。
空闲线字符由逻辑1组成,没有起始位、停止位和校验位,长度由SCI控制寄存器1(SCICR1) 中的M位决定。当TE的上升沿后,发送初始化后前导符为同步空闲符。若在发送过程中TE位清零,发送结束后TxD输出空闲符;在发送数据期间清零或设置TE位,一个帧发送结束后都要发送空闲符。

7.6.2 协议和控制流问题

从本质上来说,协议是建立连接和传输信息的一套规范。流控制指的是停止数据传输和重新开始数据传输的方法。
应答/不应答(Acknowlege/Not Acknowlege,ACK/NAK)流控制某些协议(如Kermit和Bisynch)使用一个发送者,后者在发送下一组数据前,需要等待接收者对前一组数据的应答。在一组数据发送后,接收者需要检测数据的有效性。如果数据有效,接收者就送出应答信号(ACK)。发送者把ACK信号作为发送下一组数据的许可。如果数据无效,接收者就发送一个不应答(NAK)。发送者将重新发送前一组数据。
XON/XOFF协议。该协议用ASCII字符Ctrl+S($13,称为XOFF)让对方停止发ASCII字符,Ctrl+Q($11,称为XON)让对方继续发送。使用XON/XOFF协议只能传送以ASCII码表的文本文件,不能传送二进制文件。例如,计算机从串口把数据发送到一台打印机,如果打印机缓冲区满了,就必须告诉计算机停止发送,否则数据会丢失。接收者输出一个XOFF信号,告诉发送者停止发送。然后,当接收者就绪时,送出XON信号,告诉发送者恢复发送。

7.6.3 用普通I/O口模拟SCI接发数据

在实际应用场合中,可能需要多个串行数据通信方式,通常MCU中只有1~2个SCI模块,通过专用芯片扩展可以实现多串口的通讯,但这样会使系统复杂,降低可靠性。此时可以用普通I/O口模拟实现SCI功能。

1.硬件条件
从图7-1可以看出,SCI数据传输格式中,以低电平作为起始位,所以用普通I/O口模拟串口时,I/O口需要上拉,保证I/O口通常是高电平状态。I/O口数目可以用2个,此时1个用于接收线,1个用于发送线;但也可以只用1个,发送时,将I/O方向定义为输出,接收时将I/O方向定义为输入。用1个I/O口进行SCI的模拟,显然是半双工方式进行数据通信,但用2个I/O口时,仍然是半双工方式,难于实现全双工。

2.算法描述
用I/O口模拟串行数据通信,主要是实现发送和接收一个字节数据。在发送一字节时,完全依据图7-1的SCI数据格式,在I/O口首先输出低电平,表示开始传输,然后根据所发送的数据字节,输出或高或低的电平信号。在接收一字节时,首先将I/O口设定为输入状态,等待对方的低电平信号,然后每隔一段时间采集I/O口状态,并将I/O口状态作为接收字节的1位数据。

 在发送一个字节时,算法有一个改进之处,在输出I/O上始终设定为低电平,并且通常保持I/O口为输入状态,由于有上拉,所以输出线上的实际电平信号为高,在需要输出低电平信号,才将方向设置为输出。这样操作的好处在于减少输出线上电平的波动。

用SCI模块时,可以很方便地实现波特率设定,用I/O口模拟时,需要通过计算写出精确的位延时程序,实现不同的波特率。假如总线频率是2.4576MHz,实现9600bps的波特率,其位延时计算如下:
9600bps意味着每秒钟传输9600位,则每位传输的时间是:1/9600秒。
总线频率是2.4576MHz,即每个时钟周期的时间是:1/(2.4576×106)秒。
所以传输一位数据时,需要延时的周期数是:


即1位数据的延时周期数为256个。

3.发送一字节子程序
下面给出总线频率为2.4576MHz,以9600bps的波特率模拟串口,8位数据位,1位停止位,无校验方式发送一字节的实例程序。
*------Send1Byte------发送1字节子程序----------------------------*
* 功能:以9600bps发送1字节数据,总线速率:2.4756MHZ *
* 入口:A—需要发送的1字节 *
* 出口:无 *
* 备注:位延时为256个周期 *
*----------------------------------------------------------------*
Send_1Byte:
PSHX
;1) 起始位
BSET 0,DDRA ;A口0脚定义为输出
BCLR 0,PTA ;令A口0脚为低电平
LDX #$55 ;2 cycle 1位的延时 $55=85
DBNZX * ;85*3=255 cycle
;2) 发送数据
LDX #$08 ;2 cycle
Send1Byte0:
PSHX ;2 cycle
RORA ;1 cycle 最低位-->C
BCC Send1Byte1 ;3 cycle 发送位为0
BSET 0,PTA ;4 cycle
BRA Send1Byte2 ;3 cycle
Send1Byte1:
BCLR 0,PTA
BRA Send1Byte2
Send1Byte2:
LDX #$4F ;1位的延时
DBNZX *
PULX
DBNZX Send1Byte0
;3) 停止位
BSET 0,PTA
LDX #85 ;1位的延时
DBNZX *
PULX
RTS

4.接收一字节子程序
下面给出总线频率为2.4576MHz,以9600bps的波特率模拟串口,8位数据位,1位停止位,无校验方式接收一字节的实例程序。
*------RCV_Byte_To_A------接收1字节子程序--------------------------*
* 功能:以9600bps接收1字节数据,总线速率:2.4756MHZ *
* 入口:无 *
* 出口:A *
*------------------------------------------------------------------*
RCV_Byte_To_A:
RCVBeginBit:
;1)等待起始位
BRSET 0,PTA,*
;2)接收起始位
BSR RCV_Bit_To_C
BCS RCVBeginBit ;检验起始位,不为0继续等待
;3)接收数据字节
LDA #$80 ;控制8次循环
RCVNextBit:
BSR RCV_Bit_To_C
RORA ;C-->A[7] ... a[0]-->C
BCC RCVNextBit
BSR RCV_Bit_To_C ;接受结束位,不检验
RTS
*------RCV_Bit_To_C------接收1位子程序-----------------------------*
* 功能:以9600bps接收1位数据,总线速率:2.4756MHZ *
* 入口:无 *
* 出口:C *
* 备注:位延时为256个周期 *
*------------------------------------------------------------------*
RCV_Bit_To_C:
PSHX ;2C
PSHA ;2C
LDA #$17 ;2C
LDX #$17 ;2C
RCV_Bit_0:
BRCLR 0,PTA,RCV_Bit_1 ;5C 影响C位
RCV_Bit_1:
SBC #!0 ;2C A-0-C-->A
DBNZX RCV_Bit_0 ;3C
CMP #!18 ;2C
PULA ;2C
PULX ;2C
RTS ;4C

上述给出的模拟串行收发1字节软件程序是“以软代硬”的一个实例,但“以软代硬”是有代价的,它所需要的代价是占用CPU资源,如果使用SCI模块,收发一字节的过程中是不需要占用CPU资源的。同时,在模拟串行收发1字节过程中,是不允许中断程序的干扰,如果实在需要收发过程中处理中断,很难保证波特率的准确性,如果遇到这种问题,可以用定时器的输入比较和输出捕捉功能来模拟实现串行口。所以在实际使用时要注意,用普通I/O口模拟收发子程序和其它程序之间的协调性,特别是CPU的使用、中断的处理等问题。
练习题
【基础题】

1.什么正逻辑和负逻辑?串行通信使用哪种逻辑?
2.单片机与PC机进行串行通信为什么要进行电平转换?如何进行电平转换?
3.设波特率为9600,使用NRZ格式的8个数据位、没有校验位、1个停止位,传输2K字节的文件最小需要多少时间?
4.简述串行通信收发数据的工作过程。

【实践题】
5.编写一程序,其功能是:以查询方式从串行口等待接收一个字节的数据,收到后,再通过串行口将收到的一个字节的数据发送出去。验证该程序可以通过微机向MCU发送一字节的数据,同时通过串行口接收一个字节的数据,使收到的数据与发出的数据相同。
6.用一种高级语言实现PC方串行数据收发的通用程序。


<<上一节 下一节>>

相关链接


 
关于我们 | 诚邀加盟 | 客户服务 | 相关法律 | 网站地图 | 友情链接 | 服务信箱:service@eefocus.com
© 2006 与非门科技信息咨询(北京)有限公司 All Rights Reserved.