蓝桥杯模拟热身赛

蓝桥杯模拟热身赛

内容来自b站小蜜蜂老师

在这里插入图片描述
在这里插入图片描述

#include "reg52.h"


/********************************************
Date:2022-1-14
Author:小殷同学
Learn From:B 站小蜜蜂老师
*********************************************/

sfr  AUXR = 0x8e;	  //串口辅助寄存器
sbit S5 = P3^2;
sbit S4 = P3^3;
sbit L7 = P0^6;
sbit L8 = P0^7;
unsigned char status_led ; //记录led状态
unsigned char command = 0x00; //记录串口接收数据

//共阳数目管段码
//0-f  0xbf代表 -
unsigned char code SMG_Duan[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
															   0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xbf};

unsigned char min = 0,s = 0,ms = 0; //分 秒 毫秒 变量


//---------------------------------简单延时函数-------------------------
void Delay(unsigned int t)
{
 	while(t--);
}

//-------------------------------74HC138初始化---------------------------
void Init_74HC138(unsigned char n)
{
 	switch(n)
	{
	 	case 4:P2 = P2| 0x1f; P2 = 0x80; break;
		case 5:P2 = P2| 0x1f; P2 = 0xa0; break;
		case 6:P2 = P2| 0x1f; P2 = 0xc0; break;
		case 7:P2 = P2| 0x1f; P2 = 0xe0; break;
		case 0:P2 = P2| 0X1f; P2 = 0x00; break; //所有锁存器都不选择
	}
}

//----------------------------------系统初始化---------------------------
void InitSystem(void)
{
 	 Init_74HC138(5);
	 P0 = 0x00;			 //关闭继电器与蜂鸣器
	 Init_74HC138(4);
	 P0 = 0xff;   //关闭led
}



//---------------------------------数码管安位显示--------------------------
void SMG_DisplayBit(unsigned char pos ,unsigned char dat)
{
 		Init_74HC138(6);
		P0 = 0x01 << pos ;//位选
		Init_74HC138(7);
		P0 = dat;        //段码
}

//----------------------------定时器初始化---------------------------------
void Init_Timer(void)
{
	//定时器0 用于计时 定时器1用于串口 波特率9600 8位
	//定时器0 方式1 定时器1方式二8位自动重装载值
	TMOD = 0x21; 
	TH0 = (65535-50000)/256;
	TL0 = (65535-50000)%256;
	ET0 = 1; //打开定时器0中断
	EA  = 1; //打开总中断
	TR0 = 1; //启动定时器
}

//------------------------------串口初始化-------------------------------
void Init_Uart(void)
{
	//定时器1 允许接收8位
 	TMOD = 0x21;
	TH1 = 0xfd;  //波特率9600
	TL1 = 0xfd;
	TR1 = 1; //启动定时器
	AUXR = 0x00;
	SCON = 0x50;
	ES = 1; //打开串口中断
	EA = 1; //打开总中断  
}


//-----------------------------LED功能函数--------------------------------
void LED_Running(void)
{
 	//先逐个点亮在逐个熄灭
	char i;
	Init_74HC138(4);
	for(i = 0; i < 8;i++)
	{
		 P0 = 0xfe << i;
		 Delay(50000);
	}
	for(i = 0; i < 8; i++)
	{
		P0 = ~(0xfe <<i);
		Delay(50000);
	}
	Init_74HC138(0);
}

//-----------------------------数码管功能函数--------------------------
void SMG_Running(void)
{
	char i;
	for(i = 0; i< 8;i++)
	{
		 Init_74HC138(6);
		 P0 = 0x01 << i;
		 Init_74HC138(7);
		 P0 = 0x00;
		 Delay(50000);
	}
}


