• 沒有找到結果。

机器人中 UART 的应用

“串口”你已经不陌生了,在前面的章节中,你经常需要在调试终端上显示数据,这些 数据就是机器人的大脑——单片机AT89S52 通过串口向你的电脑传送的。

串口通讯UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是一 种能够把二进制数据按位(bit)传送的通信方式。单片机 AT89S52 拥有 1 个串行通信接口。

该串口可在很宽频率范围内以多种模式工作,其主要功能如下:在输出数据时,把数据进行 并-串转换,即单片机将8位并行数据送到串口输出;在输入数据时,把数据进行串-并转换,

即从串口读入外部串行数据并将其转换为8位并行数据送到单片机。

第2 章的图 2-1 展示了 AT89S52 的各个引脚定义,大部分端口都有第 2 功能,串口就 用到了端口的第2 功能。端口 P3.0(RXD,第 10 号引脚)用来串口接收,端口 P3.1(TXD,

第11 号引脚)用来串口发送。

AT89S52 串口支持双全工模式(同时收发),并具有接收缓冲功能,即在接收第 2 个字 符时,将先前接收到的第1 个字符保存在缓冲区中,只要 CPU 在第 2 个字符接收完成之前 读取了第1 个字符,数据就不会丢失。

AT89S52 提供了两个特殊功能寄存器 SBUF 和 SCON 供软件访问和控制串口。

串口缓冲寄存器SBUF 实际上是 2 个寄存器。写 SBUF 的操作把待发送的数据送入,读 SBUF 的操作把接收到的数据取出。两个操作分别对应于两个不同的寄存器,见图 7-1。

CLK SBUF Q

波特率时钟

(发送)

D

移位寄存器 CLK

SBUF

波特率时钟

(接收)

TXD

(P3.1)

RXD

(P3.0)

AT89S52内部总线 7-1 AT89S52 串口结构简图

串口控制寄存器 SCON 包含串口的状态位和控制位,可进行位操作。控制位决定串口 的工作模式,状态位代表数据发送和接收结束后的状态。可用软件来查询状态位,也可编程 使其触发中断。

串口的工作频率,即波特率,可以是固定的,也可以是变化的。如果使用可变的波特率,

波特率的时钟信号由定时器1 提供,而且必须对其作相应的编程。

串口控制寄存器SCON

AT89S52 串口的工作模式通过设置串口控制寄存器 SCON 来选择,见表 7-1。

7-1 SCON 寄存器简表

符号 描述

SCON.7 SM0 串口模式位0(见表 7-2)

SCON.6 SM1 串口模式位1(见表 7-2)

SCON.5 SM2 串口模式位2。允许在模式 2 和模式 3 下进行多机通信;如果 接收到的第9 位数据为 0,则 RI(接收中断标志)不会被置 1 SCON.4 REN 接收使能位。必须置REN 为 1 才能接收数据

SCON.3 TB8 发送数据的第9 位。在模式 2 和 3 下,此位存放发送数据的第 9 位,利用软件置位或清除

SCON.2 RB8 接收数据的第9 位

SCON.1 TI 发送中断标志。字符发送结束时被置1,由软件清除 SCON.0 RI 接收中断标志。字符接收结束时被置1,由软件清除

7-2 串口工作模式选择

SM0 SM1 模式 描述 波特率

0 0 0 移位寄存器 1/12 fosc 0 1 1 8 位 UART 可变(由定时器1 决定)

1 0 2 9 位 UART 1/64(1/32) fosc 1 1 3 9 位 UART 可变(由定时器1 决定)

什么是波特率?

这是一个衡量通信速度的参数。它表示每秒钟传送的 bit 的个数。例如波特率 9600 表 示每秒钟发送9600 个 bit。

波特率的计算

在模式0 下,波特率是固定的,它的值为单片机的晶振频率(fosc)的 1/12。

在模式2 下,SMOD=0 时,波特率为 1/64 fosc;SMOD=1 时,波特率为 1/32 fosc。其 中,SMOD 是电源控制寄存器 PCON 的第 7 位——波特率倍增位。

