蓝桥杯单片机第六届省赛

前言

这套题其实一开始做的时候有点发懵,一直陷入到一个巨大的漏洞里面,主要是在10次数据采集上面,说白了就是练得少,太菜了

题目

在这里插入图片描述
在这里插入图片描述
这套题到现在的代码也有一些漏洞,实在是不想改了,最近有点摆烂,但是主要的功能都没有问题

思路

这道题用到了四个按键,DS1302时钟,DS18B20温度采集,这两个模块可以看我另一个专栏蓝桥杯单片机里面的内容,里面有关于蓝桥杯单片机里面常用模块的部分

这道题说白了就是用按键控制状态,蓝桥杯的题目说白了都是用按键控制状态,自己能把思路打通了,按键写出来基本就都没有什么问题。

一开始做这道题的时候,思路是用两个定时器分别控制一些数据采集和闪烁的地方,然后发现这里一个定时器就可以做到,然后得到的就是现在的屎山代码,下面看看代码,不一定全对,但是希望对大家有所帮助

#include <REGX52.H>
#include <ds1302.h>
#include <onewire.h>
unsigned char code SMG_duanma[18]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
	0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
	0xbf,0xff};
unsigned char w_adds[] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
unsigned char r_adds[] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8c};
unsigned char Timer[] = {0x50,0x59,0x23};
unsigned int wendu[10] = {0};
void delay(int t)//延时
{
	unsigned int i;
	while(t--)
		for(i = 0; i <= 615;i++);
}
	
void HC138(unsigned char n)//138译码器
{
	switch(n)
	{
		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;
	}
}

void display(unsigned char pos,num)//数码管基础显示函数
{
	HC138(6);
	P0 = 0x01 << pos;
	HC138(7);
	P0 = SMG_duanma[num];
//	delay(2);
}

void ds1302_pz()//时间设置
{
	unsigned char i;
	Write_Ds1302(0x8e,0x00);
	for(i = 0;i<3;i++)Write_Ds1302(w_adds[i],Timer[i]);
	Write_Ds1302(0x8e,0x80);
}

void ds1302_dq()//时间读取
{
	unsigned char i;
	for(i = 0;i <3;i++)Timer[i] = Read_Ds1302(r_adds[i]);
}

unsigned int temp=0;
void ds18b20()//温度采集
{

	unsigned int lsb,msb;
	Init_DS18B20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	Init_DS18B20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	lsb = Read_DS18B20();
	msb = Read_DS18B20();
	temp = msb;
	temp = (temp << 8) | lsb;
	temp *= 0.0625; 
}

unsigned int tep = 1;
void display_time()//显示时间
{
	ds1302_dq();
	display(0,Timer[2]/16);delay(2);
	display(1,Timer[2]%16);delay(2);
	if(tep == 0){display(2,17);delay(2);}
	if(tep == 1){display(2,16);delay(2);}
	display(3,Timer[1]/16);delay(2);
	display(4,Timer[1]%16);delay(2);
	if(tep == 0){display(5,17);delay(2);}
	if(tep == 1){display(5,16);delay(2);}
	display(6,Timer[0]/16);delay(2);
	display(7,Timer[0]%16);delay(2);
}

void Timer0_Init(void)		//1毫秒@11.0592MHz
{
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0xCD;				//设置定时初始值
	TH0 = 0xD4;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA = 1;
}
unsigned int led_z = 1,led_t;
unsigned int count,count_jishi,count_wendu;
unsigned int count_fi,count_fo,count_time,shezhi,count_si,caiji;
void key()//按键
{
	if(P3_0 == 0)
	{
		delay(10);
		if(P3_0 == 0)
		{
			shezhi = 0;
		}
		while(!P3_0);
	}
	
	if(P3_1 == 0)
	{
		delay(10);
		if(P3_1 == 0)
		{
			shezhi = 2;
			count_si++;
			count_wendu = 0;
			led_z = 1;
		}
		while(!P3_1);
	}
	if(P3_2 == 0)
	{
		delay(10);
		if(P3_2 == 0)
		{
			count_fi++;
			ds1302_pz();
			shezhi = 1;
			caiji = 1;
		}
		while(!P3_2);
	}
	if(P3_3 == 0)
	{
		delay(10);
		if(P3_3 == 0)
		{
			count_fo++;
			shezhi = 0;
		}
		while(!P3_3);
	}
		if(count_fo%4 == 0)count_time = 1;
		else if(count_fo%4 == 1)count_time = 5;
		else if(count_fo%4 == 2)count_time = 30;
		else if(count_fo%4 == 3)count_time = 60;
		else if(count_fo%4 == 5)count_fo = 0;
		if(count_si > 9)count_si = 0;
}

void display_shezhi()//第一个界面
{
	key();
	display(0,17);delay(2);
	display(1,17);delay(2);
	display(2,17);delay(2);
	display(3,17);delay(2);
	display(4,17);delay(2);
	display(5,17);delay(2);
	display(6,count_time/10);delay(2);
	display(7,count_time%10);delay(2);
}

void display_wendu()//温度读取的界面
{
	display(0,16);delay(2);
	display(1,0);delay(2);
	display(2,count_si);delay(2);
	display(3,17);delay(2);
	display(4,17);delay(	2);
	display(5,16);delay(2);
	display(6,wendu[count_si]/10);delay(2);
	display(7,wendu[count_si]%10);delay(2);
}


void LED()//led闪烁的,这个地方可以直接调用,代码中没有相关体现
{
	if(led_z == 0)
	{
		HC138(4);
		P0 = 0XFE;		
	}
	if(led_z == 1)
	{
		HC138(4);
		P0 = 0XFf;		
	}
	
}

void main()
{
	Timer0_Init();
//	ds1302_pz();
	while(1)
	{
		key();
		ds18b20();
//		LED();
		if(shezhi == 1)
		display_time();
		if(shezhi == 0)
		display_shezhi();
		if(shezhi == 2)
			display_wendu();
	}
}

void Timer0_Isr(void) interrupt 1
{
		if(caiji == 1)
		{	
			count++;count_jishi++;led_t++;
			if(count == 100)tep = 1;
			else if(count == 200)
			{
				tep = 0;count =0;
			}
			if(count_jishi == count_time*100)		
			{
				count_jishi = 0;
				wendu[count_wendu] = temp;
				count_wendu++;
				if(count_wendu == 10)
					shezhi = 2;		
			}
		}			
}


总结

做完这几台题就会发现,按键是中心,也就是按键控制所有,思路一定要打通
这一套题的难度不算很大,但是博主水平有限,大家先凑合着看,如果对大家有什么帮助那是最好的以上所有代码均为自己编写,肯定会有更好的解法,肯定会有,本人水平有限,如果有哪里出错或者有更好的解法可以与我私信或在评论区里进行讨论

上一套:蓝桥杯单片机第五届省赛

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值