1、功能描述
有开发板A和开发板B,通过串口,实现开发板A的按键,控制开发板B的LED亮灭。
2、实验原理
1.串口通信(UART)
串口通信是一种异步通信方式,它允许单片机通过两条线(发送线TX和接收线RX)进行数据传输。在51单片机中,串口通信是通过两个主要寄存器(SCON、SMO/SM1)和中断(RI、TI)来控制的。
. scON(串行控制寄存器)︰用于设置串口的工作模式。.SMO/SM1(多机通信控制位):用于选择串口的工作模式。
·RI(接收中断标志位)︰当接收到数据时自动置位。
· T(发送中断标志位)︰当数据发送完成后自动置位。
2.定时器作为波特率发生器
波特率,即每秒传输的比特数,是串口通信的重要参数。在51单片机中,可以使用定时器的溢出率来产生波特率。
TMOD(定时器模式寄存器)︰设置定时器的工作模式。
TH1/TL1(定时器高八位/低八位)︰设置定时器的计数初值,影响定时器溢出的时间间隔。
3.中断系统
51单片机的中断系统允许程序在特定事件发生时自动跳转到特定的服务程序。
· EA(总中断使能位):全局中断使能。. ES(串行中断使能位)︰串口中断使能。
· Rl(接收中断标志位)∶接收到数据时自动置位。
. T(发送中断标志位)︰发送完数据时自动置位。4.按键检测与消抖
在开发板A上,通过检测按键的电平变化来触发数据发送。由于机械按键在按下时可能会产生多次电平跳变(抖动),通常需要消抖处理。
·软件消抖:通过检测按键状态多次并延时,确认按键确实被按下。
5.数据发送与接收
开发板A在检测到按键按下后,将数据(如0x01)通过串口发送出去。开发板B通过串口接收到数据后,根据数据内容控制LED的亮灭。
.SBUF(串行数据缓冲寄存器)︰用于存储待发送或已接收的数据。6.LED控制
在开发板B上,根据接收到的数据来控制LED的状态。这是通过位操作来实现的,即通过改变LED对应的端口位的电平来控制LED的亮灭。
3、编程思路
开发板A(发送端)∶
1.初始化:设置定时器模式和计数初值,启动定时器,配置串口工作模式,启用接收和总中断。
2.按键检测:通过检测按键(P31)的状态,来判断是否被按下。
3.数据发送:如果检测到按键被按下,并且是首次检测到(通过key_state变量控制),则发送数据0x01到开发板B。
4.发送完成:等待发送标志位TI(传输中断标志位)置位,然后清除TI。
开发板B(接收端)∶
1.初始化:与开发板A相同,设置定时器和串口参数。
⒉.接收数据∶在串口接收中断服务程序中,读取接收到的数据并存入recv_data变量。3.LED控制:在主循环中,如果接收到的数据是ox01,则控制LED灯亮灭。
1、定时器初始化:设置定时器1为8位自动重装方式(方式2),并设置计数初值,以产生所需的波特率。
2.串口配置:设置串口为模式1(可变波特率),并启动接收功能。
3.中断配置:开启总中断和串口中断,以响应按键和串口接收事件。
4.按键处理:在开发板A上,通过检测按键状态,并在按下时发送数据。
5.数据发送:使用SBUF寄存器发送数据,并等待发送完成。
6.接收中断:在开发板B上,通过串口接收中断服务程序读取数据。
7.LED控制:根据接收到的数据控制LED灯的亮灭状态。
4、代码
开发板A:
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit key = P3^1;
void main() {
uchar key_state = 0;
uchar send_data = 0;
TMOD = 0x20;
TH1 = 0xFD;
TL1 = TH1;
TR1 = 1;
SM0 = 0;
SM1 = 1;
REN = 1;
EA = 1;
ES = 1;
while (1) {
if (key == 0) {
if (key_state == 0) {
key_state = 1;
send_data = 0x01;
SBUF = send_data;
while (!TI);
TI = 0;
}
} else {
key_state = 0;
}
}
}
void serial() interrupt 4 {
if (RI) {
RI = 0;
}
}
开发板B:
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit led = P2^1;
void main() {
uchar recv_data = 0;
TMOD = 0x20;
TH1 = 0xFD;
TL1 = TH1;
TR1 = 1;
SM0 = 0;
SM1 = 1;
REN = 1;
EA = 1;
ES = 1;
while (1) {
if (recv_data == 0x01) {
led = ~led;
}
}
}
void serial() interrupt 4 {
if (RI) {
RI = 0;
recv_data = SBUF;
}
}