在模式1 和模式 3 下,波特率按如下公式计算:

波特率= (2SMOD/32)·(fOSC/12)·[1/(2K-初值)]

在模式1 下,K=8;在模式 3 下,K=9。初值的计算见上章定时/计数器初值计算。

本章使用的是模式1 下的 8 位 UART 串口通信机制。

RS232电平与TTL电平转换

在数字电路中,只存在“1”和“0”两种逻辑状态,也就是“高电平”和“低电平”。

那么,多高的电压为高,多低的电压又是低呢?于是人们分了许多的电平标准,这里向你介 绍的是TTL 和 RS232 这两种标准。

TTL(Tansistor-Transistor Logic),是指三极管-三极管逻辑电路。很多单片机,包括你 所使用的AT89S52 都是用的这种标准。它的逻辑“1”电平是 5V,逻辑“0”电平是 0V。

RS232 标准是 1969 年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及 计算机终端生产厂家共同制定的用于串行通讯的标准。它的逻辑“1”电平是-5V--15V,

逻辑“0”电平是+5V-+15V。

RS232的全称是EIA-RS-232C,其中EIAElectronic Industry Association)代表美国电子 工业协会;RSRecommend Standard)代表推荐标准;232是标识号;C代表RS232的最新 一次修改(1969),在这之前有RS232BRS232A

为了让单片机与PC 机能相互通信,必须让这两种电平相互转换,如图 7-2 所示。

7-2 PC 机与单片机电平转换示意

图中的转换电路部分可采用机器人教学板所使用的电路,或者用专用转换芯片(如 MAX232)来进行,教材并不讲解该转换电路的具体工作原理。但不论是哪种方式,它们要 完成的工作是一致的:PC 机的 RS232 电平进入单片机之前变成 TTL 电平;单片机的 TTL 电平进入PC 机之前变成 RS232 电平。

串口总共由九个信号口组成,但要完成信号的收发,只需用RXD、TXD 和 GND 即可。

连接时需要注意:PC 机的接收端(RXD)与单片机的发送端(TXD)相连;PC 机的发送 端(TXD)与单片机的接收端(RXD)相连;两者的地端(GND)相连。

任务一 编写串口通信程序

本例程是在模式1 方式下进行通讯,设计成一个 uart.h 的头文件,以便机器人在前面章 节中的程序可以方便地调用。串口通讯程序要和串口调试窗口(如图7-3)配合适用。

注意

串口调试窗口的设置,如“串口选择”、“打开串口”等,是针对PC机串口而言,并不

是对单片机串口的设置。

7-3 串口调试界面 例程:uart.h

z 确保 RS232 接口连接好 z 输入、保存程序 uart.h #include <AT89X52.h>

#include <stdio.h>

#define XTAL 11059200

#define baudrate 9600

#define OLEN 8 //串行发送缓冲区大小

unsigned char ostart; //发送缓冲区起始索引 unsigned char oend; //发送缓冲区结束索引 char idata outbuf[OLEN]; //发送缓冲区存储数组

#define ILEN 8 //串行接收缓冲区大小

unsigned char istart; //接收缓冲区起始索引 unsigned char iend; //接收缓冲区结束索引 char idata inbuf[ILEN]; //接收缓冲区存储数组

bit bdata sendfull; //发送缓冲区满标志 bit bdata sendactive; //发送有效标志

/*串行中断服务程序*/

