51单片机串口通信实例

  • 格式:doc
  • 大小:59.00 KB
  • 文档页数:8

下载文档原格式

  / 13
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

51系列单片机串口通信实例教程

单片机的串口通信看起来是很复杂的,主要是因为他用到了更多的寄存器,与前面的知识相比他更具综合能力,写起来考虑的问题自然也变多了.而前面学习过的定时器与中断将是单片机通信的基础.

单片机的中断系统中第4个中断就是串口中断,要进行串口通信首先就要打开CPU 总中断EA,还要打开串口通信中断ES,这是串口通信的前堤,而串口通信也跟计时器一样有很多的模式,因此我们还要设置SCON寄存器来指定采用哪一种方式进行通信,而在通信的过程中,我们还要设定通信的波特率,不然的话,单片机是没办法进行采样的,这样也不会得到正确的结果了.我在实验过程中用到的是1号定时器来设定的波特率,用到了计时器方式2,也就是8位自动重装,这样可以简化编程,它的实现思想就是将常数放入TH,而TL中则是初始化参数,当溢出时,单片机会自动将TH中的常数装入TL中.

再来说说波特率,我们为什么要设定波特率,因为单片机会以16倍波特率的速度进行采样,而在实验中我们用的是10位异步收发方式,因此要将SM0置0,SM1置1.而其中的1 0位有8位数据位,第一位和最后一位是发送数据的起始与结束.采用高的皮特率就不会出错啦.而波特率是有一个公式的:

方式0的波特率 = fosc/12

方式2的波特率 =(2SMOD/64)· fosc

方式1的波特率 =(2SMOD/32)·(T1溢出率)

方式3的波特率 =(2SMOD/32)·(T1溢出率)

T1 溢出率= fosc /{12×[256 -(TH1)]}

根据公式我们很容易就算出当晶振为110592HZ时,要达到9600的波特率,我们只需要将TL1置FDH即可,如下图:

除此之外,你还要将SCON中的REN位置1,不然的话,单片机是不会接收数据的.

还有不要忘了选择定时器的工作方式,设置TMOD为0x20既是工作方式2,8位自动重装定时器.

这样一来,初始批工作算是差不多了.而串口通信分为中断方式,和查询方式,如果你想用查询方式你也不用设置IE寄存器了.

在串口通信中,还有一个很重要的寄存器SBUF,其实也不是一个,是两个,只是它们共用同一个地址,再根据表达式的不同,单片机会自动选择使用哪一个SBUF.

下面是我写的一个例子程序,产生的效果是:向单片机发送任一个0~255之间的数,将会被显

示到数码管上.并且单片机还会自动把刚才传过去的数又发送回来 ,实验过程中用到了几个工具如下:

串口调试助手V2.1.exe,51串口波特率计算器.exe(我已打包在附件中)还有一些必用的就不说了.

C代码

#include

#define uchar unsigned char

#define uint unsigned int

sbit sda = P1^0;

sbit clk = P1^1;

sbit dig1 = P1^2;

sbit dig2 = P1^3;

sbit dig3 = P1^4;

sbit dig4 = P1^5;

uchar r,flag;

uchar code table[]={0x7e,0x0c,0xb6,0x9e,

0xcc,0xda,0xfa,0x0e,

0xfe,0xde,0xef,0xf9,

0x72,0xb8,0xf2,0xe2};

void init();

void write(uchar);

void display(uchar);

void delay(uchar);

void main()

{

init();

while(1)

{

//查询方式通信

//if(RI==1) //RI为1表示收到一字节数据

//{

// RI = 0;//此步必不可少,因为硬件不能将其置0 // r = SBUF;

//}

display(r); //中断方式通信

delay(10);

if(flag==1)

{

flag = 0;

ES = 0;

SBUF = r; //放送数据

while(!TI);

TI = 0;

ES = 1;

}

}

/** 串口中断 **/

void ser() interrupt 4 {

RI = 0;

r = SBUF;

flag = 1;

}

/** 延迟函数 **/

void delay(uchar t) {

uchar x,y;

for(x=t;x>0;x--)

for(y=101;y>0;y--);

}

/** 初始化 **/

void init()

{

dig1 = 1;

dig2 = 1;

dig3 = 1;

dig4 = 1;

r = 0xff;

TMOD = 0x20;

TH1 = 0xfd;

TL1 = 0xfd;

TR1 = 1; //启动定时器1,从而设定了串口通信的波特率SM0 = 0;

SM1 = 1; //设定串口通信方式为十位异步收发器

REN = 1; //打开串口通信

EA = 1;

ES = 1;

}

/** 向数据码管写入一个字节数据 **/

void write(uchar u)

{

uchar i;

for(i=0;i<8;i++)

{

clk = 1;

sda = u&0x80;

clk = 0;

u = u<<1;

}

}

/** 显示一个3位的整数 **/

void display(uchar num)

{