电子工程师提升计划-第8章 接口技术【2.4】

7.5 串行通信口的应用

        单片机利用串行通信口可以和外部设备进行通信,通信形式有单工通信、双工通信和多机通信3种。多机通信情况较为复杂,本节只介绍单工通信和双工通信。

7.5.1 单工通信

        单工通信时,在同一时间内,单片机要么向外部设备发送数据,要么接收外部设备送来的数据,两者不能同时进行。
1.发送数据
        要让单片机发送数据,必须编写发送数据程序,再将程序写入单片机,在程序的控制下,单片机就可以向外部设备发送数据。举例:编写程序,将单片机内40H~48H单元的数据发送给外部设备,要求串行通信口工作在方式2(一帧数据为11位),数据位的第9位作为奇偶校验位。

程序如下:
MOV  SCON,#80H ;将串行通信口设为工作方式2(即让
SM0=1、SM1=0)
MOV  PCON,#80H ;将波特率设为加倍(即为fosc/32)
MOV  R0,# 40H ;将数据40H送入寄存器R0
MOV  R2,#08H ;将数据08H送入寄存器R2
LOOP: MOV  A,@R0  ;将R0中的地址所指单元中的数据送入
累加器A
MOV  C,P  ;将寄存器PSW的奇偶校验位P中的值送入CY位
(进位标志位)
MOV  TB8,C  ;将CY位中的值送入寄存器SCON的TB8位(在发
送数据时,TB8
;位会作为第9位数据发送)
MOV  SBUF,A  ;将A中的数据送入缓冲器SBUF,同时启动串
行通信口开始发送
;SBUF中的数据
WAIT: JBC  TI,CONT ;判断TI位是否为“1”。若TI=1,则
执行标号CONT处的指令,同时
;将TI位清0;若TI=0,则执行下一条指令
SJMP WAIT  ;跳转执行标号WAIT处的指令(本条指令和上一条
指令的功能是等待
;数据发送完成,发送完成后便执行标号CONT处的指令,未完成则
;反复执行上一条指令,直到数据发送完毕将TI位置“1”)
CONT: INC  R0   ;将R0中的数据加1
DJNZ R2,LOOP ;将R2中的数据减1,若不为“0”,则跳转执行
标号LOOP处的指令;
;若为“0”,则结束程序
程序说明:
        标号LOOP至最后一条指令的程序段要反复执行多次,第1次执行程序段时发送40H单元中的数据,当执行到最后一条指令时,R0中的数据为41H,R2中的数据由08H变为07H,然后回跳到标号LOOP处,开始第2次执行程序段,第2次执行时发送41H单元中的程序。如此反复执行多次,最后一次执行程序段时发送48H中的数据,由于执行到最后一条指令时,R2中的数据已减为“0”,不会再产生跳转,而是结束程序。
2.接收数据

        要让单片机通过串行通信口接收数据,需要编写数据接收程序。下面通过一个例子来说明数据接收程序的编写方法。
        举例:编写程序,让单片机能接收外部设备送来的数据,串行通信口设为工作方式 2,要求单片机能判断数据的奇偶校验位是否错误。
程序如下:
MOV  SCON,# 90H ;将串行通信口设为工作方式2,并允许接
收(即让SM0=1、SM1=0、
;REN=1),串行通信口开始等待外部设备向RXD端送入数据
LOOP: JBC  RI,READ ;判断RI位是否为“1”。若RI=1,则
执行标号READ处的指令,同
;时将RI位清0;若RI=0,则执行下一条指令
SJMP LOOP  ;程序跳转执行标号LOOP处的指令
READ: MOV  A,SBUF  ;将SBUF中的数据送入累加器A中
JB  PSW.0,ONE ;判断PSW的第0位(即奇偶校验位P)是否为
“1”。若为“1”,跳
;转执行标号ONE处的指令;若不为“1”,则执行下一条指令
JB  RB8,ERR ;判断寄存器SCON的RB8位是否为“1”。若为
“1”,跳转执行标号ERR
;处的指令;若不为“1”,则执行下一条指令
SJMP RIGHT  ;跳转执行标号RIGHT处的指令
ONE: JNB  RB8,ERR ;判断RB8位是否为“0”。若为
“0”,则执行标号ERR处的指令,否
;则执行下一条指令
RIGHT:…      ;奇偶校验正确应执行的指令,指令可根
据要实现的功能编写,这里
;省略

