蓝桥杯第六届初赛 温度记录器

邮差的信 提交于 2020-03-04 11:14:38

第六届考查的是一个DS1302的时间显示和一个DS18B20的温度间隔采集,然后保存10个数据。
主要的难点我觉得是如何采集和保存10个温度数据和与该界面无关的按键操作无效。在这里插入图片描述设备工作模式的说明的3,4点
在这里插入图片描述
1.温度采集本身有时间间隔,所以不能放到中断里直接读取,通过设置一个中间变量,保存中间变量的数据,来进行读取。2.保存温度数据要在中断里执行,主程序里面过多语句的话,会影响采集温度的时效性和显示。3.设备工作模式的3,4点通过设置标志位,判断标志位,使与本界面无关的按键操作无效。
代码风格学习大科的,相对简单通俗易懂。
主函数

#include <STC15F2K60S2.H>
#include "ds1302.h"
#include "onewire.h"
#define uchar unsigned char
#define uint unsigned int
void display1(uchar yi,uchar er,uchar san,uchar si);
void display2(uchar wu,uchar liu,uchar qi,uchar ba);
void delayms(int ms);
void writetime();
void readtime();
void Timer0Init(void);
void keyscan();
uchar temget();
uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
uchar time[]={50,59,23,2,3,1,20};
uchar yi,er,san,si,wu,liu,qi,ba;
uchar set=0,delay=1,flag,num,n,m,fla;
uchar wendu[10];
int tt;
void allinit()
{
 P2=0xa0;
 P0=0x00;
 P2=0x80;
 P0=0xff;
 P2=0xc0;
 P2=0xff;
 P2=0xe0;
 P0=0xff;
}
void main()
{
	allinit();
	Timer0Init();
	writetime();
 while(1)
 {
 
		keyscan();
		num=temget();
   if(set==0)
	 {
	   yi=11;er=11;san=11;si=11;wu=11;liu=10;qi=delay/10;ba=delay%10;
	 }
	 else if(set==1)
	 {
		if(flag==0)
		{
		
			readtime();
			yi=time[2]/10;er=time[2]%10;si=time[1]/10;wu=time[1]%10;qi=time[0]/10;ba=time[0]%10;
			if(time[0]%2==0)
			{
			 san=10;liu=10;
			 if(m==10)
			 {
			  P2=0x80;P0=0xfe;
			 }
			}
			else if(time[0]%2==1)
			{
			 san=11;liu=11;
			 	if(m==10)
			 {
			  P2=0x80;P0=0xff;
			 }
			}
	  }
    else if(flag==1)
		{
		 yi=10;er=n/10;;san=n%10;si=11;wu=11;liu=10;qi=wendu[n]/10;ba=wendu[n]%10;
	   fla++;
		 if(fla==100)
		 {
			fla=0;
			 n++;
			 if(n==10)
			 {
				n=0;
			 }
			}
		}
	}
   display1(yi,er,san,si);
	 display2(wu,liu,qi,ba);
 }
}

按键执行函数

void keyscan()
{
  if(P30==0)  //S7
	{
	 delayms(5);
	 if(P30==0)
	 {
     if(set==1)
		 {
			if(flag==1)
			{
				set=0;n=0;
				flag=0;
			}
		 }
	 }
	 while(!P30);
	}
	else if(P31==0)//S6
	{
	 delayms(5);
	 if(P31==0)
	 {
		 if(set==1)
		 {
		  if(m==10)
			{
				flag=1;m=0;
				P2=0x80;P0=0xff;
			}
		 }
	 }
	 while(!P31);
	}
	else if(P32==0) //S5
	{
	 delayms(5);
	 if(P32==0)
	 {
	   if(set==0)
		 {
			set=1;
			ET0=1;EA=1;
		}
	 }
	 while(!P32);
	}
	else if(P33==0) //S4
	{
	 delayms(5);
	 if(P33==0)
	 {
	   if(set==0)
		 {
		  if(delay==1)delay=5;
			else if(delay==5)delay=30;
			else if(delay==30)delay=60;
			else if(delay==60)delay=1;
		 }
	 }
	 while(!P33);
	}
}

定时中断函数

void Timer0Init(void)		//5毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x00;		//设置定时初值
	TH0 = 0x28;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}

void time0() interrupt 1
{
	tt++;
	if(tt==delay*200)
	{
     tt=0;
		 wendu[m]=num;
		 m++;
		 if(m==10)
		 {
		  ET0=0;EA=0;
		 }
	}
}

温度读取和时钟显示函数

uchar temget()
{
  uchar temp,low,high;
	Init_DS18B20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay_OneWire(200);
	
	Init_DS18B20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	low=Read_DS18B20();
	high=Read_DS18B20();
	
	temp=high<<4;
	temp|=low>>4;
	
	return temp;
}
void writetime()
{
  uchar i,add=0x80;
	for(i=0;i<7;i++)
	{
	  time[i]=((time[i]/10)<<4)|(time[i]%10);
	}
	Write_Ds1302_Byte(0x8e,0x00);//打开写保护
	for(i=0;i<7;i++)
	{
	  Write_Ds1302_Byte(add,time[i]);
		add=add+2;
	}
	Write_Ds1302_Byte(0x8e,0x80);//关闭写保护
}
void readtime()
{
  uchar i,add=0x81;
	Write_Ds1302_Byte(0x8e,0x00);
	for(i=0;i<7;i++)
	{
	  time[i]=Read_Ds1302_Byte(add);
		add=add+2;
		time[i]=(time[i]/16)*10+time[i]%16;
	}
	Write_Ds1302_Byte(0x8e,0x80);
}

数码管显示和延时函数

void display1(uchar yi,uchar er,uchar san,uchar si)
{
  P2=0xc0;
	P0=0x01;
	P2=0xe0;
	P0=tab[yi];
	delayms(1);
	
	P2=0xc0;
	P0=0x02;
	P2=0xe0;
	P0=tab[er];
	delayms(1);
	
	P2=0xc0;
	P0=0x04;
	P2=0xe0;
	P0=tab[san];
	delayms(1);
	
	P2=0xc0;
	P0=0x08;
	P2=0xe0;
	P0=tab[si];
	delayms(1);
}
void display2(uchar wu,uchar liu,uchar qi,uchar ba)
{
	P2=0xc0;
	P0=0x10;
	P2=0xe0;
	P0=tab[wu];
	delayms(1);

	P2=0xc0;
	P0=0x20;
	P2=0xe0;
	P0=tab[liu];
	delayms(1);

	P2=0xc0;
	P0=0x40;
	P2=0xe0;
	P0=tab[qi];
	delayms(1);
	
	P2=0xc0;
	P0=0x80;
	P2=0xe0;
	P0=tab[ba];
	delayms(1);
}
void delayms(int ms)
{
 int i,j;
 for(i=0;i<ms;i++)
 for(j=0;j<845;j++);
}

onewire和ds1302驱动为官方驱动

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!