蓝桥杯之单片机学习(十四)——基础技能综合实训案例解析
一、训练任务
在CT107D单片机综合训练平台上,设计程序,用于本地和远程控制现场灯光的开关,并能通过串口远程读取工厂的系统运行时间。
二、训练要求
- 设计系统初始化函数,关闭蜂鸣器和继电器等无关设备。
- 设计设备检测函数,首先检测LED指示灯,从L1~L8依次逐个点亮,再依次逐个熄灭;然后检查数码管,从左到右依次点亮数码管的所有段码,再依次从左到右熄灭。
- 系统从上电开始显示系统运行时间,从00时00分00秒开始,显示格式:
- 八个LED指示灯分为2组: L1-L4为远程控制组,L7-L8为本地控制组。远程控制组的指示灯由上位机通过串口发送命令控制开关,本地控制组的指示灯由独立按键控制开关。按键检测需做去抖动处理,松开有效,按键S5控制L7,按键S4控制L8。
三、通信规约
- 串口工作在8位UART模式,波特率为9600BPS
- 上位机通过串口控制下位机的L1~L4指示灯和读取系统运行时间。
- 控制命令为一一个字节, 高4位为命令类型,低4位为执行参数。
- 控制灯光开关命令中,低4位每1位控制一个LED灯 的开关,无返回值。
- 读取运行时间命令中,低4位保留,各位为0,返回3个字节的时间数据,用16进制的BCD码表示,先发时,再发分,后发秒。如果系统运行的时间为12时24分16秒,收到读取时间命令字后,返回: 0x12 0x24 0x16。
代码展示
#include <reg52.h>
typedef unsigned int uint;
typedef unsigned char uchar;
sfr AUXR = 0X8e;
sbit S5 = P3^2;
sbit S4 = P3^3;
sbit L7 = P0^6;
sbit L8 = P0^7;
uchar code SMG_duanma[18] =
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};//分别是0-9(对应下标),A-F,“-”,“.”
uchar time_005s = 0;
uchar time_s = 0;
uchar time_m = 0;
uchar time_h = 0;
void SMGDisplay();
//配置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;
}
}
//在pos位码上,显示value段码
void DisplaySMG_Bit(uchar pos, uchar value)
{
SelectHC138(6);
P0 = 0X01 << pos;
SelectHC138(7);
P0 = value;
}
void Initsys()
{
SelectHC138(5);
P0 = 0X00;//关闭蜂鸣器和继电器
SelectHC138(4);
P0 = 0XFF;//关闭LED
}
void Delay_CL_CSMG(uint t)
{
while(t--);
while(t--);
}
void CheckSys()
{
//检测LED
uchar i;
SelectHC138(4);
for(i = 1; i <= 8; i++)
{
P0 = 0XFF << i;
Delay_CL_CSMG(60000);
Delay_CL_CSMG(60000);
}
for(i = 1; i <= 8; i++)
{
P0 = ~(0XFF << i);
Delay_CL_CSMG(60000);
Delay_CL_CSMG(60000);
}
//检测数码管
for(i = 0; i < 8; i++)
{
DisplaySMG_Bit(i, 0X00);
Delay_CL_CSMG(60000);
Delay_CL_CSMG(60000);
}
P0 = 0XFF;
}
//*********************************
//本地控制
void Delay_K(uint t)
{
while(t--);
}
void LocalCheck()
{
SelectHC138(4);
if(S4 == 0)
{
Delay_K(100);
if(S4 == 0)
{
L8 = 0;
}
while(S4 == 0)
{
SMGDisplay();
}
L8 = 1;
}
if(S5 == 0)
{
Delay_K(100);
if(S5 == 0)
{
L7 = 0;
}
while(S5 == 0)
{
SMGDisplay();
}
L7 = 1;
}
}
//*********************************
//*********************************
//定时器
void InitTimer0()
{
TMOD = 0X01;
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
ET0 = 1;
EA = 1;
TR0 = 1;
}
void ServiceTimer0() interrupt 1
{
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
time_005s++;
if(time_005s == 20)
{
time_005s = 0;
time_s++;
if(time_s == 60)
{
time_s = 0;
time_m++;
}
if(time_m == 60)
{
time_m = 0;
time_h++;
}
if(time_h == 99)
{
time_h = 0;
}
}
}
//*********************************
//数码管显示
void Delay_SMG(uint t)
{
while(t--);
}
void SMGDisplay()
{
DisplaySMG_Bit(0, SMG_duanma[time_h / 10]);
Delay_SMG(500);
DisplaySMG_Bit(1, SMG_duanma[time_h % 10]);
Delay_SMG(500);
DisplaySMG_Bit(2, SMG_duanma[16]);
Delay_SMG(500);
DisplaySMG_Bit(3, SMG_duanma[time_m / 10]);
Delay_SMG(500);
DisplaySMG_Bit(4, SMG_duanma[time_m % 10]);
Delay_SMG(500);
DisplaySMG_Bit(5, SMG_duanma[16]);
Delay_SMG(500);
DisplaySMG_Bit(6, SMG_duanma[time_s / 10]);
Delay_SMG(500);
DisplaySMG_Bit(7, SMG_duanma[time_s % 10]);
Delay_SMG(500);
P0 = 0XFF;
}
//************************************
//串口通信
uchar command = 0;
void InitUart()
{
TMOD = 0X20;
TH1 = 0XFD;
TL1 = 0XFD;
TR1 = 1;
SCON = 0X50; //模式1
AUXR = 0X00;
ES = 1;
EA = 1;
}
void ServiceUart() interrupt 4
{
if(RI == 1)
{
command = SBUF;
RI = 0;
}
}
void SendByteUart(uchar dat)
{
SBUF = dat;
while(TI == 0);
TI = 0;
}
void UartWorking()
{
if(command != 0)
{
SelectHC138(4);
switch(command & 0XF0)
{
case 0xA0:
P0 = (P0 | 0X0F) & (~command | 0XF0); //保留高4位,反转低四位
command = 0X00;
break;
case 0xB0:
SendByteUart((time_h / 10 << 4) | (time_h % 10));
SendByteUart((time_m / 10 << 4) | (time_m % 10));
SendByteUart((time_s / 10 << 4) | (time_s % 10));
command = 0X00;
break;
}
}
}
//************************************
void main()
{
Initsys();
CheckSys();
InitTimer0();
InitUart();
InitUart();
while(1)
{
LocalCheck();
SMGDisplay();
UartWorking();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理