《蓝桥杯真题》:2022年单片机省赛(第十三 / 13届第一场)

Posted Mascotttttt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《蓝桥杯真题》:2022年单片机省赛(第十三 / 13届第一场)相关的知识,希望对你有一定的参考价值。

2022年单片机省赛

有关题目







实现代码

注意:
数据处理方面:由于ds1302芯片存储的数据是BCD码,所以我们要进行BCD码与十进制之间的转换,例如0x16 的BCD码为16,十进制为1 * 16 + 6 = 32。
源文件修改方面:官方给onewire.h,ds1302.h中使用的时C51的头件"reg52.h",我们需修改为对应的15系列头文件"STC15F2K60S2.h",这样才可以使用一些特殊位寄存器。

底层代码:需修改驱动代码onewire.c中单总线延时函数,官方给我们是STC89C52RC系列,15系列的单片机速度比51快8~12倍,需要修改对应的延时函数。修改如下
void Delay_OneWire(unsigned int t)

char i;
while(t–)
for (i = 0; i < 12; i++);

main.c

#include "STC15F2K60S2.h"
#include "onewire.h"
#include "ds1302.h"

#define uchar unsigned char
#define uint unsigned int

sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;

uchar jm = 0;//界面初始化温度界面
code uchar tab[] = 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff, 0xc1, 0xbf; 
//U -  11 12

uchar init_time[3] = 0x40, 0x59, 0x23;//初始化时间秒 分 时
uchar time[3] =  0 ;//秒 分 时

bit mod_flag;//0为温度控制模式
bit rel_flag;//继电器是否闭合标志,为0未闭合
bit flag_5s;
bit led10_flag;//初始化0为led10熄灭
bit L1_flag;//初始化0为L1熄灭
bit L3_flag;//初始化0为L3熄灭

float curr_temp;
uchar para_temp = 23;

void sys_init();
void key_handle();
float rd_temperature();
void rd_time();
void rel_handle();
void led();

void dsp_smg_bit(uchar pos, val);
void display();//显示功能,分四个大块
void dsp_temp();
void dsp_time();
void dsp_para();
void dsp_min_sec();//长按S17显示分秒

void delay_k(uchar t);//延时t * 10us
void Delay1ms();		//1ms@12.000MHz,延时1ms用于给足数码管足够显示时间

void main()

	sys_init();
	while(1)
	
		curr_temp = rd_temperature();
		rd_time();//实时读取时间
		key_handle();
		display();	
		rel_handle();//继电器处理
		led();
	


void led()
	
	if (time[0] == 0x00 && time[1] == 0x00)
	
		L1_flag = 1;
						   
	if (L1_flag)
	
		P2 = (P2 & 0x1f) | 0x80;
		L1 = 0;
	
	else 
	
		P2 = (P2 & 0x1f) | 0x80;
		L1 = 1;
	
	
	if (!mod_flag)
	
		P2 = (P2 & 0x1f) | 0x80;
		L2 = 0;
	
	else 
	
	 	P2 = (P2 & 0x1f) | 0x80;
		L2 = 1;
	
	
	if (led10_flag)
	
		//继电器吸附,间隔0.1sL3闪烁
		if (L3_flag)
		
			P2 = (P2 & 0x1f) | 0x80;
			L3 = 0;
		
		else 
			L3 = 1;
	

	P0 |= 0xf8;//将L4~L8熄灭
	P2 &= 0x1f;


void rel_handle()

	uint t = (uchar)(curr_temp * 10);
	if (!mod_flag)
	
		if (t > para_temp * 10)
		
			led10_flag = 1;
			P2 = (P2 & 0x1f) | 0xa0;
			P0=0X10;
		
		else 
			
			led10_flag = 0;
			P2 = (P2 & 0x1f) | 0xa0;
			P0 = 0xaf;
			
	
	else if (mod_flag)
	
		if (time[0] == 0x00 && time[1] == 0x00)
		
			rel_flag = 1;//整点,继电器吸附标志
		
		if (rel_flag)
		
			P2 = (P2 & 0x1f) | 0xa0;
			P0 = 0x10;
			led10_flag = 1;
		
		else 
		
			P2 = (P2 & 0x1f) | 0xa0;
			P0 = 0xaf;
			led10_flag = 0;
		
	
	//P0 |= 0x00;
	//P2 &= 0x1f;



void rd_time()

	uchar t;
	
	t = Read_Ds1302_Byte(0x81);//秒
	time[0] = t / 16 * 10 + t % 16 ;
	
	t = Read_Ds1302_Byte(0x83);//分
	time[1] = t / 16 * 10 + t % 16 ;
	
	t = Read_Ds1302_Byte(0x85);//时
	time[2] = t / 16 * 10 + t % 16 ;


void display()

	if (0 == jm)
		dsp_temp();
	else if (1 == jm)
		dsp_time();
	else if (2 == jm)
		dsp_para();

void dsp_min_sec()

	dsp_smg_bit(1, 11);//U
	dsp_smg_bit(2, 2);//
	
	dsp_smg_bit(4, time[1] / 10);
	dsp_smg_bit(5, time[1] % 10);
	dsp_smg_bit(6, 12);//-
	dsp_smg_bit(7, time[0] / 10);
	dsp_smg_bit(8, time[0] % 10);


