蓝桥杯

   日期:2021-04-06     浏览:115    评论:0    
核心提示:第三届蓝桥杯单片机类温度监控器题目要求要实现温度监控可以将功能模块化,前期准备头文件、管脚定义、全局变量定义、函数声明#include<STC15F2K60S2.H>#include"Delay.h"#include"SelectHC573.h"#include"Disp_SMG.h"#include"onewire.h"#include "iic.h"sbit S7=P3^0;//按键sbit S6=P3^1;sbit S5=P3^2;sbit S4=P3^3

第三届蓝桥杯单片机类温度监控器

题目要求

要实现温度监控可以将功能模块化,

前期准备

头文件、管脚定义、全局变量定义、函数声明

#include<STC15F2K60S2.H>
#include"Delay.h"
#include"SelectHC573.h"
#include"Disp_SMG.h"
#include"onewire.h"
#include "iic.h"

sbit S7=P3^0;//按键
sbit S6=P3^1;
sbit S5=P3^2;
sbit S4=P3^3;
sbit L1=P0^0;//LED
sbit L2=P0^2;
sbit J=P0^4;//继电器
unsigned char SMG_DM[18]={ 
	0xc0,0xf9,0xa4,0xb0,0x99,0x92,
	0x82,0xf8,0x80,0x90,0x88,0x80,
	0xc6,0xc0,0x86,0x8e,0xbf,0x7f
};
unsigned int temp=0;//温度
unsigned char max=30;//上限
unsigned char min=20;//下限
char a=1;//存储数据控制位

void Dsip();
void All_Init();

锁存器选择函数

//=================================
//函 数 名:锁存器选择函数
//功 能:将选择的锁存器打开
//输入参数:所选择的锁存器
//输出参数:无
void SelectHC573(unsigned char n)
{ 
	switch(n)
	{ 
		case 0:P2=P2&0x1f;break;		//将打开的锁存器关闭
		case 4:P2=P2&0x1f|0x80;break;	//打开LED相关的锁存器
		case 5:P2=P2&0x1f|0xa0;break;	//蜂鸣器、继电器相关的锁存器
		case 6:P2=P2&0x1f|0xc0;break;	//数码管位选
		case 7:P2=P2&0x1f|0xe0;break;	//数码管段选
	}

}

外设关闭函数

//========================
//函数名:外设初始化函数
//功能:关闭外设
//输入参数:无
//输出参数:无
//========================
void All_Init()
{ 
	SelectHC573(4);
	P0=0xff;//熄灭LED数据
	SelectHC573(0);
	SelectHC573(5);
	P0=0x00;//熄灭蜂鸣器、继电器数据
	SelectHC573(0);
}

延时函数

//======================
//函数名:延时函数
//功能:延时
//输入参数:延时大小
//输出参数:无
void Delay(unsigned char t)
{ 
	while(t--);
}

功能实现

功能一数码管显示

//======================
//函数名:数码管显示函数
//功能:传入参数,让数码管显示
//输入参数:要显示的数据,和要显示的位置
//输出参数:无
//========================
void Disp_SMG(unsigned char dat,unsigned char pos)
{ 
	SelectHC573(6);
	P0=0x01<<pos;//要显示的位置
	SelectHC573(7);
	P0=dat;//要显示的数据
}

下面这段代码实现了题目中的要求

//========================
//函数名:显示
//功能:将要显示的数据放在一个函数中
//输入参数:无
//输出参数:无
//========================
void Dsip()
{ 
		Disp_SMG(SMG_DM[max/10],0);
		Delay(100);
		Disp_SMG(SMG_DM[max%10],1);
		Delay(100);
		Disp_SMG(SMG_DM[min/10],2);
		Delay(100);
		Disp_SMG(SMG_DM[min%10],3);
		Delay(100);
		Disp_SMG(0xff,4);
		Delay(100);
		Disp_SMG(0xff,5);
		Delay(100);
		Disp_SMG(SMG_DM[temp/10],6);
		Delay(100);
		Disp_SMG(SMG_DM[temp%10],7);
		Delay(100);
}

效果是这样的

功能二温度获取


要实现此功能需要ds18b20数字芯片获取,

#include "onewire.h"

//单总线延时函数
void Delay_OneWire(unsigned int t)
{ 
  while(t--);
}

//DS18B20初始化
bit Init_DS18B20(void)
{ 
	bit initflag = 0;
	DQ = 1;
	Delay_OneWire(144);
	DQ = 0;
	Delay_OneWire(960); 
	DQ = 1;
	Delay_OneWire(120); 
	initflag = DQ;    
	Delay_OneWire(60);
  
	return initflag;
}

