用51单片机实现串口通信,并对接收到的6个十六进制数与初定十六进制数55 00 03 11 00 ec作比较
这是一个基本的 51 单片机串口接收程序,用于接收六个十六进制数,并将其存储到一个数组中。程序然后与给定的六个十六进制数进行比较,如果匹配,它将向串口发送一个“O”消息,否则发送“E"
#include <reg51.h>
#define BUFFER_SIZE 6
unsigned char buffer[BUFFER_SIZE];
unsigned char expected[] = {0x55, 0x00, 0x03, 0x11, 0x00, 0xec};
void main() {
unsigned char i;
// 初始化串口和时钟,参考上面的,不多写了
// ...
// 循环接收 6 个字节的数据
for (i = 0; i < BUFFER_SIZE; i++) {
while (!RI); // 等待接收到数据
buffer[i] = SBUF; // 读取接收到的数据
RI = 0; // 清除接收中断标志
}
// 比较接收到的数据与预期的数据
for (i = 0; i < BUFFER_SIZE; i++) {
if (buffer[i] != expected[i]) {
// 如果不匹配,向串口发送一个错误消息并退出程序
SBUF = 'E';
while (!TI); // 等待发送完成
TI = 0; // 清除发送中断标志
return;
}
}
// 如果匹配,向串口发送一个成功消息
SBUF = 'O';
while (!TI); // 等待发送完成
TI = 0; // 清除发送中断标志
}
注意,这是一个基本的示例程序。在实际的应用中,你需要根据你的具体需求对其进行修改和优化。例如添加超时机制来避免无限等待串口数据。
参考GPT和自己的思路,可以使用以下代码实现串口通信,并判断接收到的数据是否与目标数据相同:
#include <reg51.h>
#include <stdio.h>
// 串口初始化
void UartInit()
{
SCON = 0x50; // 8位数据位,可变波特率
TMOD &= 0x0F; // 设置定时器1为模式2
TMOD |= 0x20;
TH1 = 0xFD; // 波特率9600
TL1 = 0xFD;
TR1 = 1; // 启动定时器1
ES = 1; // 允许串口中断
EA = 1; // 开启总中断
}
// 串口中断服务函数
void Uart() interrupt 4
{
if (RI) // 接收中断
{
RI = 0; // 清除接收标志位
// 处理接收到的数据
unsigned char data = SBUF; // 读取接收缓冲区
// 比较接收到的数据是否与目标数据相同
if (data == 0x55)
{
// 接收到第一个字节,开始比较后续的5个字节
unsigned char recvData[6];
recvData[0] = data;
int i;
for (i = 1; i < 6; i++)
{
while (!RI); // 等待接收完成
RI = 0; // 清除接收标志位
recvData[i] = SBUF; // 读取接收缓冲区
}
// 比较接收到的数据是否与目标数据相同
if (recvData[1] == 0x00 && recvData[2] == 0x03 && recvData[3] == 0x11 && recvData[4] == 0x00 && recvData[5] == 0xec)
{
// 接收到目标数据,执行相应操作
}
}
}
}
int main()
{
UartInit();
while (1);
return 0;
}
以上代码中,UartInit()函数用于初始化串口,Uart()函数是串口中断服务函数,每当接收到一个字符时,中断服务函数就会被触发。在中断服务函数中,我们通过判断接收到的数据是否为目标数据的第一个字节(0x55),来启动接收并比较后续的5个字节。如果接收到的数据与目标数据相同,则执行相应的操作。在main()函数中,我们仅仅启动了串口,然后进入一个死循环,保证程序不会退出。
目的:用异步通信实现单片机与计算机之间的数据交流
1.波特率
波特率可以衡量数字信号传输的速率,其大小为每秒传输二进制数的位数,单位为:bps。比如:每秒传输300帧数据,一帧数据是十个二进制数,则传输速率就是300x10=3000(bps)。单片机和计算机的传输速率要一致。
2.波特率的设置
计算机的波特率可以在界面上直接调整,那单片机的波特率要怎么设置呢?
我们一般是把T1(定时中断1)作为波特率的发生器,而且利用的是T1的工作方式2。
此时波特率的计算公式为:
解释一下公式内容:
一.SMOD
SMOD属于PCON寄存器,不可位寻址,大家可以把其理解为波特率加倍标志,置0的时候不加倍,置1的时候波特率加倍。
二. fosc
fosc就是单片机的晶振频率,一般是11.0529MHz(还有一种情况是12MHz,但其误差相对较大,一般不予采用)1M=1000,000
三.(256-T初)
T1的工作方式2是八位数据自动装填(八位二进制数的范围是0~255,共256个数),初始值在开始时装入TH1和TL1,工作时只有TH1计数,当TH1溢出时把TL1中的初始值重新赋值给TH1,这样就实现了自动装填。
(256-T初)代表着每次定时器计数的次数。
3.如何设置波特率(假如设置波特率为9600bps)
首先-设置定时器T1的工作方式:编辑TMOD寄存器为TMOD=0X20;使定时器T1处于工作方式2;
然后-计算T1的初始值并装载TH1和TL1,波特率为9600bps时TH1=0XFD、TL1=0XFD;
最后-启动T1:编辑TCON寄存器中的TR1,使TR1=1(打开T1定时器)。通过设置PCON寄存器PCON=0X00设置SMOD=0。
4.如何确定串行口控制
通过编辑SCON寄存器控制串行口
其实主要是控制串行口的工作方式:SM0=0、SM1=1,和打开串行口的允许接收位:REN=1。
5.打开中断
打开总中断和串口通信中断:EA=1、ES=1。
6.SBUF寄存器
前面讲了一大堆铺垫,相信大家都有一个疑问:单片机是怎么发送数据呢?它又是如何接收数据呢? 如果要细讲这其中的传输原理,那会是复杂难懂的,好在单片机的内部硬件自带发送和接收数据的功能,它是通过SBUF寄存器实现的。
SBUF寄存器有俩个,一个是发送寄存器,另一个是接收寄存器(名字都一样),但在逻辑上SBUF只有一个(地址都为99H),物理结构上,这是俩个完全独立的寄存器。如果CPU写SBUF,数据就会被送入发送寄存器准备发送;如果CPU读SBUF,则读入的数据一定来自接收寄存器。
简单来讲:a=SBUF,代表单片机从计算机接收到了数据(接收到的数据自动存在接收寄存器SBUF中)并且从接收寄存器SBUF读取数据并赋给a。SBUF=a,代表单片机要给计算机发送a数据,只需将a赋给发送寄存器SBUF就行,发送寄存器SBUF会自动给计算机发送SBUF中的数据。
下面是其工作图:(RXD是接收引脚,TXD是发送引脚)
7.TI与RI
TI和RI都在SCON寄存器中。
TI是发送中断标志位,当数据发送完成后,TI由硬件置1,TI置1后向CPU提出中断申请,进入中断函数后需要软件置0(TI=0;)
RI是接收中断标志位,当数据接收完成后,RI由硬件置1,RI置1后向CPU提出中断申请,进入中断函数后需要软件置0(RI=0;)
8.串口中断
串口中断函数是
void (函数名无所谓) interrupt 4
{
中断程序;
}
一旦TI或者RI为1就执行中断函数,并且需要在中断函数中将TI、RI重新置0。
1、定义一个足够大的数组作为缓存区,进行接收串口数据(使用串口通信接收函数进行接收数据);
2、在循环中取出接收的数组每一位与需要的内容进行比较,如果符合则在串口助手打印提示内容即可(使用串口通信发送函数)。