【第十四届蓝桥杯单片机模拟题3】

【第十四届蓝桥杯单片机模拟题3】

下面这套题应该也是第十四届的模拟题,具体是那套不清楚了,同样也有串口相关的功能,这一届考串口不出意外应该是必不可少了,对应串口的接收和发送还不同会的小伙伴可以看看哦,(同样也欢迎指出错误以及分享更好的实现方式)。

若有帮助请给小殷一个关注和赞赞吧,你们的支持也是我前进的重要动力鸭

在这里插入图片描述

下面是完成的工程链接,有需自提哈
链接:https://pan.baidu.com/s/1c-iNZTHcy8PQcbrkgfPgPw?pwd=i55a
提取码:i55a
–来自百度网盘超级会员V5的分享

距第十四届蓝桥杯还剩最后两天时间,祝各位小伙伴都可以取得好成绩,加油鸭 别忘记点赞关注哦

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

在这里插入图片描述

注意:

在题目中有串口和矩阵键盘的功能,注意避开串口引脚的操作哦,不然串口发送会有问题,数码管也会受到影响

#include <STC15F2K60S2.H>
#include "iic.h"
#include "onewire.h"
/*======================第十四届蓝桥杯单片机模拟题===================
@Author:小殷
@Date:2023.4.5
=====================================================================*/
typedef unsigned char uchar;
typedef unsigned int  uint;
#define Control_Port(x,y)  P0 = y;P2 = x;P2 = 0
uchar  smg_bit[9] = {10,10,10,10,10,10,10,10,10};            //设置为10对应着0xff 关闭数码管初始化
//数码管段码 0-9 shut-off -
uchar smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0xc1,0xbf,0xc6,0x8c,0x88};
uchar L[4];                        //LED
uchar interface = 1;               //界面
uint Temperature = 0;              //温度
uint adc_volt = 0;                 //电压
uchar key_feq = 0;                 //按键刷新周期
uchar adc_feq = 0;                 //adc读取周期
uchar temperature_feq = 0;         //温度读取周期
uchar relay = 0,buzzer = 0;        //继电器和蜂鸣器
uchar usart_cmd = 0;               //串口接收缓存
uchar lock_flag = 0,usart_flag = 0;//锁定状态和串口发送状态
//=========================下面为相关函数声明=================================
void Delay5ms();		         //@12.000MHz
void Timer2Init(void);		     //1毫秒@12.000MHz
void UartInit(void);		     //9600bps@12.000MHz
void Send_Byte(uchar dat);       //发送字节
void Send_String(uchar *str);    //发送字符串
float Read_Temperature(void);    //读取温度
void Data_Tackle_Task(void);     //数据处理任务
void SMG_Dispaly_Task(void);     //数码管显示任务
uchar Read_Key_Value(void);      //按键值获取
void Key_Tackle_Task(void);      //按键处理任务
uchar Read_ADC_Value(uchar dat); //ADC值读取
void Init_System(void);          //系统初始化
//=========================下面为功能函数的实现===============================
void Delay5ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 59;
	j = 90;
	do
	{
		while (--j);
	} while (--i);
}

void Timer2Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0x20;		//设置定时初始值
	T2H = 0xD1;		//设置定时初始值
	AUXR |= 0x10;		//定时器2开始计时
	IE2 |= 0x04;
	EA = 1;
}

void UartInit(void)		//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器时钟1T模式
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xC7;		//设置定时初始值
	TH1 = 0xFE;		//设置定时初始值
	ET1 = 0;		//禁止定时器%d中断
	TR1 = 1;		//定时器1开始计时
	ES = 1;
	EA = 1;
}

void Send_Byte(uchar dat)
{
	SBUF = dat;
	while(TI == 0);
	TI = 0;
}

void Send_String(uchar *str)
{
	while(*str != '\0')
	{
		Send_Byte(*str++);
	}
}
float Read_Temperature(void)
{
	uchar LSB = 0,MSB = 0;
	float temp = 0;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	init_ds18b20();
	temp = ((MSB << 8)| LSB) * 0.0625;
	return temp;
}

void Data_Tackle_Task(void)
{
	if(temperature_feq > 150)
	{
		temperature_feq = 1;
		Temperature = Read_Temperature() * 10;
	}
	
	if(adc_feq > 150)
	{
		adc_feq = 1;
		adc_volt = Read_ADC_Value(0x03) *(5.0/255) * 100;
	}
	
	//下面为LED控制逻辑处理
	L[1] = (interface == 1)?(1):(0);
	L[2] = (interface == 2)?(1):(0);
	//下面为继电器和蜂鸣器控制逻辑处理
	relay  = (Temperature/10 >= 28)?(1):(0);
	buzzer = (adc_volt > 360)?(1):(0);
	//下面为串口功能处理
	if(usart_flag)
	{
		usart_flag = 0;
		if(interface == 1)
		{
			Send_String("TEMP:");
			Send_Byte(Temperature/100 + '0');
			Send_Byte(Temperature/10%10 + '0');
			Send_Byte('.');
			Send_Byte(Temperature%10 + '0');
			Send_String("℃\r\n");
		}
		else if(interface == 2)
		{
			Send_String("Voltage:");
			Send_Byte(adc_volt/100 + '0');
			Send_Byte('.');
			Send_Byte(adc_volt/10%10 + '0');
			Send_Byte(adc_volt%10 + '0');
			Send_String("V\r\n");
		}
	}
	if(lock_flag)
	{
		if(usart_cmd == 'A')
		{
			interface = 1;
			Send_String("TEMP:");
			Send_Byte(Temperature/100 + '0');
			Send_Byte(Temperature/10%10 + '0');
			Send_Byte('.');
			Send_Byte(Temperature%10 + '0');
			Send_String("℃\r\n");
		}
		else if(usart_cmd == 'B')
		{
			interface = 2;
			Send_String("Voltage:");
			Send_Byte(adc_volt/100 + '0');
			Send_Byte('.');
			Send_Byte(adc_volt/10%10 + '0');
			Send_Byte(adc_volt%10 + '0');
			Send_String("V\r\n");
		}
		usart_cmd = 0;      //清除等待下一次
	}
}

