【第十四届蓝桥杯单片机组模拟赛1】

第十四届蓝桥杯单片机组模拟赛1

距第十四届蓝桥杯单片机还有不到一个月的时间啦,加油

在这里插入图片描述

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

源码

/*------------------------------第十四届蓝桥杯单片机模式赛--------------------------
@Author:小殷丫
@Date:2023.03.11
-----------------------------------------------------------------------------------*/

#include <STC15F2K60S2.H>
#include "absacc.h"
#include "intrins.h"
#include <stdio.h>


//定义行
sbit H1 = P3^0;
sbit H2 = P3^1;
sbit H3 = P3^2;
sbit H4 = P3^3;

//定义列
sbit L1 = P3^4;
sbit L2 = P3^5;
sbit L3 = P4^2;
sbit L4 = P4^4;

sbit TX = P1^0;
sbit RX = P1^1;


int distance = 0,distance_param = 30;    //实时距离和设置参数
unsigned char L3_flag = 0,L3_Flash = 0;  //LED 相关标志位
char usart_flag = 0,mode = 1;            //串口发送标志和界面模式
char str[24] = {0};                      //存储字符串数据
char led_status = 0xff;                  //LED 控制
//数码管段码
char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
					   0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};


void delay(unsigned int t);                                      //简单延时
void Delay12us();                                                //@12.000MHz 延时12us
void Delay200ms();		                                         //@12.000MHz
void Init_74HC138(unsigned char dat);                            //74HC138锁存器初始化
void SMG_Choice_By_Bit(unsigned char pos,unsigned char dat);     //数码管安位操作
void Controal_ALL_SMG(unsigned char dat);                        //所以数码管控制
void Key_Controal(void);                                         //按键控制
void Display_Distance(void);                                     //实时距离显示
void Display_Distance_Param(void);                               //设置参数距离
void Send_Wave();                                                //产生8个40KHx超声波信号        
void Measure_Distance();	                                     //超声波测距
void initUart(void);		                                     //9600bps@12.000MHz
void SendByte(unsigned char dat);                                //发送单个字符
void SendString(unsigned char *str);                             //字符串发送
void Init_Timer1(void);                                          //定时器1初始化
void Led_Running(void);                                          //led功能函数
void Init_System(void);                                          //上电初始化相关


/*===============================================下面为正式功能实现=========================================*/

void delay(unsigned int t)
{
	while(t--);
}

void Delay200ms()		//@12.000MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 10;
	j = 31;
	k = 147;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
//74HC138初始化
void Init_74HC138(unsigned char dat)
{
	switch(dat)
	{
		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;
		case 0:P2 = (P2 & 0x1f)|0x00;break;
	}
	P2 = (P2 & 0x1f)|0x00;
}

//数码管位选操作
void SMG_Choice_By_Bit(unsigned char pos,unsigned char dat)
{
	P0 = (0x01 << pos);
	Init_74HC138(6);
	P0 = dat;
	Init_74HC138(7);
}


//控制所有数码管
void Controal_ALL_SMG(unsigned char dat)
{
	P0 = 0xff;
	Init_74HC138(6);
	P0 = dat;
	Init_74HC138(7);
}


void Key_Controal(void)
{
	H4 = 0;
	H1 = H2 = H3 = 1;
	if(mode == 2)
	{
		//S12
		if(L2 == 0)
		{
			delay(20);
			if(L2 == 0)
			{
				while(L2 == 0)
				{
					Display_Distance_Param();
				}
				if(mode == 2)
				{				
					distance_param += 10;			
				}
			}
		}
		//S16
	  if(L1 == 0)
		{
			delay(20);
			if(L1 == 0)
			{
				while(L1 == 0)
				{
					Display_Distance_Param();
				}
				if(mode == 2)
				{	
					if(distance_param - 10 < 0)
					{
						distance_param = 0;
					}
					else
					{
						distance_param -= 10;	
					}
				}
			}
		}
	}
	if(mode == 1)
	{
		//S8
		if(L3 == 0)
		{
			delay(20);
			if(L3 == 0)
			{
				while(L3 == 0)
				{
					Display_Distance();
				}
				distance_param = distance ;
			}
		}
	}
	//S4
	if(L4 == 0)
	{
		delay(20);
		if(L4 == 0)
		{
			if(mode == 1)
			{
				while(L4 == 0)
				{
					Display_Distance();
				}
				mode = 2;
			}
			else if(mode == 2)
			{
				while(L4 == 0)
				{
					Display_Distance_Param();
				}
				mode = 1;
			}
		}
	}
	
	//S9 串口发送
	H3 = 0;
	H1 = H2 = H4 = 1;
	if(L3 == 0)
	{
		delay(20);
		if(L3 == 0)
		{
			while(L3 == 0)
			{
				if(mode == 1)
				{
					Display_Distance();
				}
				else
				{
					Display_Distance_Param();
				}
			}
			usart_flag = 1;		
		}
	}
}


void Display_Distance(void)
{
	//U 1000 0011 0xc1
	SMG_Choice_By_Bit(0,0xc1);
	delay(500);
	SMG_Choice_By_Bit(1,smg_data[mode]);
	delay(500);
	SMG_Choice_By_Bit(5, smg_data[distance / 100]);
	delay(500);
	SMG_Choice_By_Bit(6, smg_data[(distance % 100) / 10]);
	delay(500);
	SMG_Choice_By_Bit(7, smg_data[distance % 10]);
	delay(500);
}	


