2011年第三届蓝桥杯单片机(省赛)_温度监控器

蓝桥杯第3届省赛(单片机)_温度监控器

题目

2011年第三届蓝桥杯单片机(省赛)_温度监控器_第1张图片

2011年第三届蓝桥杯单片机(省赛)_温度监控器_第2张图片
2011年第三届蓝桥杯单片机(省赛)_温度监控器_第3张图片
这是2011年蓝桥杯单片机组的省赛题,我感觉整体的难度不大,可能有点挑战性的就是EEPROM储存了,本次题型主要考查了数码管,独立按键,IIC-(EEPROM储存),继电器和电机拖动了。考察的都是那几种固定的模块。

题目分析

1 数码管显示单元

首先在数码管那一面上,DS1部分显示上限温度与下限温度,而在DS2部分我们要关闭前两位数码管而在最后两位显示自测温度,这题主要考的是数码管显示,对于DS1部分,我们只需写变量来控制温度上下限的高低,而自测温度那一部分,我们可以通过ds18b20部分将所得温度表达出来,最后再将温度通过乘除部分来通过数码管显示。

2 温度测量单元

这题比较简单,只需要改写底层驱动代码(onewhile)就可以测量了。

3 按键控制单元

这里主要考察的是独立按键,独立按键比较简单,只需要写好相应的按键代码格式就行,然后通过不同按键来控制不同的变量来控制温度值的变量。
(这里的按键代码格式我会在下面的代码显示部分表达出来)

4 EEPROM的记录

这里也是一样,只需要改写底层驱动代码(iic)就可以测量了.不过温度要保留在0X01,0X00部分。

5 电机拖动,6温控单元

由于我没有电机拖动,我在这里就用led1来代替了,其实主要的程序都一样,等我到时候有电机时我再来改动吧!再电机拖动哪里我主要是用了定时器,继电器也是一样,把定时器函数写在定时器函数里面,这里我先不多说,等到代码部分我在详见。

代码部分

time.c

# include "time.h"

void Timer0Init(void)		//100微秒@12.000MHz
{
     
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x9C;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA=ET0=1;
}

time.h

# ifndef _TIME_H
# define _TIME_H

# include 

void Timer0Init(void);

# endif

smg.c

# include "smg.h"

unsigned char code tab[11]={
     0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XFF};
unsigned char dspbuf[8]={
     10,10,10,10,10,10,10,10};

void smg_display(void)
{
     
	static unsigned char i;
	
	P0=0XFF;
	P2&=0X1F;
	P2|=0XE0;//Y7C
	P2&=0X1F;	
	
	P0=(1<<i);
	P2&=0X1F;
	P2|=0XC0;//Y6C
	P2&=0X1F;	
	
	P0=tab[dspbuf[i]];
	P2&=0X1F;
	P2|=0XE0;//Y7C
	P2&=0X1F;	
	
	if(++i==8)
		i=0;
}

smg.h

# ifndef _SMG_H
# define _SMG_H

# include 

void smg_display(void);
extern unsigned char dspbuf[8];

# endif

key.c
(这里的是矩阵按键的基本模型,通过按键控制变量最后控制数码管)

# include "key.h"

unsigned char key_value;

void key_read(void)
{
     
   static unsigned char i; //静态变量

	if(P30!=1||P31!=1||P32!=1||P33!=1)
	{
     
	    i++;
		if(i==1)
		{
     
			if(P30!=1)   key_value=1;
			else if(P31!=1)   key_value=2;
			else if(P32!=1)   key_value=3;
			else if(P33!=1)   key_value=4;		
	 }
  else if(i>=30) //长按变短按
	{
     
	   i=1;
		 key_value=0;
	}
 }
	else //没有按键按下则为零
	  i=0;
}

key.h

# ifndef _KEY_H
# define _KEY_H

# include 

void key_read(void);
extern unsigned char key_value;

# endif

other.c

# include "other.h"

void relay_on(void)
{
     
		  P2=(P2&0X1F)|0XA0;
			P0|=0X10;
			P2&=0X1F;
	P04=1;                 //在这里我认为这部分代码比上述代码好,出现的bug少
	P2&=0X1F;
	P2|=0XA0;
    P2&=0X1F;
	
}

void relay_off(void)
{
     		
	 P04=0;
	 P2&=0X1F;
	 P2|=0XA0;
	 P2&=0X1F;

//	P2=(P2&0X1F)|0XA0;
//	P0&=0xEF;
//	P2&=0X1F;

}

void bee_off(void)
{
     
	P06=0;
	P2&=0X1F;
	P2|=0XA0;
	P2&=0X1F;
	
//  P2=(P2&=0X1F)|0XA0;
//	P0&=0X00;
//	P2&=0X1F;
}

other.h

# ifndef _OTHER_H
# define _OTHER_H

# include 

void relay_on(void);
void relay_off(void);
void bee_off(void);

# endif

main.c

# include 
# include "time.h"
# include "smg.h"
# include "key.h"
# include "ds18b20.h"
# include "iic.h"
# include "other.h"

unsigned char tempature_max;
unsigned char tempature_min;
unsigned char key_allow;
unsigned int temp;
unsigned char flag_key;
unsigned char flag_relay;

