蓝桥杯之单片机学习(十二)——串口通信进阶应用案例解析
一、训练内容
在CT107D单片机综合训练平台上,利用51单片机的串行接口与上位机建立传数据输信道。采用8位的UART模式,即模式1, 波特率为9600BPS。数据发送采用查询方式,数据接收采用中断方式。
二、训练要求
- 系统上电初始化之后,关闭蜂鸣器和继电器等无关设备,并向上位机发送字符串“Hello world”,回车换行。
- 上位机通过串口发送单字节命令可以控制下位机的8个LED灯开关。
- 上位机通过串口发送单字节命令可以读取下位机运行信息。
三、代码展示
#include <reg52.h>
sfr AUXR = 0X8e;
typedef unsigned int uint;
typedef unsigned char uchar;
//配置HC138
void SelectHC138(uchar channel)
{
switch(channel)
{
case 4: //LED
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;
case 0: //锁住所有寄存器
P2 = (P2 & 0X1F) | 0X00;
break;
}
}
void Initsys()
{
SelectHC138(5);
P0 = 0X00;//关闭蜂鸣器和继电器
SelectHC138(4);
P0 = 0XFF;//关闭LED
}
//*******************************
void InitUart()
{
TMOD = 0x20;
TH1 = 0XFD; //在12兆下,9600波特率
TL1 = 0XFD;
TR1 = 1;
SCON = 0X50; //模式1
AUXR = 0X00;
ES = 1;
EA = 1;
}
uchar command = 0;
void ServiceUart() interrupt 4
{
if(RI == 1)
{
command = SBUF;
RI = 0;
}
}
void SendByteUart(uchar dat)
{
SBUF = dat;
while(TI == 0);
TI = 0;
}
void SendStringUart(uchar *str)
{
while(*str != '\0')
{
SendByteUart(*str);
str++;
}
}
//*******************************
void Working()
{
SelectHC138(4);
if(command != 0)
{
switch(command & 0xf0) //提取高四位
{
case 0xA0:
P0 = (P0 | 0X0F) & (~command | 0XF0); //保留高4位,反转低四位
command = 0X00;
break;
case 0xB0:
P0 = (P0 | 0XF0) & (~command << 4| 0X0F);
command = 0X00;
break;
case 0xC0:
SendStringUart("The System is Runing……\r\n");
command = 0X00;
break;
}
}
}
void main()
{
Initsys();
InitUart();
SendStringUart("Hello world");
while(1)
{
Working();
}
}
四、一些参考以及注意事项
- 通信规约如下:
注意:对于STC15F2K6052单片机,需要对**AUXR寄存器(0x8e)**配置。