//通过单总线写一个字节
void Write_DS18B20(unsigned char dat)
{ 
	unsigned char i;
	for(i=0;i<8;i++)
	{ 
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(60);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(60);
}

//读一个字节
unsigned char Read_DS18B20(void)
{ 
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{ 
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{ 
			dat |= 0x80;
		}	    
		Delay_OneWire(60);
	}
	return dat;
}

上述代码考试当天会提供,我们只需要自己进行修改即可,(上面的代码是修改过的)比赛所提供的文件中onewire.h中没有声明函数,需要自己进行声明
比赛当天提供的代码是1Hz的,将onewire.c中所有延时函数扩大12倍即可成为12Hz的

温度获取


void Delay_wd(unsigned int t)
{ 
	while(t--)
	{ 
		Dsip();
	}
}
//========================
//函数名:温度获取函数
//功能:获取温度给全局变量temp
//输入参数:无
//输出参数:无
//========================
void Ds18B20_temp()
{ 
	
	unsigned int LSB,MSB;//温度数据
	Init_DS18B20();//初始化
	Write_DS18B20(0xcc);//跳过ROM指令
	Write_DS18B20(0x44);//开始温度转换
	Delay_wd(1000);//稍微延时一下
	
	Init_DS18B20();//初始化
	Write_DS18B20(0xcc);//跳过ROM指令
	Write_DS18B20(0xbe);//读取高速缓存
	
	LSB=Read_DS18B20();//读取低8位
	MSB=Read_DS18B20();//读取高8位
	Init_DS18B20();//初始化
	temp=MSB;
	temp=(temp<<8)|LSB;//高8位左移,低四位赋给temp
	temp>>=4;//去掉小数位
}

注意:不要将高位和低位弄反了,不然读出来的数据是错误的

功能三按键实现


这个功能很好实现,定义两个全局变量max\min为上下限温度,当按键按下时数值改变,并且将数值保存在AT24C02中。

void Key()
{ 
	if(S7==0)
	{ 
		Delay(10);
		if(S7==0)
		{ 
			min--;
			a=0;//全局变量,为实现功能四而设定
		}
	}
	if(S6==0)
	{ 
		Delay(10);
		if(S6==0)
		{ 
			max--;
			a=0;
		}
	}
	if(S5==0)
	{ 
		Delay(10);
		if(S5==0)
		{ 
			min++;
			a=0;
		}
	}
	if(S4==0)
	{ 
		Delay(10);
		if(S4==0)
		{ 
			max++;
			a=0;
		}
	}
	if(a==0)//功能四的部分实现
	{ 
		Write_24c02(0x00,max);//向e2prom写入温度上限
		Delay(2000);
		Write_24c02(0x01,min);//写入温度下限
		a=2;
	}
}

功能四将数据保存在AT24C02中

#include "iic.h"
void IIC_Start(void)
{ 
	SDA = 1;
	SCL = 1;
	somenop;
	SDA = 0;
	somenop;
	SCL = 0;	
}
void IIC_Stop(void)
{ 
	SDA = 0;
	SCL = 1;
	somenop;
	SDA = 1;
}
void IIC_Ack(unsigned char ackbit)
{ 
	if(ackbit) 
	{ 	
		SDA = 0;
	}
	else 
	{ 
		SDA = 1;
	}
	somenop;
	SCL = 1;
	somenop;
	SCL = 0;
	SDA = 1; 
	somenop;
}
bit IIC_WaitAck(void)
{ 
	SDA = 1;
	somenop;
	SCL = 1;
	somenop;
	if(SDA)    
	{    
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else  
	{  
		SCL = 0;
		return 1;
	}
}

void IIC_SendByte(unsigned char byt)
{ 
	unsigned char i;
	for(i=0;i<8;i++)
	{    
		if(byt&0x80) 
		{ 	
			SDA = 1;
		}
		else 
		{ 
			SDA = 0;
		}
		somenop;
		SCL = 1;
		byt <<= 1;
		somenop;
		SCL = 0;
	}
}

unsigned char IIC_RecByte(void)
{ 
	unsigned char da;
	unsigned char i;
	
	for(i=0;i<8;i++)
	{    
		SCL = 1;
		somenop;
		da <<= 1;
		if(SDA) 
		da |= 0x01;
		SCL = 0;
		somenop;
	}
	return da;
}

这些代码比赛当天都会提供,需要自己看手册来实现功能就行,我们要写的代码是下面的部分

void Write_24c02(unsigned char seat,unsigned char dat)
{ 
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(seat);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}
//========================

//========================

void EEPROM_Read(unsigned char* pucBuf,unsigned char addr,
											unsigned char num)
{ 
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
while(num--)
{ 
*pucBuf++ = IIC_RecByte();
if(num) 
	IIC_Ack(0);
else IIC_Ack(0);
}
IIC_Stop();
}


其实本质就是时序图,大概总结了一下,写入数据的如下
启动总线-----发送设备地址+写-----等待应答-----发送数据的储存地址(0x00-0xFF,256个字节)-----等待应答-----发送数据-----等待应答-----停止总线
读入数据如下
启动总线-----发送设备地址+写-----等待应答-----发送数据存储地址-----等待应答-----发送设备地址+读-----等待应答-----读取数据-----主机发送是否应答……

功能五、六


自己现在没有一个直流电机,就用L1、L2d代替超过上限时工作和不工作

void Elect()
{ 
		if(temp<min)
		{ 
				All_Init();
				SelectHC573(5);
				J=1;
		}
		else 
		{ 
				All_Init();
				SelectHC573(5);
				J=0;
		}
		if(temp>max)
		{ 
			SelectHC573(4);
			P0=0xfd;
		}
		else
		{ 
			SelectHC573(4);
			P0=0xfe;
		}
}

主函数

void main()
{ 
	All_Init();

	EEPROM_Read(&max,0x00,1);//读取温度上下限
	EEPROM_Read(&min,0x01,1);
	while(1)
	{ 
		Elect();
		Key();
		Dsip();
		Ds18B20_temp();
	}
}

具体文件

链接:https://pan.baidu.com/s/1pRPqaDrWomakjsXBSTjPgA
提取码:qwer

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服