一 实验目的:
1. 掌握8051单片机口异步串口通信工作原理。
2. 学习串口通信的编程控制方法。
3.掌握单片机与电脑互传字符的方法。
二 、实验原理:
C51单片机中断功能的内部结构原理如下图1:
单片机串口通信内部结构图如图2:
按收数据通过P3.0引脚逐个收到,收到8个二进制数后,接收结束标志位RI=1,不能再接收数据。发送数据通过P3.1引脚逐个送出,送完8个二进制数后,发送结束标志位TI=1,不能再发送数据。收、发的8个二进制数总是去查ASCII表。单片机与其他设备通信都是异步工作方式,通信前双方要约定好通信的波特率,单片机波特率是由定时器T1工作在方式2模式确定,常用波特率有4800 bps 、 9600bps。
三、实际编程:
实现一个单片机与另一个单片机通信,要求一个单片机(甲机)做发送任务,另一单片机(乙机)做接收任务,将你姓名的字符由甲机传到乙机。提示:两个单片机之间用两根外接引线联接,一根线接两机的共公地;另一根线一端接甲机的发送引脚P3.1、一端接乙机的接收引脚P3.0。
单片机甲的发送端程序:
#include <REG52.H>
#include <intrins.H>
#include<string.h> //程序中用到strlen()函数
#include "LCD1602.H"
#define uchar unsigned char
#define uint unsigned int
unsigned char i=0;//记录发送数组字符位置
unsigned char Fasongzifu[]= "Made in China\0";//要发送的字母可以任意组合
void main(void)
{
TMOD = 0x20; //设置T1工作方式2,作波特率发生器用
SCON = 0x40; //设定串行口工作在方式1,且串口P3.0引脚对应通道不接收数据,
TL1 = 0xfd; //初值确定波特率为9600bps
TH1 = 0Xfd; //高八位放重置值
PCON = 0x00; //波特率不翻倍,这句也可不写,默认就是不翻倍
TR1 = 1; //启动定时器T1
EA = 1; //打开中断总开关
ES = 1; //打开串口中断信号开关
while(Fasongzifu[i]!='\0')
{
SBUF =Fasongzifu[i];
while(TI==0);//等待缓冲器中数据发送完成
TI = 0; //外力清零发送完成标志TI,为下一个数据发送做好了准备。
}
while(1);
}
void serial_serve(void) interrupt 4 //中断发送处理函数
{
if(TI==1)
{
TI = 0; //外力清零发送完成标志TI,为下一个数据发送做好了准备。
i++;
}
}
单片机乙接收端程序:
// 单机2接受程序
#include <REG52.H>
#include <intrins.H>
#include<string.h> //程序中用到strlen()函数
#include "LCD1602.H"
#define uchar unsigned char
#define uint unsigned int
/*************************************************************/
uchar code as_0[]="MCU:"; //液晶上显示提示语句
uchar st[16]="*** "; //保存串口缓冲器中的数组,初始值为3个*号2个空格
static uchar i=0; //变量统计收到的数据个数。
void initUART(void); // 串口初始化函数
void main(void) //主函数
{
initUART(); //串口初始化
InitLcd(); //初始化1602液晶
DisplayListChar(0,0,as_0);//在1602液晶第一行显示提示字符
while(1)
{
DisplayListChar(0,1,st);//在1602液晶第二行显示电脑发送来的一串字符
}
}
void initUART(void) // 串口初始化函数
{
TMOD=0x20; //设定定时器T1于工作方式2,自动重载
TH1=0xfd; //定时器高八位赋初值,波特率9600
TL1=0xfd; //定时器低八位赋初值,波特率9600
SCON=0x50; //设定串口于工作方式1,一次传送10位数据,其中中间8位有效
TR1=1; //启动定时器
ES=1; //打开串口中断开头
EA=1; //打开中断总开关
}
void serial_serve(void) interrupt 4 //中断接收处理函数
{
if(RI)
{
RI=0;
st[i++]=SBUF; //把电脑串口发送到缓冲区的数据保存到数组
}
}
实验现象演示:
甲机传多个字符到单片机LCD1602显示