单片机 串口实验 实验五
实验五 串口实验
一、实验目的
1、掌握MCS-51单片机串口通信的原理。
2、掌握MCS-51单片机串口通信程序的设计方法及其过程。
3、掌握MCS-51单片机串口通信的电路应用。
二、实验任务
两片单片机分别接一个按键和两个数码管,通过串口通信,实现单片机1的按键控制单片机2的数码管进行数值累加。本实验要求单片机处理器的晶振频率为11.0592MHz,串口传输波特率为:4800bps。
三、实验原理
AT89C51/51、STC89C51/52标准MCS-51单片机MCU都有能进行异步传输的串行口(UART),且具有一对UART(RX和TX)。UART可以工作在全双工异步方式或半双工同步方式,并且支持多处理器通信。AT89C51/51、STC89C51/52单片机具有一个串口数据发送寄存器(SBUF)和一个串口数据接收寄存器(SBUF),并通过单片机内部定时器T1作为波特率发生器。在使用串口通信时只需要配置好串行口控制寄存器以及定时器T1就可以通过SBUF发送和接收数据。每发送完一帧数据之后处理器内部会自动把串口控制寄存器其中SCON的D1位TI(发送中断标志位)硬件置为1,如果需要传输下一帧数据就需要用户在控制程序中软件清零。每接收完一帧数据之后就处理器内部会自动把串口控制寄存其中SCON的D0位RI(接收中断标志位)硬件置为1,如果需要接收下一帧数据就需要用户在控制程序中软件清零。
AT89C51/51、STC89C51/52单片机具有4种串行口工作方式:方式0(一位寄存器方式),方式1(8位异步通信方式),方式2和方式3(9位异步通信方式)。本实验将选择方式1作为串行口通信方式。定时器T1 TOMD工作在方式2(8位自动重置定时/计数器),波特率计算公式为:
波特率 =(2SMOD/32)·(T1溢出率)
定时器T1的初始值为:
T1的初值=256 - fosc×2SMOD /(12×波特率×32)
本实验要求单片机处理器的晶振频率为11.0592MHz,串口传输波特率为:4800bps。因此,可以根据定时器T1的初始值计算公式计算其初始值。
电路原理图如图5-1所示。
图5-1串口通信实验电路图
注释:上面的原理是课程设计给的模板,不是我写的,仅供参考,如有相同就是参考的,参考书:单片机原理与接口技术实验指导书、单片机原理与接口技术
四、程序流程图
图5-2本次实验程序流程图
五、实验结果及分析总结
本次实验顺利实现了两个单片机使用串口通信,收获了MCS-51单片机串口通信的原理以及串口通信程序的设计方法过程和通信的电路应用。在实验的过程中出现了一个最基本也是最致命的实验错误,绘制的电路图是错误的。
即在完成代码的编写之后,下载至仿真电路,不可以实现串口通信,反复的检查了几次依旧检查不出是代码的问题,最后再一次的检查仿真电路图时,发现是将通信的串口连接错误(即将U1的P3.0接到了U2的P3.0),因此在更改串口的错误连接之后,再一次的进行仿真,才得到的实验结果是正确的。本次实验的代码如图5-4以及第六点程序附录所示。
图5-3本次实验绘制电路图
图5-4关键程序标注
六、程序附录
#include <reg51.h>
#define DUANMA P0 // 数码管段码引脚
#define WEI P2 // 数码管位选引脚
sbit KEY = P1^7; // 按键引脚
unsigned char table[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f }; // 数码管段码表
unsigned char secNum;
unsigned char recDATA;
void delayms(unsigned int ms) {
unsigned int i, j;
for (i = ms; i > 0; i--)
for (j = 120; j > 0; j--);
}
void INIT() {
SCON = 0x50; //串行口工作于方式1
PCON &= 0x7f;
TMOD = 0x20; //T1工作于方式2
TL1 = 0xfa;
TH1 = 0xfa; //波特率是4800
EA = 1;
ES = 1;
TR1 = 1;
}
void checkKey() {
if (KEY == 0) { // 检测按键是否按下
delayms(10); // 延时去抖动
if (KEY == 0) { // 再次检测按键是否按下
secNum++; // 按键加1
SBUF = secNum; // 发送数据给单片机2
while (KEY == 0); // 等待按键释放
}
}
}
void main() {
INIT();
while (1) {
checkKey(); // 检测按键是否按下
WEI = 0xfe;
DUANMA = table[recDATA / 10 % 10];
delayms(10);
WEI = 0xfd;
DUANMA = table[recDATA % 10];
delayms(10);
}
}
void chuankou() interrupt 4 //接收
{
if (RI == 1) {
recDATA = SBUF; // 接收单片机1发送的数据
RI = 0;
}
}
学习过程中,参考资料网上的,如有侵权删。如有需要自行下载源文件,里面code文件是程序代码,还有一个仿真文件。