//-------------------------------关闭所有数码管----------------------
void SMG_CLOSEALL(unsigned char dat)
{
	 Init_74HC138(6);
	 P0 = 0xff; //选中所有数码管
	 Init_74HC138(7);
	 P0 = dat; //关闭
}
//----------------------------时间显示函数----------------------------
void Time_Display(void)
{
	 SMG_DisplayBit(0,SMG_Duan[min/10]);
	 Delay(100);
	 SMG_DisplayBit(1,SMG_Duan[min%10]);
	 Delay(100);
	 
	 SMG_DisplayBit(2,SMG_Duan[16]);
	 Delay(100);
	 SMG_DisplayBit(3,SMG_Duan[s/10]);
	 Delay(100);
	 SMG_DisplayBit(4,SMG_Duan[s%10]);
	 Delay(100);
	 SMG_DisplayBit(5,SMG_Duan[16]);
	 Delay(100);
	 SMG_DisplayBit(6,SMG_Duan[ms/10]);
	 Delay(100);
	 SMG_DisplayBit(7,SMG_Duan[ms%10]);
	 Delay(100);
	 SMG_CLOSEALL(0xff);
	 Delay(100);	 
}

//-------------------------------------按键功能函数-----------------------


void Key_Scans(void)
{
 	//S5 控制L7 S4控制L8
	if(S5 == 0)
	{
		Delay(20);
		if(S5 == 0)
		{
			while(S5 == 0)
			{
			 	 Time_Display();
			}
			Init_74HC138(4);
		//	status_led = (status_led | 0x40) & (~status_led | 0xbf);
		//	P0 = status_led;
			L7 = 0;
			Init_74HC138(0);
		}
	}

	if(S4 == 0)
	{
		Delay(20);
		if(S4 == 0)
		{
			while(S5 == 0)
			{
			 	 Time_Display();
			}
			Init_74HC138(4);
		//	status_led = (status_led | 0x80) & (~status_led | 0x7f);
			L8 = 0;
		//	P0 = status_led;
			Init_74HC138(0);
		}
	}

}
//----------------------------------串口控制---------------------------------
//发送一个字节
void SendByte(unsigned char dat)
{
 	SBUF = dat;
	while(TI == 0);
	TI = 0;
}

//发送字符串
void SendString(unsigned char *str)
{
 	while(*str != '\0')
	{
		 SendByte(*str++);
	}
}

//数据处理
void Command_Tackle(void)
{
 	if(command != 0x00)
	{
		switch(command & 0xf0)	 //取出命令类型
		{
	 		case 0xa0:			//远程灯光控制命令
				Init_74HC138(4);
				status_led = (P0 | 0x0f) & (~command | 0xf0);
				P0 = status_led;
				Init_74HC138(0);
				command = 0x00;
				break;
			case 0xb0:
				//获取系统时间命令
				
				SendByte((min/10 << 4) | (min %10));
				SendByte((s/10 << 4)   | (s %10));
				SendByte((ms/10 << 4)  | (ms %10));	
				
				SendString("\r\nsuccess\r\n");
				command = 0x00;
				break; 
		}
	}
}



void main(void)
{
	InitSystem();
	LED_Running();
	SMG_Running();
	Init_Timer();
	Init_Uart();
	while(1)
	{
		 Command_Tackle();
		 Time_Display();
		 Key_Scans();
	}

}

//-----------------------------------定时器0中断服务函数--------------------
void Server_Timer0() interrupt 1
{
 	TH0 = (65535-50000)/256;
	TL0 = (65535-50000)%256;
	ms++;
	if(ms == 20) //1s
	{
		ms = 0;
		s++;
		if(s == 60)
		{
			s = 0;
			min++;
			if(min == 12)
			{
				min = 0;
			}
		}
	}
}


void Server_Uart() interrupt 4
{
 	if(RI == 1)
	{
		RI = 0;
		command = SBUF;
	}
}
总结:
学完小蜜蜂老师的视频已经基本掌握了常用的外设程序的编写。
针对上面这个模拟赛来讲,整体难度并不高,可能就是需要大家
注意一些小细节譬如使用串口的时候(头文件为reg52.h)时
需要加入辅助寄存器sfr AUXR = 0x8e 并且在进行初始化的时候
AUXR = 0x00 不能漏掉 。其次的话就是对按键处理的时候我们在等待
按键松开时需要将数码管显示函数也加入其中 避免我们按按键的时候数码管
会间断性显示。


路漫漫其修远兮 ,加油鸭
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小殷学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值