ERR:…      ;奇偶校验错误应执行的指令
要读懂上面的程序,须了解下面几个要点。
① 串行通信口在接收数据时,会将第9位数据(这里为奇偶校验位)送入寄存器SCON的RB8位中。
② 特殊功能寄存器(PSW)的第0位(P 位)为奇偶校验位,MCS-
51 系列单片机为偶校验,当累加器A中“1”的个数为偶数时,P位为
“0”,否则P位为“1”。
③ 如果接收的8 位数据都没有发生错误,那么寄存器SCON 中RB8位的值(来自帧数据中的奇偶校验位)与寄存器PSW中奇偶校验位P位的值应一致。例如外部设备传送的数据中有3个“1”,那么RB8位应为“1”,含3个“1”的数据送入累加器A中后,会使寄存器PSW的P位也为“1”。也就是说,如果数据未发生错误,P位和RB8位的值应相同;
        如果数据传送时发生错误,其中一位“1”变为“0”,那么传送到累加器A中的数据也只含有2个“1”,寄存器PSW的P位就为“0”,而RB8位仍为“1”(该位与数据中的奇偶校验位一致,并不因数据错误而改变),即数据发生错误, P位和RB8位的值会不同。
程序说明:
        在前面的程序中,“JB PSW.0,ONE”用来判断P位是否为“1”。若为“1”,再执行“JNB RB8, ERR”来判断RB8位是否为“0”。若为“0”,说明P位和RB8位的值不同,则执行校验错误标号ERR处的指令;若不为“0”(即为“1”),P位和RB8位的值相同,则执行校验正确标号RIGHT处的指令。
        在执行“JB PSW.0,ONE”来判断P位是否为“1”时,若P位为“0”,则执行“JB RB8, ERR”来判断RB8位是否为“1”。若为“1”,说明P位和RB8位的值不同,则执行校验错误标号ERR处的指令;若RB8位为“0”,P位和RB8位的值相同,则执行“SJMP RIGHT”而跳转执行校验正确标号RIGHT处的指令。

7.5.2 双工通信

        当给单片机写入发送数据程序时,在发送程序的控制下单片机只能发送数据;当给单片机写入接收数据程序时,单片机只能接收数据。如果希望单片机在发送数据时,一旦外部设备有数据送来马上可以接收数据,则需要给单片机写入双工通信程序。下面通过一个例子来说明双工通信程序的编写方法。

        举例:编写双工通信程序,让单片机能向外部设备发送和接收数据,其中要发送的数据放在首地址为 20H 的单元中,接收的数据放在首地址为 40H 的单元中,要求波特率为2.4 kbaud/s。
        在编写程序时,要确定定时器T1的工作方式并计算初值(也可查表7-2)。现让T1工作在方式2,它的初值X计算公式如下:

十进制数244转换成十六进制数是F4H。
双工通信程序如下:
MAIN: MOV  TMOD,#20H ;将定时器T1设为工作方式2(即让
TMOD的M1=1、M0=0)
MOV  TL1,#0F4H ;设置T1的初值为244
MOV  TH1,#0F4H ;设置T1的重装值为244
SETB TRl   ;将寄存器TCON的TR1位置“1”,启动T1开始计

MOV  SCON,#50H ;将串行通信口设为工作方式1,并允许接收
(即让SM0=0、SM1=1、
;REN=1)
MOV  R0,#20H ;将数据20H送入寄存器R0
MOV  R1,#40H ;将数据40H送入寄存器R1

SETB ES   ;将寄存器IE的ES位置“1”,开启串行通信口中

