蓝桥杯:第五届初赛:“简易温度采集与控制装置”

 

1、自己写过程中遇到的问题及解决:

①上电后:温度显示00(会延迟好几秒才会显示正常的环境温度)

    升温过程:温度变化不灵敏(时间比较长,温度跨度变化大)17℃——24℃(中            间隔好几秒才变)

②矩阵键盘按键不灵敏:按好几遍可能才会变化

解决:DS18B20 温度读取函数中涉及到延时,在前面模块化学习过程中延时700~900ms:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KGM5LiN5Zyw5LiK,size_15,color_FFFFFF,t_70,g_se,x_16watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KGM5LiN5Zyw5LiK,size_17,color_FFFFFF,t_70,g_se,x_16 

将延时减短,问题解决!(同时发现:此时延时可以不用动态扫描数码管),如下:

/*================DS18B20温度传感器============================================

=============================================================================*/
void Delay(unsigned int t)
{
	while(t--);
//	{
//		ShowSMG();//检测发现:去掉动态扫描,效果更好一些
//	}
}

void Read_DS18B20_temp()
{
	unsigned char LSB, MSB;
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	Delay(200);//********按键不灵敏、温度读取不灵敏:延时时间缩短一点!!***********
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	LSB = Read_DS18B20();//读低8位
	MSB = Read_DS18B20();//读高8位
	init_ds18b20();
	
	temp = MSB;
	temp <<= 8;
	temp = temp | LSB;
	temp >>= 4;//移除小数位
}

③灯闪烁的时候灭得非常快,一亮就灭:watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KGM5LiN5Zyw5LiK,size_20,color_FFFFFF,t_70,g_se,x_16

 LED熄灭应该写在按键里——就熄灭一次(不能循环!!!)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KGM5LiN5Zyw5LiK,size_20,color_FFFFFF,t_70,g_se,x_16

参考代码:

#include "reg52.h"
#include "onewire.h"

sfr P4 = 0xc0;

unsigned char code SMG_duanma[19] = {
	//  0   1    2    3    4    5    6    7
		0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
	//  8   9    A10  B11  C12  D13  E14  F15
		0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
	// -16  .17
		0xbf,0x7f,0xff};  //共阳数码管
unsigned char yi, er, san, si, wu, liu, qi, ba;
				
sbit H1 = P3^0;
sbit H2 = P3^1;
sbit H3 = P3^2;
sbit H4 = P3^3;//行
		
sbit L1 = P4^4;
sbit L2 = P4^2;
sbit L3 = P3^5;//列

unsigned char led = 0;//灭		
		
unsigned int temp;//温度(问题:温度为0??)temp16位!!用int!!!!		
		
unsigned char Tmax = 30;//温度上限
unsigned char Tmin = 20;//温度下限
		
unsigned char qujian = 0;//0:T<tmin / 1:tmin<= t <=tmax / 2:t>tmax		

unsigned char set = 0;//设置键		
unsigned char clear = 0;//清除键

unsigned char key = 0;//按键标志位				
unsigned char shu;//按键值		
		
