无论用查询方式还是中断方式进行串行通信编程,在程序初始化时均必须对SCI进行初始化,主要进行波特率设置、通信格式的设置、发送接收数据方式的设置等,本小节给出最基本的用法,以作为HC08系列单片机的串行通信编程入门。下一小节将给出规范的串行通信编程子程序,读者可以直接将其应用于实际的嵌入式应用系统的开发中。
1.SCI初始化
有关口地址的定义已经在头文件GP32.H中给出, SCC1、SCC2、SCC3、SCBR、SCS1、SCS2、SCDR可以直接使用。
对SCI进行初始化,最少由以下三步构成:
第一步:定义波特率。一般选择内部总线时钟为串行通信的时钟源(这个设置在MCU的系统初始化中完成,令系统设置寄存器CONFIG2的SCIBDSRC位为1即可,从学习顺序角度,本书将这部分内容放在第14章,此处默认系统初始化时已经做了这样的设置)。设MCU的系统初始化时已经定义总线频率为fBUS,同时准备定义串行通信波特率,记为Bt。通过选择SCI波特率寄存器SCBR的波特率预分频位SCP(两位)、波特率选择位SCR(三位),以便选择合适的分频系数PD、BD,代入公式Bt=fBUS /(64×PD×BD),使得Bt等于需要的值。当然,从表面上看,由这个公式,已知fBUS、Bt,求PD、BD两个未知数不行。但只要注意到,在介绍SCI波特率寄存器SCBR时,PD、BD取值是有限制的,这样,由fBUS、Bt可以“拼凑”出PD、BD,从而得到波特率寄存器SCBR的设定值。为此,不少书籍还专门列了一个表,给出不同fBUS、Bt下的PD、BD的“拼凑”值。这里举例说明,设总线频率fBUS=2.4576MHz,准备定义波特率Bt=9600,则由公式Bt=fBUS /(64×PD×BD)可以“拼凑”出,PD=1(即SCP1、SCP0=00)、BD=4(即SCR2、SCR1、SCR0=010),波特率寄存器SCBR的未定义位取0,则SCBR的值应为二进制“00000010”,程序如下:
//总线频率fBUS=2.4576MHz,定义波特率Bt=9600
LDA #%00000010
STA SCBR
第二步:写控制字到SCI控制寄存器1(SCC1)。设置是否允许SCI、数据长度、输出格式、选择唤醒方法、是否校验等。例如,设定允许SCI、正常码输出、8位数据、无校验,SCC1取值应为二进制“01000000”,程序如下:
//设置允许SCI,正常码输出、8位数据、无校验
LDA #%01000000
STA SCC1
实际上,这种情况只是令SCC1的SCI允许位(第6位)为1,其它位取默认值。
第三步:写控制字到SCI控制寄存器2(SCC2)。设置是否允许发送与接收、是中断接收还是查询接收等。例如,设置允许发送(TE=1)、允许接收(RE=1)、查询方式收发,SCC2取值应为二进制“00001100”,程序如下:
//设置允许发送、允许接收,查询方式收发
LDA #%00001100
STA SCC2
用查询方式,可以不对SCI控制寄存器3(SCC3)初始化,另外几个寄存器供后面编程使用,不需初始化。
2.发送一个数据与接收一个数据
一般情况下,对SCI的初始化只在程序的初始化部分进行一次,串行通信的基础编程是发送与接收数据。发送数据是通过判断状态寄存器SCS1的第7位(SCTE)进行的,而接收数据是通过判断状态寄存器SCS1的第5位(SCRF)进行的。不论是发送还是接收,均使用SCI数据寄存器SCDR。发送时,将要发送的数据送入SCDR即可,接收时,从SCDR中取出的即是收到的数据。
例如,下面的程序将寄存器A中的数从串行引脚TxD发送出去。通过对状态寄存器SCS1的第7位(SCTE)判断是否可以向数据寄存器SCDR送数,若SCTE=1可以送数,否则必须等待。
//串行发送A中的数
BRCLR 7,SCS1,. //SCS1.7=0? 为0则等待
STA SCDR //SCS1.7=1,可以发送数据
要以查询方式接收一个数据,首先通过状态寄存器SCS1的第5位(SCRF)判断有没有数据可收,若SCRF=1,则有数据可收,下面程序持续等待串行口(实际上是RxD引脚)直到接收到一个数,数据接收后放入寄存器A中:
//查询方式接收一个串行数据,接收的数据放入寄存器A中
BRCLR 5,SCS1,. //SCS1.5=0? 为0则等待
LDA SCDR //SCS1.5=1,可以取出数据