SETB EA   ;将IE的EA位置“1”,开启总中断
ACALL SOUT  ;跳转执行标号SOUT处的指令
LOOP: SJMP LOOP  ;反复执行本条指令
;以下为中断子程序
ORG  0023H  ;指示下一条指令的地址为0023H
AJMP SRR1  ;跳转执行标号SRR1处的指令
SRR1: JNB  RI,SEND ;判断RI位是否为“0”,为“0”则执
行SEND处的指令,否则执行
;下一条指令
ACALL SIN   ;跳转执行SIN处的指令
SJMP NEXT  ;跳转执行NEXT处的指令
SEND: ACALL SOUT  ;跳转执行SOUT处的指令
NEXT: RETI     ;中断返回(返回至“LOOP: SJMP 
LOOP”指令)
;以下为发送子程序
SOUT: CLR  TI   ;将寄存器SCON的TI位清0
MOV A,@R0   ;将R0中的地址所指单元中的数据送到累加器A

INC  R0   ;将R0中的值加1
MOV  SBUF,A  ;将A中的值送入缓冲器SBUF,同时开始发送
SBUF中的数据
RET     ;子程序返回(返回至“LOOP: SJMP LOOP”指
令)
;以下为接收子程序
SIN:  CLR  RI   ;将SCON的RI位清0
MOV  A,SBUF  ;将接收SBUF中的数据送入A中
MOV  @R1,A  ;将A中的数据送入R1中的地址所指的单元中
INC  R1   ;将R1中的值加1
RET     ;子程序返回(返回至“SJMP NEXT”指令)

第8章 接口技术

        单片机的功能主要是控制,但仅仅一块单片机是不够的,构建一个较完善的控制系统,还需要给单片机增加接口电路。接口电路主要由输入接口和输出接口组成。

8.1 输入接口

        输入接口的功能是将外部设备送来的信号转换成单片机能接收的信号。根据外部设备的不同或输入信号的不同,输入接口可分为开关量输入接口、键盘输入接口和模拟量输入接口等。

8.1.1 开关量输入接口

        用开关给单片机输入的信号称为开关量。开关有断开和闭合两种状态,因此用开关给单片机输入的开关量有“1”和“0”两种。
1.开关输入电路
        图8-1所示是一种简单的开关输入电路。在理想状态下,当按下开关S时,给单片机输入一个“0”(低电平);当S断开时,则给单片机输入一个“1”(高电平)。
        实际上,当按下开关S时,由于手的抖动,S会断开、闭合几次,然后稳定闭合,所以按下开关时,给单片机输入的低电平不稳定,而是高、低电平变化几次(持续 10~20ms),再保持为低电平,同样在S弹起时也有这种情况。开关给单片机输入的信号如图8-2所示。开关抖动给单片机输入不正常的信号后,可能会使单片机产生误动作,应设法消除开关的抖动。

2.开关抖动的消除方法
开关抖动的消除方法通常有两种:硬件防抖和软件防抖。
(1)硬件防抖
硬件防抖的方法很多,图8-3所示是几种常见的硬件防抖电路。

        图8-3(a)所示是RS触发器防抖电路。当开关S与上端接触时,端(置“1”端)为“0”,触发器被置“1”,输出端Q=1;当开关被拨向下端时, 端(置“0”端)为“0”,触发器被置“0”,Q=0,这
时即使手发生抖动,开关又脱离下端(由于上端距离下端较远,开关抖动也不会接触到上端),使 端为“1”,Q端仍保持为“0”不变(因为当 、 均为“0”时,RS触发器状态保持不变),从而消除了抖
动。
        用 RS 触发器可以消除开关抖动,但这种电路较复杂,成本也高,为此可采用图8-3(b)和图8-3(c)所示的RC防抖电路。在图8-3(b)中,当开关S 断开时,+5V 电压经电阻R 对电容C