void dsp_para()

	dsp_smg_bit(1, 11);//U
	dsp_smg_bit(2, 3);//
	
	dsp_smg_bit(7, para_temp / 10 % 10);
	dsp_smg_bit(8, para_temp % 10);


void dsp_time()

	dsp_smg_bit(1, 11);//U
	dsp_smg_bit(2, 2);//
	
	dsp_smg_bit(4, time[2] / 10);
	dsp_smg_bit(5, time[2] % 10);
	dsp_smg_bit(6, 12);//-
	dsp_smg_bit(7, time[1] / 10);
	dsp_smg_bit(8, time[1] % 10);


void dsp_temp()

	uint x = (uint)(curr_temp * 10);//当前温度扩大10倍
	dsp_smg_bit(1, 11);//U
	dsp_smg_bit(2, 1);//
	dsp_smg_bit(6, x / 100 % 10);
	
	//第7位数码管显示小数点
	P2 = (P2 & 0x1f) | 0xc0;
	P0 = 1 << (7 - 1);
	
	P2 = (P2 & 0x1f) | 0xe0;
	P0 = tab[x / 10 % 10] & 0x7f;
	Delay1ms();
	
	P0 = 0xff;
	P2 &= 0x1f;
	
	dsp_smg_bit(8, x % 10);


void dsp_smg_bit(uchar pos, val)

	P2 = (P2 & 0x1f) | 0xc0;
	P0 = 1 << (pos - 1);
	
	P2 = (P2 & 0x1f) | 0xe0;
	P0 = tab[val];
	Delay1ms();
	
	P0 = 0xff;
	P2 &= 0x1f;


void Delay1ms()		//@12.000MHz

	unsigned char i, j;

	i = 12;
	j = 169;
	do
	
		while (--j);
	 while (--i);


void delay_k(uchar t)

	while(t--)
		display();


 void key_handle()

	P35 = P34 = P32 = 1;
	P33 = 0;//第四行拉低
	if(!P35)//s12
	
		delay_k(10);
		if(!P35)
		
			
			if (++jm >= 3)
			jm = 0;
			while(!P35)
			
				display();
			
		
	
	
	if(!P34)//s16
	
		delay_k(10);
		if(!P34)
		
			if (2 == jm)
				
				if (++para_temp > 99)
					para_temp = 99;
			
				while(!P34)
			
				display();
			
		
	
	
	P35 = P34 = P33 = 1;
	P32 = 0;//第三行拉低
	if(!P35)//s13
	
		delay_k(10);
		if(!P35)
			
			mod_flag = !mod_flag;
			while(!P35)
			
				display();
			
		
	
	
	if(!P34)//s17
	
		delay_k(10);
		if(!P34)
		
			if (2 == jm)
			
				if (--para_temp < 10)//参数操作 + 参数检查
					para_temp = 10;
			
			if (1 == jm)
			
				while(!P34)//s17的长按键操作
				
					rd_time();
					dsp_min_sec();
				
			
			while(!P34)
			
				display();
					
		
	


float rd_temperature()

	uchar l, h;
	uint t;
	float temp;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	l = Read_DS18B20();
	h = Read_DS18B20();
	
	t = (h & 0x0f);
	t <<= 8;
	t |= l;
	temp = t * 0.0625;
	
	return temp;


void timer0() interrupt 1

	static uint i1, i2, i3;
	if (rel_flag)//继电器闭合5秒断开标志
	
		if (++i1 == 5000)
		
			i1 = 0;
			rel_flag = 0;
		
	
	if (L1_flag)
	
		if (++i2 == 5000)
		
			i2 = 0;
			L1_flag = 0;
		
	
	if (++i3 == 100)//0.1s切换一次L3的状态,使其闪烁
	
		L3_flag = !L3_flag;
		i3 = 0;
	



void sys_init()

	//关蜂鸣器,继电器
	P2 = (P2 & 0x1f) | 0xa0;
	P0 = 0xaf;
	
	P2 = (P2 & 0x1f) | 0x80;
	P0 = 0xff;
	P2 &= 0x1f;

	Write_Ds1302_Byte(0x8e,0x00);//关闭写保护
	Write_Ds1302_Byte(0x80, init_time[0]);//秒
	Write_Ds1302_Byte(0x82, init_time[1]);//分
	Write_Ds1302_Byte(0x84, init_time[2]);//时
	Write_Ds1302_Byte(0x8e,0x80);//开启写保护
	
	//1ms
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	
	ET0 = 1;
	ET1 = 0;//禁止定时器中断1中断
	EA = 1;

onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

#include <STC15F2K60S2.H>

bit init_ds18b20(void);
unsigned char Read_DS18B20(void);
void Write_DS18B20(unsigned char dat);
void Delay_OneWire(unsigned int t);  

#endif


onewire.c

/*
  程序说明: 单总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
  日    期: 2011-8-9
*/
#include "onewire.h"

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC

	char i;
	while(t《蓝桥杯真题》:2022单片机省赛第二场(第十三 / 13届第二场)

《蓝桥杯真题》:2022单片机省赛第二场(第十三 / 13届第二场)

《蓝桥杯真题》:2022单片机省赛第二场(第十三 / 13届第二场)

《蓝桥杯真题》:2022单片机省赛第二场_客观题(第十三 / 13届第二场)

《蓝桥杯真题》:2022单片机省赛第二场_客观题(第十三 / 13届第二场)

《蓝桥杯真题》:2022单片机省赛第二场_客观题(第十三 / 13届第二场)