void Delay5ms()		//@12.000MHz
{
     
	unsigned char i, j;

	i = 59;
	j = 90;
	do
	{
     
		while (--j);
	} while (--i);
}


void allinit(void)
{
     
    P0=0X00;
	P2&=0X1F;
	P2|=0XA0; //Y5C
	P2&=0X1F;
	
	//灯全灭
	P0=0XFF;
	P2&=0X1F;
	P2|=0X80;//Y4C
	P2&=0X1F;	

}

void eeprom_init(void)
{
     
   if(eeprom_read(0X99)==0X99)//这里可以随便定,只要不是数据库里的变量就行
	 {
     //这里主要是把板里的数据清除掉
		 tempature_max=30;
		 tempature_min=23;
	   tempature_max=eeprom_read(0X00);
		 tempature_min=eeprom_read(0X01);
	 }
  else
	{
     
	   eeprom_write(0X99,0X99);
	}
}

void main(void)
{
        
		allinit();
	    eeprom_init();
		Timer0Init();
		bee_off();
	    relay_off();
	
	while(1)
	{
     
		/******************key******************/
		     if(key_allow==1)
				 {
     
				    key_allow=0;
					  key_read();
				 }
			
				 
					switch(key_value)
					{
     
						case 1: 
							key_value=0;
						  flag_key=1;
						  break;
						case 2:
							key_value=0;
						  flag_key=2;
						  break;
						case 3:
						key_value=0;
						  flag_key=3;
						  break;
						case 4:
						key_value=0;
						  flag_key=4;
						  break;				
					}
					
			/****************ds18b20*******************/
						temp=temp_read();
					
					if(temp<tempature_min)
					{
     
					  flag_relay=1;
					}
					if(temp>tempature_min)
					{
     
					  flag_relay=2;
					}
					   					
					if(temp>tempature_max)
					{
     
					   flag_relay=3;
					}
					if(temp<tempature_max)
					{
     
					  flag_relay=4;
					}
					
			/****************temp_change*****************/		
					
					if(tempature_min>tempature_max||tempature_max==99||tempature_min==99)
					{
     
					   tempature_min--;				
					}
					
					switch(flag_key)
					{
     
						case 4:
							flag_key=0;
							if(tempature_max!=99)
							{
     
							tempature_max++;
							eeprom_write(0x00,tempature_max);
							Delay5ms();//延迟5毫秒来储存数据
							}								
						break;
						case 3:
							flag_key=0;
							if(tempature_min!=99)
							{
     
							tempature_min++;
							eeprom_write(0x01,tempature_min);
							Delay5ms();
							}			
						break;
						case 2:
							flag_key=0;
							if(tempature_max!=99)
							{
     
							tempature_max--;
							eeprom_write(0x00,tempature_max);
							Delay5ms();
							}			
						break;
						case 1:
							flag_key=0;
							if(tempature_min!=99)
							{
     
							tempature_min--;
							eeprom_write(0x01,tempature_min);
							Delay5ms();
							}
						break;		
					}
					
												
		/**************smg***************/
					
				dspbuf[0]=tempature_max/10;
				dspbuf[1]=tempature_max%10;
				dspbuf[2]=tempature_min/10;
				dspbuf[3]=tempature_min%10;
				dspbuf[4]=10;
				dspbuf[5]=10;
				dspbuf[6]=temp/10;
				dspbuf[7]=temp%10;
								 
	}
	
}

void time0(void) interrupt 1
{
     
   static unsigned char key_30_times;
	  if(++key_30_times==30)
		{
     
		  key_30_times=0;
			key_allow=1;
		}
		
	   /***************温控单元***************/
			
					if(flag_relay==1)
					{
     					
					  relay_on();
						flag_relay=0;
						bee_off();

					}
					if(flag_relay==2)
					{
     	
					flag_relay=0;
				  relay_off();		
						bee_off();						
					}		
	
					if(flag_relay==3)
					{
     
					 P0=0xFE;
					 P2&=0X1F; 
					 P2=0X80;
					 P2&=0X1F;
					}
					
					if(flag_relay==4)
					{
     
					  P0=0xFF;
						P2&=0X1F; 
						P2=0X80;
						P2&=0X1F;
					}
					
		smg_display();
}
//(这里的温控单元要在这里因为因为就是你那个如果放在中断的话,你可能在调用那个继电器打开函数的时候,刚执行到p14等于1他那个中断时间到了,
//它就进入到那个数码段,显示那里要批零就等于0xff,然后继续往下执行,P0就会被刷新掉。)

//然后等你处理完数码管之后,出来再继续进行那个继电器那个,打开那个函数,然后这时候p04应该不是1了,或者是其他的数,如果把温控单元这一部分放在主函数部分那继电器会不灵敏,会跳来跳去,显示bug。

结语

在这里我还是要感谢一下我都朱师兄,感谢他帮我找到了bug(就是温控单元那部分),不然我现在可能还卡在这道题吧!,我也看了一些大佬的文章,感觉自己的代码还是有许多问题,比如代码过长,不简便,所以,我认为我自己还是要好好学习,也感谢大家的观看,如果你认为可以的话可以收藏一下哦(⊙o⊙)!实在不行也给个赞( ̄▽ ̄)"吧!谢谢大家。

你可能感兴趣的:(蓝桥杯省赛,单片机)