微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > PC与单片机RS-232串口的通讯和控制

PC与单片机RS-232串口的通讯和控制

时间:12-03 来源:互联网 点击:

上面的程序中除了设置串口的语句和延时语句外,负责向串口发送的语句只有一行,即“printf("helleo world!\n")”。学习过编程的一般都知道,print语句的作用是输出字符串的,但我们如果从单片机的A/D模块上获得了数据想发送到PC,应该怎么做呢?虽然你也可以先将这些数据转换成数字字符串,例如我们从一个8位的A/D模块上获得的数据是个数值从0-255的8位的数值,如果数值是1,那你得先将1这个数值转换成“1”字符对应的代码49(二进制110001,十六进制31H),再用printf语句发送出去。如果值是255,那你得先把它转换成3个字符“2”、“5”、“5”,再用printf发送出去。但这样既复杂又不规范,“1”是一个字符,“2”、“5”、“5”是三个字符,随着数值的不同,发送的数据的字节数据也不同,这样可不行。

我们还是先蹲蹲马步,了解一下单片机串口发送数据的实质:

上图是串口的发送时序示意图,最上面的TX表示的是单片机串口的发送线,,第二根CLK是内部时钟线,最下面的是发送标志信号TI。

我们以最常用的串行方式1,即10位异步通信方式来简单分析一下。它规定了1位起始位、8位数据位和1位停止位。其中第一位(起始位)和最后一位(停止位)是在你设定好串口的方式,打开串口后由芯片内串口模块自动插入的,不用人为加。

当你想通过串口发送数据时,只需要向AT89S52内的一个8位的特殊功能寄存器SBUF(99H)送入一个字节你想要发送给PC的数据,它就会自动连同起始位,数据位,停止位一起产生10位串行的电位信号送出。在第10个脉冲后将TX线的电位拉高,同时将标志位TI置1,告诉自己的程序发送结束。

接收方也是以规定好的相同的波特率时钟脉冲为基准,当某一个脉冲到来后检测到RX线上的电位被拉低,就知道对方开始发送数据了,然后从下一个脉冲起计数并在每个脉冲后检查RX线上的电位,若是高电位便记做1,低电位便记做0,如此得到8个位的数据,然后在第10个脉冲后,检测到RX线上的电位为1就知道这帧数据传送完毕。(注意:单片机的串行发送口(TX)和PC的接收口(RX)是通过串行线直接连接的,所以这两点的信号是相同的)

例如要发送“1”这个字符,代码是49(二进制110001,十六进制31H),串口发送时低位在前,如下图

归纳起来,若想发送数据只要向SBUF送一个字节的数据,然后等TI变为1后,就再发第二个字节依,此类推。

再说说字符和数值的关系,对于电路来说,它不知道什么是字符,什么是数值,只是按高低电位发送一帧帧的电信号。例如00000000代表0(00H),10101010代表170(AAH),11111111代表255(FF),但对于接收方PC就有不同了,大家都知道,电脑下载文本比下载一幅图像的数据量要小得多,原因就是文本只是用一个代码来代表一个将要显示的文字图像,而这个文字的图像数据就预先存在自己的电脑里,就是所说的字库。而你下载一幅图像,则需要每一个阵点的数据都得传送,所以数据量很大。西文也是一样的,也是用代码来代表一个需要显示的西文字符图像,这就是ACSII码。这样用一个字节的数(0-255)的范围就能代表所有的西文字符和常用符号了,例如用数值65(十六进制为41H)代表“A”。用数值49(十六进制为31H)代表“1”,我只要向SBUF里输入值65,PC只要以字符方式接收,就会显示“A”字。如果以数值方式接收,变量的值就是65。这里面也包括有一些非字符的功能控制符号。例如13代表回车,10代表换行。

下面我们就来试试改写一下发送程序:试着用送数值和送字符两种方式发送。同样是“A”“B”“C”“D”四个字符。

#include
#include
void delay(void) //定义一个延时子程序
{
unsigned int i;
for (i=65535;i>0;i--);
}

void main(void) //主程序
{
SCON=0x50; //串口方式1
TMOD=0x20; //定时器1,定时方式为2
PCON=0x80; //设定串口工作方式为1
TCON=0x40; //设定时器1开始计数
TH1=0xfd; //设定波特率为19200
TL1=0xfd; //
TI=1;
TR1=1; //启动定时器
while(1)
{

SBUF=65; //向SBUF内写入65的数值,也就是字符“A”的代码

while(TI==0); //检测TI,当TI=0时,说明还没发送完,就循环等待。

TI=0; //当TI=1时,就把TI的值置0,以便下一组发送。

SBUF=66; //向SBUF送数值66.即字符“B”的代码

while(TI==0);

TI=0;

SBUF=C; //向SBUF送字符“C”

while(TI==0);

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top