51单片机串口通信进阶教程~
喵~亲爱的,今天凉面ya要带你好好探秘一下这段超有意思的51单片机串口通信进阶代码啦!这就仿佛开启一场超酷的单片机冒险,而这段代码就是你手中超厉害的冒险地图呢。
一、整体功能打比方
把51单片机想象成一个机灵的小管家哈。它有个“小电话”,也就是串口,靠着这个“小电话”能和外界愉快交流。外界会给小管家发各种指令,就像布置任务一样。小管家可负责啦,会依据这些指令完成不同工作,像控制小灯的亮灭,或者给外界回个消息啥的。咱们这段代码就是小管家的行动宝典哟。
本程序主要达成了51单片机的串口通信和对外部设备的控制功能。单片机通过串口接收外部设备传来的数据,然后瞅瞅数据的高4位,根据不同情况搞不同操作:
要是高4位是0xA?,小管家就把数据低4位取反,再输出到P0端口,这样前面四个LED灯就会按照后面的值亮起来啦。
要是高4位是0xB?,小管家先把数据低4位左移4位再取反,接着输出到P0端口,后面四个LED灯就会乖乖按后面的值亮咯。
要是高4位是0xC?,小管家就会通过串口给外界送出固定字符串 “The system is running!”,就像在说自己工作得超棒呢。
二、代码详细解读
1. 头文件和变量声明
#include "reg52.h"
//-------------------下方为变量
unsigned char byte;
const char *str = "The system is running!";
#include "reg52.h"
:这就好比是小管家打开了它的百宝箱,里面装着各种常用的工具(寄存器定义),这样它就能使用这些工具来完成任务啦。unsigned char byte
:byte
就像是小管家的一个小本子,用来记录从“小电话”(串口)接收到的信息。const char *str = "The system is running!"
:str
就像是小管家准备好的一段台词,当满足特定条件时,它就会把这段台词通过“小电话”告诉外界。而且const
表示这段台词是固定不能修改的哟。
2. 特殊功能寄存器设置
//-------------------下方为设置
sfr AUXR = 0x8e;
sfr AUXR = 0x8e
:这就像是小管家找到了一个特殊的开关(AUXR
寄存器),并且知道了这个开关的位置(地址 0x8e
),通过操作这个开关可以实现一些特殊的功能呢。
3. Select573
函数
void Select573(unsigned char channel)
{
switch(channel)
{
case 4:
{
P2=(P2&0x1f)|0x80;
break;
}
case 5:
{
P2=(P2&0x1f)|0xa0;
break;
}
case 6:
{
P2=(P2&0x1f)|0xc0;
break;
}
case 7:
{
P2=(P2&0x1f)|0xe0;
break;
}
}
P2=(P2&0x1f);
}
这个函数就像是小管家的一个遥控器,channel
就是遥控器上的不同按钮。按下不同的按钮(传入不同的 channel
值),小管家就能控制不同的设备。比如按下按钮 4,就可以控制某个特定的灯光;按下按钮 5,又能控制另一个设备啦。最后 P2=(P2&0x1f);
就像是小管家把遥控器归位,准备下一次操作。
4. Initsystem
函数
void Initsystem()
{
P0=0xff;
Select573(4);
P0=0x00;
Select573(5);
}
这个函数就像是小管家在开始工作前的准备工作。它先把 P0
端口设置为 0xff
,就像是把一个房间的所有LED都关掉,然后按下遥控器的按钮 4 控制相关设备;接着又把 P0
端口设置为 0x00
,就像把蜂鸣器啥的都关掉,再按下按钮 5 控制设备。这样一系列操作就是为了让系统处于一个初始的稳定状态。
5. UartInit
函数
void UartInit(void) //9600bps@11.0592MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xE0; //设定定时初值
TH1 = 0xFE; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
EA = 1;
ES = 1;
}
这个函数就像是小管家在调试“小电话”(串口)。它设置了“小电话”的通信规则(SCON = 0x50
表示 8 位数据、可变波特率),还调整了时钟和定时器,让“小电话”能以合适的速度和外界交流(波特率为 9600bps)。最后打开了全局中断开关(EA = 1
)和串口中断开关(ES = 1
),这样当“小电话”收到消息时,小管家就能马上知道啦。
6. Sendbyte
函数
void Sendbyte(unsigned char byt)
{
SBUF = byt;
while(TI==0);
TI=0;
}
这个函数就像是小管家通过“小电话”给外界发送消息。SBUF = byt
就是把要发送的消息(byt
)放到“小电话”的发送箱里。while(TI==0);
就像是小管家在等待“小电话”提示消息已经发送出去了(TI
是发送完成标志位)。当消息发送出去后,TI=0
就像是小管家把“小电话”的发送提示重置,准备下一次发送。
7. ServiceUart
函数
void ServiceUart() interrupt 4
{
if(RI==1)
{
RI=0;
byte=SBUF;
}
}
这个函数就像是小管家听到“小电话”响铃(串口接收到消息)后的反应。if(RI==1)
就是判断“小电话”是否响铃了(RI
是接收完成标志位)。如果响铃了,就把“小电话”里的消息(SBUF
)记录到小本子(byte
)上,然后把“小电话”的响铃标志重置(RI = 0
),等待下一次消息。
8. main
函数
void main()
{
P2=(P2&0x1f);//1
UartInit();//3
Initsystem();//2
while(1)
{
if((byte&0xf0)==0xa0)
{
P0=~(byte&0x0f);
Select573(4);
}
if