实验室札记
单片机串行口通信的相关设置

🏠 首页 《无线电》杂志 2005年 🔗 第8期 🔗 第40页 分类:电脑·单片机·通信 🔗 张春峰 🔗

串行通信是单片机的一个重要功能。单片机与单片机之间、单片机与电脑PC机之间、单片机与串行器件(如移位寄存器、集成温度传感芯片、时钟芯片等)之间的数据传送往往都是用串行通信的。显然,对串行通信口的初始化及其设置也就至关重要了。笔者曾设计制作过一种“智能床头柜控制器”。它是由一个近乎三棱形的遥控手柄与一个控制盒组成。其实遥控手柄并非真正的“遥控”,而是由一根较长的类同于电话机与其手柄那样的螺旋形连线连起来的。

电路简介

“遥控手柄”上的电路结构如图1所示。MCU的P1.0~P1.3与其P2口构成了4×8的键盘矩阵;MCU的P1.6(MISO)、P1.7(SCK)作为同步移位串行通信口,用以时间、温度等显示的数据通信;MCU的全双工串行通信口(UART)经模拟多路开关/分离器74HC4052切换后,一路与床柜里的“控制盒”连接进行数据传送,使其执行相应的控制操作,及反馈温度等检测信息;另一路传送至由三片74HC164组成的输出扩展口,将指示信号输出,点亮相应的发光二极管。

图1
图1 🔍原图 (567×449)

由于指示灯信息输出与“控制盒”数据通信共用一个UART串口,因而当74HC4052切换连通到“控制盒”时,UART串口被设置为方式2工作模式——这适合单片机与单片机之间的串口通信,因为方式2的波特率是固定的,只要两个单片机所用的晶振频率相同,就可省却产生波特率的定时器资源。当74HC4052切换至发送指示灯信息时,UART串口被设置为方式0的工作模式。这是一个同步移位的工作方式,正好与8位串入/并出移位寄存器74HC164匹配,工作方式0的波特率也是固定的。

问题现象

整机组装完毕后就投入了调试。开机时还看不出有问题,但当按过键盘矩阵中的薄膜开关按键后,显示屏的显示数码就混乱不堪,其他功能似乎也不太正常了。很显然,开始基本是正常的,经按键运作后出现混乱现象了,那多半不是硬件的缺陷所引起的,而往往是因为软件的问题。

由于直观能反映的问题现象是显示屏上显示混乱,所以最先去查看的是与显示相关的程序。但清查后却未发现有可疑之处。

问题探究

问题出在哪里呢?用仿真器对所有可能的怀疑之处进行断点监察,发现串行口中断服务程序被频繁地调用!这就难怪了,可能就是因为串行口不停地中断,于是CPU就忙于串行口中断服务处理,无暇顾及其他,包括用于数据显示的那个串口的正常运作,导致显示的数码混乱。

为什么会引起串行口频繁不停的中断呢?用仿真器对串行口中断部分的程序进一步监察发觉,引起频繁中断是因为串行口不停地在接收数据,每接收一帧数据就中断一次。不停地接收就不停地中断,造成CPU疲于为中断奔命。

原来,程序初始化时,对串行口控制寄存器SCON的设置使串行口处于允许接收状态(SCON.4=1,即允许接收控制位REN=1),并将74HC4052切换连通到“控制盒”。当手柄上的按键有所操作时,软件切换将MCU的串行口与串入/并出移位寄存器组连接,以输送指示灯信息作出相应指示。这时串行口被设置成同步移位的工作方式0,串行数据通过RDX输入或输出,而TDX用于输出移位时钟以作同步信号。在这种方式下,收/发的数据为8位,无起始位及停止位等,因而,一旦满足允许接收的条件—SCON.4=1与SCON.0=0(即接收中断标志位RI=0)同时成立时,它就开始接收。

再者接收中断标志位RI在第8位数据结束时,由CPU 硬件置“1”,申请中断,表示一帧数据接收结束。CPU响应中断时取走数据,并由中断服务软件清“0”RI,准备接收下一帧数据,而RI清为“0”又满足接收条件→串行口又以f\(_{osc}\)/12波特率进行接收→CPU又将RI置“1”→又请求中断→中断服务软件又清“0”RI→串行口又接收……就这样,不断循环,不停中断,导致了以上问题现象的发生。

分析解决

对于以上问题,最好搞清串行口工作在方式0及方式2模式下的特点,来适当设置串行口。方式0前面已经简述了,它是8位数据为一帧的,无起始位、奇偶校验位及停止位的通信格式,也就是它没有“起始”、“停止”等的抑制,所以一旦满足允许接收的条件,它就会不断地接收。而方式2则不同,它是11位数据为一帧的异步通信格式,其中1位起始位、8位数据位,1位可编程的数据位和1位停止位。其接收时,数据从引脚RXD(P3.0)端输入,在REN=1的前提下,并在RXD上检测到1→0的跳变,即“起始位”才开始接收。有了这样“起始”条件的抑制,就不会出现像方式0时那样的问题了(串行口的发送,不管在哪种工作方式下都是一样的: 当执行一条数据写入发送缓冲器SBUF(99H)的指令时,就启动了发送器开始发送)。

有了以上的了解,针对问题现象可这样解决: 只有当按键发送相应的指示灯信息时才把串行口设置为工作方式0,同时使允许接收控制位REN=0; 当发送子程序返回后就马上修改串口设置—将其设置为工作方式2,并使REN=1(其相关的程序流程如图2所示,当然,也可将串口的设置包涵在所调用的子程序中,如图3所示)。这样一来以便与下面的“控制盒”随时通联,二来及时修改串口的设置也就解决了不断接收、不停中断,影响CPU难以正常工作,导致显示混乱的根本问题。

图2
图2 🔍原图 (283×489)

文/张春峰