void SMG_Dispaly_Task(void)
{
	if(interface == 1)
	{
		smg_bit[1] = 11;
		smg_bit[2] = interface;
		smg_bit[3] = 10;
		smg_bit[4] = 10;
		smg_bit[5] = 10;
		smg_bit[6] = Temperature/100;
		smg_bit[7] = Temperature/10%10;
		smg_bit[8] = Temperature%10;
	}
	else if(interface == 2)
	{
		smg_bit[1] = 11;
		smg_bit[2] = interface;
		smg_bit[3] = 10;
		smg_bit[4] = 10;
		smg_bit[5] = 10;
		smg_bit[6] = adc_volt/100;
		smg_bit[7] = adc_volt/10%10;
		smg_bit[8] = adc_volt%10;
	}
}

uchar Read_Key_Value(void)
{
	static uchar last_trg = 0,cnt = 0;
	uchar trg = 0,cur = 0,value = 3,key_x = 0,key_y = 0;
	//P3 = 0x0f;P4 = 0x00;

	P4 = 0x00;
	//P30 = 1;
	//P31 = 1;
	P32 = 1;
	P33 = 1;
	P34 = 0;
	P35 = 0;
	P36 = 0;
	P37 = 0;

	//if(!P30) key_x = 3;
	//else if(!P31) key_x = 2;
	if(!P32) key_x = 1;
	else if(!P33) key_x = 0;
	//P3 = 0xf0;P4 = 0xff;
	P4 = 0xff;
	//P30 = 0;
	//P31 = 0;
	P32 = 0;
	P33 = 0;
	P34 = 1;
	P35 = 1;
	P36 = 1;
	P37 = 1;

	if(!P34) key_y = 4;
	else if(!P35) key_y = 3;
	else if(!P42) key_y = 2;
	else if(!P44) key_y = 1;
	cur = key_y ^ 0x00;
	trg = cur^cnt&cur;
	cnt = cur;
	
	if((last_trg^trg & last_trg) && cur)
	{
		value = key_x + key_y * 4;
	}
	last_trg = trg;
	return value;
}

void Key_Tackle_Task(void)
{
	uchar key_value = 0;
	if(key_feq > 10)
	{
		key_feq = 1;
		key_value = Read_Key_Value();
	}
	
	if(key_value == 4)
	{
		lock_flag = 0;         //只要按下S4即为锁定状态
		interface = (interface == 1)?(2):(1);
	}
	if(key_value == 5)
	{
		if(lock_flag == 0)  //锁定状态下才有效
		{
		   lock_flag = 1;  //解锁状态
		}
	}
	if(key_value == 12)   //通过按键进行串口发送
	{
		usart_flag = 1;
	}
}

uchar Read_ADC_Value(uchar dat)
{
	uchar adc = 0;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	adc = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	return adc;
}
void Init_System(void)
{
	Control_Port(0x80,0xff);         //关闭LED
	Control_Port(0xa0,0x00);         //关闭蜂鸣器和继电器
	Control_Port(0xc0,0x00);         //关闭数码管
	while(++temperature_feq < 150)   //上电时代温度稳定后再读取可以避免出现错误值
	{
		Temperature = Read_Temperature()*10;
	}
	UartInit();                      //串口初始化
	Delay5ms();                      //等待串口初始化完成
	Timer2Init();                    //定时器2初始化
	//Send_String("Usart Test\r\n");
}

void main(void)
{
	Init_System();
	while(1)
	{	
		Data_Tackle_Task();
		SMG_Dispaly_Task();
		Key_Tackle_Task();	
	}
}


void Timer2_Server() interrupt 12
{
	static uchar dsp_smg = 1;
	static uchar l3_count = 0;
	//下面为LED控制
	Control_Port(0x80,~(L[1] << 0 | L[2] << 1 | L[3] << 2));
	//下面为蜂鸣器和继电器控制
	Control_Port(0xa0,relay << 4 | buzzer << 6);
	//下面为数码管控制
	Control_Port(0xc0,0x00);
	//小数显示
	if((interface == 1 && dsp_smg == 7) || (interface == 2 && dsp_smg == 6))
	{
		Control_Port(0xe0,smg_data[smg_bit[dsp_smg]] & 0x7f);
	}
	//整数显示
	else
	{
		Control_Port(0xe0,smg_data[smg_bit[dsp_smg]]);
	}
	//位选操作
	Control_Port(0xc0,1 << (dsp_smg - 1));
	if(++dsp_smg > 8)
	{
		dsp_smg = 1;
	}
	//锁定状态
	if(lock_flag == 0)
	{
		if(l3_count++ == 100)
		{
			l3_count = 0;
			L[3] = !L[3];
		}
		
	}
	//下面为相关数据刷新频率
	temperature_feq++;
	key_feq++;
	adc_feq++;
}


void Usart_Server() interrupt 4
{
	if(RI)
	{
		RI = 0;                 //清除中断标志位
		usart_cmd = SBUF;       //将接收指令缓存到usart_cmd
	}
}
  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小殷学长

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

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

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

打赏作者

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

抵扣说明:

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

余额充值