SBUF 数据缓冲寄存器 这是一个可以直接寻址的串行口专用寄存器。有朋友这样问起过“为何在串行口收发中,都只是利用到同一个寄存器SBUF?而不是收发各用一个寄存器。”实际上SBUF 包含了两个独立的寄存器,一个是发送寄存,另一个是吸收寄存器,但它们都共同利用同一个寻址地址-99H。CPU 在读SBUF 时会指到吸收寄存器,在写时会指到发送寄存器,而且吸收寄存器是双缓冲寄存器,这样可以避免吸收中断没有及时的被相应,数据没有被取走,下一帧数据已到来,而造成的数据重叠问题。发送器则不须要用到双缓冲,一样平常情形下我们在写发送程序时也不必用到发送中断去外理发送数据。操作SBUF寄存器的方法则很大略,只要把这个99H 地址用关键字sfr定义为一个变量就可以对其进行读写操作了,如sfr SBUF = 0x99;当然你也可以用其它的名称。常日在标准的reg51.h 或at89x51.h 等头文件中已对其做了定义,只要用#include 引用就可以了。
SCON 串行口掌握寄存器 常日在芯片或设备中为了监视或掌握接口状态,都会引用到接口掌握寄存器。SCON 便是51 芯片的串行口掌握寄存器。它的寻址地址是98H,是一个可以位寻址的寄存器,浸染便是监视和掌握51 芯片串行口的事情状态。51 芯片的串口可以事情在几个不同的事情模式下,其事情模式的设置便是利用SCON 寄存器。它的各个位的详细定义如下:

SM0 SM1 SM2 REN TB8 RB8 TI RI

SM0、SM1 为串行口事情模式设置位,这样两位可以对应进行四种模式的设置。串行口事情模式设置。
SM0 SM1 模式 功能 波特率
0 0 0 同步移位寄存器 fosc/12
0 1 1 8位UART 可变
1 0 2 9位UART fosc/32 或fosc/64
1 1 3 9位UART 可变
在这里只解释最常用的模式1,其它的模式也就逐一略过,有兴趣的朋友可以找干系的硬件资料查看。表中的fosc 代表振荡器的频率,也便是晶振的频率。UART 为(Universal Asynchronous Receiver)的英文缩写。
SM2 在模式2、模式3 中为多处理机通信使能位。在模式0 中哀求该位为0。
REM 为许可吸收位,REM 置1 时串口许可吸收,置0 时禁止吸收。REM 是由软件置位或清零。如果在一个电路中吸收和发送引脚P3.0,P3.1 都和上位机相连,在软件上有串口中断处理程序,当哀求在处理某个子程序时不许可串口被上位机来的掌握字符产生中断,那么可以在这个子程序的开始处加入REM=0 来禁止吸收,在子程序结束处加入REM=1 再次打开串口吸收。大家也可以用上面的实际源码加入REM=0 来进行实验。
TB8 发送数据位8,在模式2 和3 是要发送的第9 位。该位可以用软件根据须要置位或打消,常日这位在通信协议中做奇偶位,在多处理机通信中这一位则用于表示是地址帧还是数据帧。
RB8 吸收数据位8,在模式2 和3 是已吸收数据的第9 位。该位可能是奇偶位,地址/数据标识位。在模式0 中,RB8 为保留位没有被利用。在模式1 中,当SM2=0,RB8 是已吸收数据的停滞位。
TI 发送中断标识位。在模式0,发送完第8 位数据时,由硬件置位。其它模式中则是在发送停滞位之初,由硬件置位。TI 置位后,申请中断,CPU 相应中断后,发送下一帧数据。在任何模式下,TI 都必须由软件来打消,也便是说在数据写入到SBUF 后,硬件发送数据,中断相应(如中断打开),这时TI=1,表明发送已完成,TI 不会由硬件打消,以是这时必须用软件对其清零。
RI 吸收中断标识位。在模式0,吸收第8 位结束时,由硬件置位。其它模式中则是在吸收停滞位的半中间,由硬件置位。RI=1,申请中断,哀求CPU 取走数据。但在模式1 中,SM2=1时,当未收到有效的停滞位,则不会对RI 置位。同样RI 也必须要靠软件打消。常用的串口模式1 是传输10 个位的,1 位起始位为0,8 位数据位,低位在先,1 位停滞位为1。它的波特率是可变的,其速率是取决于定时器1 或定时器2 的定时值(溢出速率)。AT89C51 和AT89C2051 等51 系列芯片只有两个定时器,定时器0 和定时器1,而定时器2是89C52 系列芯片才有的。
波特率 在利用串口做通讯时,一个很主要的参数便是波特率,只有高下位机的波特率一样时才可以进行正常通讯。波特率是指串行端口每秒内可以传输的波特位数。有一些初学的朋友认为波特率是指每秒传输的字节数,如标准9600 会被误认为每秒种可以传送9600个字节,而实际上它是指每秒可以传送9600 个二进位,而一个字节要8 个二进位,如用串口模式1 来传输那么加上起始位和停滞位,每个数据字节就要占用10 个二进位,9600 波特率用模式1 传输时,每秒传输的字节数是9600÷10=960 字节。51 芯片的串口事情模式0的波特率是固定的,为fosc/12,以一个12M 的晶振来打算,那么它的波特率可以达到1M。模式2 的波特率是固定在fosc/64 或fosc/32,详细用那一种就取决于PCON 寄存器中的SMOD位,如SMOD 为0,波特率为focs/64,SMOD 为1,波特率为focs/32。模式1 和模式3 的波特率是可变的,取决于定时器1 或2(52 芯片)的溢出速率。那么我们怎么去打算这两个模
式的波特率设置时干系的寄存器的值呢?可以用以下的公式去打算。
波特率=(2SMOD÷32)×定时器1 溢出速率
上式中如设置了PCON 寄存器中的SMOD 位为1 时就可以把波特率提升2 倍。常日会利用定时器1 事情在定时器事情模式2 下,这时定时值中的TL1 做为计数,TH1 做为自动重装值 ,这个定时模式下,定时器溢出后,TH1 的值会自动装载到TL1,再次开始计数,这样可以不用软件去干预,使得定时更准确。在这个定时模式2 下定时器1 溢出速率的打算公式如下:
溢出速率=(计数速率)/(256-TH1)
上式中的“计数速率”与所利用的晶体振荡器频率有关,在51 芯片中定时器启动后会在每一个机器周期使定时寄存器TH 的值增加一,一个机器周期即是十二个振荡周期,以是可以得知51 芯片的计数速率为晶体振荡器频率的1/12,一个12M 的晶振用在51 芯片上,那么51 的计数速率就为1M。常日用11.0592M 晶体是为了得到标准的无偏差的波特率,那么为何呢?打算一下就知道了。如我们要得到9600 的波特率,晶振为11.0592M 和12M,定时器1 为模式2,SMOD 设为1,分别看看那所哀求的TH1 为何值。代入公式:
11.0592M
9600=(2÷32)×((11.0592M/12)/(256-TH1))
TH1=250
12M
9600=(2÷32)×((12M/12)/(256-TH1))
TH1≈249.49
上面的打算可以看出利用12M 晶体的时候打算出来的TH1 不为整数,而TH1 的值只能取整数,这样它就会有一定的偏差存在不能产生精确的9600 波特率。当然一定的偏差是可以在利用中被接管的,就算利用11.0592M 的晶体振荡器也会因晶体本身所存在的偏差使波特率产生偏差,但晶体本身的偏差对波特率的影响是十分之小的,可以忽略不计。