void Display_Distance_Param(void)
{
	//U 1000 0011 0xc1
	SMG_Choice_By_Bit(0,0xc1);
	delay(500);
	SMG_Choice_By_Bit(1,smg_data[mode]);
	delay(500);
	SMG_Choice_By_Bit(5, smg_data[distance_param / 100]);
	delay(500);
	SMG_Choice_By_Bit(6, smg_data[(distance_param /10) % 10]);
	delay(500);
	SMG_Choice_By_Bit(7, smg_data[distance_param % 10]);
	delay(500);
}


void Delay12us()                  //@12.000MHz 延时12us
{
	unsigned char i;
 
	_nop_();
	_nop_();
	i = 33;
	while (--i);
}


void Send_Wave()                 //产生8个40KHx超声波信号
{
	unsigned char i;
	for(i = 0; i < 8; i++)
	{
		TX = 1;
		Delay12us();	
		TX = 0;
		Delay12us();
	}
}


void Measure_Distance()	        //超声波测距
{
	unsigned int time = 0;
	
	TMOD &= 0xf0;	            //定时器0模式0,13位,最大8192个计数脉冲								
	TL0 = 0x00;										
	TH0 = 0x00;		
	
	Send_Wave();		        //发送超声波信号							
	TR0 = 1;            //启动定时器						
	while((RX == 1) && (TF0 == 0));    //等待超声波信号返回或者等到测量超出范围
	TR0 = 0;            //停止定时器				
	
	if(TF0 == 0)	            //正常测量范围							
	{
		time = TH0;									
		time = (time << 8) | TL0;		
		distance = ((time / 10) * 17) / 100 + 3;
		//distance = time * 0.017;
	}
	
	else                        //超出测量范围			
	{
		TF0 = 0;
		distance = 999;
	}
	
}


void initUart(void)		//9600bps@12.000MHz
{
	SCON = 0x50;		
	AUXR |= 0x01;		
	AUXR &= 0xFB;		
	T2L = 0xE6;		
	T2H = 0xFF;		
	AUXR |= 0x10;	
	ES = 1;
	EA = 1;
}


//发送一个字节
void SendByte(unsigned char dat)
{
 	SBUF = dat;
	while(TI == 0); //等待发送完成
	TI = 0;	 //清除标志位

}

//发送一个字符串
void SendString(unsigned char *str)
{
 	//字符串以'\0'为结束标志
	while(*str != '\0')
	{
		SendByte(*str++);
	}
}


//定时器1初始化
void Init_Timer1(void)
{
	TMOD = 0x10;         // 定时器1方式1 16
	TH1 = (65535 - 50000)/256;  //50ms
	TL1 = (65535 - 50000)%256;
	ET1 = 1;
	TR1 = 1;
	EA  = 1;
}

void Led_Running(void)
{
	if(mode == 1)
	{
		//0111 1111  将bit0置0 其他位不变
		led_status &= 0xfe;
	}
	else
	{
		//1000 0000   将bit0置1 其他位不变
		led_status |= 0x01;
	}
	if(mode == 2)
	{
		//1011 1111   将bit2置0 其他位不变
		led_status &= 0xfd;
	}
	else
	{
		//0100 0000   将bit2置1 其他位不变
		led_status |= 0x02;
	}
	
	if(distance_param < distance)
	{
		L3_flag = 1;
		if(L3_Flash)
		{
			//1101 1111  将bit3置0 其他位不变
			led_status &= 0xfb;
			L3_Flash = 0;
		}
		else
		{
			//0100 0000   将bit3置1 其他位不变
			led_status |= 0x04;
		}
	}
	else
	{
		L3_flag = 0;
		//0100 0000   将bit3置1 其他位不变
		led_status |= 0x04;
	}
	P0 = led_status;
	Init_74HC138(4);	
}
//系统初始化
void Init_System(void)
{
	P0 = 0xff;
	Init_74HC138(4);
	P0 = 0x00;
	Init_74HC138(5);
	Controal_ALL_SMG(0xff);
}


void main(void)
{
	Init_System();   //系统初始化
    Init_Timer1();  //定时器1初始化
	initUart();   //串口初始化
	while(1)
	{
		Led_Running();
		Key_Controal();
		Measure_Distance();	  
		switch(mode)
		{
			case 1:Display_Distance();break;
			case 2:Display_Distance_Param();break;
		}
		if(usart_flag)
		{
			usart_flag = 0;
			sprintf(str,"Distance:%dcm\r\n",distance);
		    SendString(str);
			Delay200ms();
		}
		
	}
}


//定时器中断服务函数 50ms进一次中断
void Timer1_Server() interrupt 3
{
	static unsigned char t = 0;
	TH1 = (65535 - 50000)/256;  //50ms
	TL1 = (65535 - 50000)%256;
	if(L3_flag)
	{
		t++;  
		if(t == 4)//200ms
		{
			t = 0;
			L3_Flash = 1;
		}
	}
}
  • 15
    点赞
  • 135
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小殷学长

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

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

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

打赏作者

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

抵扣说明:

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

余额充值