充电,在电容 C 上充得+5 V电压,当按下开关时,S闭合,由于开关电阻小,电容C通过开关迅速将两端电荷放掉,两端电压迅速降低(接近0 V),单片机输入为低电平,若手发生抖动导致开关短时断开,+5V电压经电阻R对电容C充电,但由于电阻R阻值大,短时间电容C充电很少,电容C两端电压基本不变,单片机输入仍为低电平,从而消除了开关抖动。
        图8-3(c)所示防抖电路的工作原理读者可自己分析。如果采用图8-3(b)和图8-3(c)所示的防抖电路,选择RC的值比较关键,RC元件的值可以用下式计算:

因为抖动时间一般为10~20ms,如果R=10 kΩ,那么C可在2.8~5.6μF中选择,通常选择3.3μF。
(2)软件防抖
        虽然用硬件可以消除抖动,但会使输入电路变复杂且成本提高,对于擅长编程的人,可以通过软件来消除抖动。
        软件防抖的思想是在单片机第1次检测到开关按下时,马上执行延时子程序(需10~20ms),在执行延时子程序时,即使开关发生抖动,单片机也不采取措施,而是待延时子程序执行完后,再检测开关的状态,由于这时开关状态已稳定,所以检测到的是正确的开关输入信号。
        下面以图8-1所示的开关输入电路为例编写一段程序,用于消除开关S按下时产生的抖动。
程序如下:
ORG 0100H   ;让下一条指令从0100H地址开始
START: SETB P2.3   ;将P2.3端口置“1”
JB P2.3,$   ;检测P2.3端口是否为“1”,为“1”则仍执
行本条指令,否则执行下
;一条指令
ACALL DELAY   ;跳转执行标号DELAY处的指令

JB P2.3,$   ;再检测P2.3端口
ACALL CTRL   ;跳转执行标号CTRL处的指令
LJMP START   ;跳转执行标号START处的指令
;以下为延时子程序
DELAY: MOV R7,#40   ;将数据40(该数为十进制数,在汇
编时会自动转换成相应的十六进
;制数)送入寄存器R7中
D1:  MOV R6,#200   ;将数据200送入寄存器R6中
DJNZ R6,$   ;将R6中的值减1,若为“0”则执行下一条指
令,否则再执行本条
;指令,本指令需执行200次才能使R6中的值为“0”
DJNZ R7,D1   ;将R7中的值减1,若为“0”则执行下一条指
令,否则执行标号D1
;处的指令
RET     ;子程序返回(返回至“ACALL DELAY”指令的下
一条指令)
;以下为开关闭合应执行的程序,可根据需要编写,这里省略
CTRL: …

RET     ;子程序返回(返回至“LJMP START”指令)
END
程序说明:
        “JB P2.3,$”指令用于检测开关是否按下,如果开关按下,再执行“ACALL,DELAY”指令调用标号DELAY处的延时子程序。
        在延时子程序中,先给寄存器 R7、R6 置数,然后用“DJNZR6,$”指令对 R6 中的数据进行减1运算,因为只有R6中的数据为“0”,才会执行下一条指令,否则反复执行本条指令,而R6中的数据为200,故本条指令要反复执行200次才能使R6中的数据为“0”。因为本指令为双机器周期指令(也即24时钟周期指令),若单片机的时钟频率为12MHz,则每执行一次需耗时2μs,执行完本条指令共耗时400μs。本条指令执行完后,再用“DJNZ R7,D1”指令将R7中的数据减1,不为“0”跳转执行标号 D1 处的指令,重新给 R6 置数 200,然后又用“DJNZ R6,$”指令减 1来延时400μs,如此重复40次,直到R7中的数据减至“0”,这样一共延时16000μs。然后执行“RET”指令返回到“ACALL DELAY”的下一条“JB P2.3,$”指令,检测P2.3端口的状态,由于这时开关已闭合稳定,P2.3 端口稳定为“0”,于是执行“ACALL CTRL”指令,跳转执行标号 CTRL处的子程序(即开关
闭合后单片机应执行的程序)。
        标号CTRL处的子程序执行完成后,会执行最后的“RET”指令,跳转执行“LJMP START”指令,再跳转执行标号START处的指令,让程序又重新开始运行,检测下一次开关闭合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BinaryStarXin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值