static void com_isr(void) interrupt 4 using 1 {

//---接收数据--- char c;

if(RI) //接收中断置位

{ void putbuf(char c)

{

//printf函数使用putchar输出一个字符 char putchar (char c)

{

if (c=='\n') //增加新的行

{ //getchargets函数使用_getkey char _getkey(void)

{

void com_initialize(void) {

void uart_Init() {

com_initialize();

EA=1; //开总中断,见表6-2

}

uart.h 是如何工作的?

#define XTAL 11059200

#define baudrate 9600

声明你所使用的晶振频率为11.0592MHz 及串口使用的波特率为 9600。

#define OLEN 8

#define ILEN 8

输出和输入的位数均是8 位。

存储器结构

AT89S52 内部存储器由片上ROM 和片上 RAM 组成。片上 RAM 空间由各种用途的存 储器空间组成,包括通用 RAM、可位寻址 RAM(BDATA 区)、寄存器组以及特殊功能寄 存器(SFR)。

另外,AT89S52 有附加的 128 字节的内部 RAM,称为 IDATA 区,地址与 SFR 是重叠 的。这个空间通常用于存放使用频繁的数据。如:

char idata outbuf[OLEN]; //发送缓冲区存储数组 char idata inbuf[ILEN]; //接收缓冲区存储数组

BDATA 区允许软件以“位”为单位访问存储器,这是一项非常有用的功能,仅以一条 指令就可以实现对位进行置位、清除、与、或等操作,简化了设计。

bit bdata sendfull; //发送缓冲区满标志 bit bdata sendactive; //发送有效标志

函数 void com_initialize(void)对串口进行了初始化并设置了波特率 9600,串口将工作在 模式1 下;函数 void uart_Init( )调用了 com_initialize( )并打开了总中断。

参考前一章可知,TMOD |=0x20;让定时/计数器 1 工作在方式 2 下;SCON=0x50;设置 串口工作在模式1;根据波特率公式反推出初值为:

初值=2K-[(2SMOD/32)·(fOSC/12)/波特率]= 28-[(20/32)·(11.0592*106/12)/9600]=253=0XFD 使用函数 void putbuf(char c)写字符到 SBUF 或发送缓冲区;函数 char _getkey(void)从 AT89S52 的串口中读入一个字符,然后等待字符输入;而 char putchar(char c)则是通过调用 putbuf( )输出字符。注意,putchar( )只能输出一个字符,而你用到的 printf 则是通过调用 putchar( )可输出字符串。

函数 static void com_isr(void) interrupt 4 using 1 你不会陌生,它的样子和我们以前讲过 的定时/计数器 0 中断函数相似,它的作用就是进行串口中断服务,接收和发送数据。“4”

你可以在“C:\Program Files\Keil\C51\LIB”目录下找到这两个函数的定义。其中 getkey( ) 函数前面加了下划线“_”,表示该函数并不是标准的 C 库函数。uart.h 头文件修改了这两个 函数用来满足自己的需求。

例程 HelloRoBot.c——printf(“Hello,this is a message from your Robot\n”);

printf( )函数调用 putchar( )函数将第一个字符(字符‘H’)发送到寄存器 SBUF 中;SBUF 满,TI 置位,进入中断处理函数发送该字符;之后,字符‘H’通过串口线到达 PC 机串口,

串口调试窗口进行接收处理,并将字符‘H’在接收区内显示。

如此往复,直到 printf( )函数发送最后一个字符‘\n’——回车命令,将光标置位在下 一行,发送工作才结束。整个发射流程如示意图7-4。

7-4 串口发射流程示意

例程 ControlServoWithComputer.c——scanf("%d",&PulseDuration);

当你在串口调试窗口“发送区”内写入整数1700 并点击“发送”按钮时,调试窗口会 将字符‘6’(整数 1700 在十六进制的表示下为 6A4,转换过程由调试窗口程序完成)通过 串口线发送到单片机的串口。

scanf( )函数通过调用 getkey( )函数从单片机串口处接收字符‘6’,接收缓冲寄存器 SBUF 满,RI 置位,进入中断处理函数,取出字符‘6’;如此循环,直到全部数据接收完。

最后,scanf( )函数再将接收到的数据,即 1700 赋给变量 PulseDuration。

串口接收流程如示意图7-5。

7-5 串口接收流程示意

工程素质和技能归纳

1.51 单片机串口的概念和使用 2.波特率的简介及计算

3.单片机存储器结构 4.串口的工作流程

科学精神的培养

1.查找相关资料,学习串口控制寄存器 SCON 及特殊寄存器 PCON 的功能及用法 2.芯片 MAX232 也具有进行 RS232 与 TTL 电平转换功能,查阅相关资料,掌握它的 用法

3.在头文件 STDIO.H 中包含了我们常用的许多函数,了解这些函数的用法