void InitHC138(unsigned char n)
{
	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 Delayms(unsigned int ms)//延时 ms
{
	unsigned int i, j;
	for (i = ms; i > 0; i--)
		for (j = 845; j > 0;j--);
}

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

/*===============数码管========================================================

=============================================================================*/
void SMG_Bit(unsigned pos, unsigned char dat)
{
	InitHC138(6);
	P0 = 0x01 << pos;
	InitHC138(7);
	P0 = dat;
}

void SMG_All(unsigned char dat)
{
	InitHC138(6);
	P0 = 0xff;
	InitHC138(7);
	P0 = dat;
}

void ShowSMG()
{
	SMG_Bit(0, SMG_duanma[yi]);
	Delayms(1);
	SMG_Bit(1, SMG_duanma[er]);
	Delayms(1);
	SMG_Bit(2, SMG_duanma[san]);
	Delayms(1);
	SMG_Bit(3, SMG_duanma[si]);
	Delayms(1);
	SMG_Bit(4, SMG_duanma[wu]);
	Delayms(1);
	SMG_Bit(5, SMG_duanma[liu]);
	Delayms(1);
	SMG_Bit(6, SMG_duanma[qi]);
	Delayms(1);
	SMG_Bit(7, SMG_duanma[ba]);
	Delayms(1);
	
	SMG_All(0xff);//防止最后一位数码管过亮
}

/*================3X4矩阵按键==================================================

=============================================================================*/
void ScanKeys()
{
	
//第一行:
	H1 = 0; H2 = H3 = H4 = 1;
	L1 = L2 = L3 = 1;
	if (L1 == 0)
	{
		Delayms(5);
		if (L1 == 0)
		{
			shu = 0;
			key = 1;
		}
		while(!L1)
		{
			ShowSMG();
		}
	}
	else if (L2 == 0)
	{
		Delayms(5);
		if (L2 == 0)
		{
			shu = 1;
			key = 1;
		}
		while(!L2)
		{
			ShowSMG();
		}
	}
	else if (L3 == 0)
	{
		Delayms(5);
		if (L3 == 0)
		{
			shu = 2;
			key = 1;
		}
		while(!L3)
		{
			ShowSMG();
		}
	}
	
//第二行:	
	H2 = 0; H1 = H3 = H4 = 1;
	L1 = L2 = L3 = 1;
	if (L1 == 0)
	{
		Delayms(5);
		if (L1 == 0)
		{
			shu = 3;
			key = 1;
		}
		while(!L1)
		{
			ShowSMG();
		}
	}
	else if (L2 == 0)
	{
		Delayms(5);
		if (L2 == 0)
		{
			shu = 4;
			key = 1;
		}
		while(!L2)
		{
			ShowSMG();
		}
	}
	else if (L3 == 0)
	{
		Delayms(5);
		if (L3 == 0)
		{
			shu = 5;
			key = 1;
		}
		while(!L3)
		{
			ShowSMG();
		}
	}
	
//第三行:	
	H3 = 0; H2 = H1 = H4 = 1;
	L1 = L2 = L3 = 1;
	if (L1 == 0)
	{
		Delayms(5);
		if (L1 == 0)
		{
			shu = 6;
			key = 1;
		}
		while(!L1)
		{
			ShowSMG();
		}
	}
	else if (L2 == 0)
	{
		Delayms(5);
		if (L2 == 0)
		{
			shu = 7;
			key = 1;
		}
		while(!L2)
		{
			ShowSMG();
		}
	}
	else if (L3 == 0)
	{
		Delayms(5);
		if (L3 == 0)
		{
			shu = 8;
			key = 1;
		}
		while(!L3)
		{
			ShowSMG();
		}
	}
	
//第四行:	
	H4 = 0; H2 = H3 = H1 = 1;
	L1 = L2 = L3 = 1;
	if (L1 == 0)
	{
		Delayms(5);
		if (L1 == 0)
		{
			shu = 9;
			key = 1;
		}
		while(!L1)
		{
			ShowSMG();
		}
	}
	else if (L2 == 0)//设置键:按下进入设置界面;再次按下保存数据
	{
		Delayms(5);
		if (L2 == 0)
		{
			if (set == 0)
			{
				set = 1;//进入界面
				
				yi = 16; er = 18; san = 18; si = 18; wu = 18;
				liu = 16; qi = 18; ba = 18;//Tmax/Tmin:进入界面为熄灭状态
				
				InitHC138(4);//设置的时候把LED、蜂鸣器继电器关闭(题目没有要求)
				P0 = 0xff;
				InitHC138(5);
				P0 = 0x00;
			}
			else if (set == 1)
			{
				set = 0;//保存数据
				InitHC138(4);
				P0 = 0xff;//修正错误并保存数据后,L2熄灭
			}
		}
		while(!L2);
	}
	else if (L3 == 0)//清除键
	{
		Delayms(5);
		if (L3 == 0)
		{
			if (clear == 0)
			{
				clear = 1;//按下清除(所有数据)
			}
			while(!L3)
			{
				ShowSMG();
			}
		}
	}	
}

/*================DS18B20温度传感器============================================

=============================================================================*/
void Delay(unsigned int t)
{
	while(t--);
//	{
//		ShowSMG();//检测发现:去掉动态扫描,效果更好一些
//	}
}

void Read_DS18B20_temp()
{
	unsigned char LSB, MSB;
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	Delay(200);//********按键不灵敏、温度读取不灵敏:延时时间缩短一点!!***********
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	LSB = Read_DS18B20();//读低8位
	MSB = Read_DS18B20();//读高8位
	init_ds18b20();
	
	temp = MSB;
	temp <<= 8;
	temp = temp | LSB;
	temp >>= 4;//移除小数位
}

/*==================定时器T0===================================================
0:继电器关闭,L1 0.8秒闪烁 160
1:继电器关闭,L1 0.4秒闪烁 80
2:继电器打开,L1 0.2秒闪烁 40
0.2s = 200ms = 20 0000us = 40*5000us
=============================================================================*/
unsigned char count = 0;

void Init_Timer0()//定时器中断函数
{
	TMOD = 0x01;
	TH0 = (65535 - 5000) / 256;
	TL0 = (65535 - 5000) % 256;
	
	TR0 = 1;
	ET0 = 1;
	EA = 1;
}

void ServiceTimer0() interrupt 1 //中断服务函数
{
	TH0 = (65535 - 5000) / 256;
	TL0 = (65535 - 5000) % 256;//非自动重装模式
	
	if (set == 0)//非设置模式的时候 L1才闪烁
	{
		count++;
		if (qujian == 0)//区间0:继电器关闭,L1 0.8s闪烁
		{
			if (count == 160)
			{
				count = 0;
				if (led == 0)//0.8s L1闪烁
				{
					led = 1;
					InitHC138(4);
					P0 = 0xfe;
				}
				else if (led == 1)
				{
					led = 0;
					InitHC138(4);
					P0 = 0xff;
				}
			}
		}
		
		else if (qujian == 1)//区间1:继电器关闭,L1 0.4s闪烁
		{
			if (count == 80)
			{
				count = 0;
				if (led == 0)
				{
					led = 1;
					InitHC138(4);
					P0 = 0xfe;
				}
				else if (led == 1)
				{
					led = 0;
					InitHC138(4);
					P0 = 0xff;
				}
			}
		}
		
		else if (qujian == 2)//区间2:继电器打开,L1 0.2s闪烁
		{
			if (count == 40)
			{
				count = 0;
				if (led == 0)
				{
					led = 1;
					InitHC138(4);
					P0 = 0xfe;
				}
				else if (led == 1)
				{
					led = 0;
					InitHC138(4);
					P0 = 0xff;
				}
			}
		}
	}
}

//*****************主函数******************************************************
void main()
{
	InitSystem();
	Init_Timer0();
	
	yi = 16; er = qujian; san = 16; si = 18; wu = 18; liu = 18;
	qi = temp/10; ba = temp%10;//一定要写初始化 不然上电的时候数码管全是0000 0000
	
	while(1)
	{
		ShowSMG();
		ScanKeys();
		Read_DS18B20_temp();
		
		
		if (set == 0)//没设置的时候(保存数据)
		{
				if (temp < Tmin)
				{
					qujian = 0;//区间0:继电器关闭
					InitHC138(5);
					P0 = 0x00;
				}
				else if ((temp >= Tmin) && (temp <= Tmax))
				{
					qujian = 1;//区间1:继电器关闭
					InitHC138(5);
					P0 = 0x00;
				}
				else if (temp > Tmax)
				{
					qujian = 2;//区间2:打开继电器
					InitHC138(5);
					P0 = 0x10;
				}
				yi = 16; er = qujian; san = 16; si = 18; wu = 18; liu = 18;
				qi = temp/10; ba = temp%10;
		}
		
		else if (set == 1)//设置
		{
			if (clear == 1)//清除键
			{
				clear = 0;//释放状态
				yi = 16; er = 18; san = 18; si = 18; wu = 18; 
				liu = 16; qi = 18; ba = 18;//所有数据清除
			}
			
			if ((er == 18) && (key == 1))//key=1,按键按下
			{
				key = 0;//释放状态
				er = shu;
			}
			else if ((san == 18) && (key == 1))
			{
				key = 0;
				san = shu;
			}
			else if ((qi == 18) && (key == 1))
			{
				key = 0;
				qi = shu;
			}
			else if ((ba == 18) && (key == 1))
			{
				key = 0;
				ba = shu;
				
				Tmax = er*10 + san;
				Tmin = qi*10 + ba;
				
				if (Tmin > Tmax)//设置错误(L2亮 数据清除(清除后也亮?))
				{
					InitHC138(4);
					P0 = 0xfd;//L2亮
					yi = 16; er = 18; san = 18; si = 18; wu = 18;
					liu = 16; qi = 18; ba = 18;//数据全部清除
				}
			}	
		}
	}
}

 

 

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

行不地上

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

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

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

打赏作者

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

抵扣说明:

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

余额充值