蓝桥杯第七届省赛(单片机)_模拟风扇控制系统

蓝桥杯第七届省赛(单片机)_模拟风扇控制系统

题目

蓝桥杯第七届省赛(单片机)_模拟风扇控制系统_第1张图片
蓝桥杯第七届省赛(单片机)_模拟风扇控制系统_第2张图片
蓝桥杯第七届省赛(单片机)_模拟风扇控制系统_第3张图片
大家好各位,我又回来了。最近由于忙于过年和开学所以没有时间来写博客,不过这段时间到有空闲的时间,我会陆续的把蓝桥杯单片机的博客给补上,废话不多说,那我们开始主题吧!

这是第七届蓝桥杯单片机组的省赛题,我感觉整体的难度不大,可能有点挑战性的就是pwm按键更换模式,其他大部分考察的也就是数码管显示ds18b20按键led显示。这些都是蓝桥杯的必考模块,大部门都很简单,只要根据平时我们所写的模块嵌套上去就行。

题目分析

1 数码管显示单元

根据题目分析,本次赛题要求我们有两种数码管的显示状况,工作模式和室温模式两种。其实对于两种的数码管状态的显示我们可以根据变量来进行控制与表达。例如我们设一个变量flag_smg,当flag_smg等于1时,数码管显示工作状态,当flag_smg等于2时,数码管显示室温状态。这里可能讲的比较简洁,等下我会把代码发布,到时候看代码就比较好理解了。

2 温度测量单元

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

3 按键控制单元

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

4 LED灯显示与pwm

led灯显示是单片机的基础部分比较简单,打开锁存器就行,而pwm与电机有关,我想等等有代码来表示这pwm的意思。

代码部分

time.c

# include "time.h"

void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA=ET0=1;
}
void Timer1Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0xBF;		//定时器时钟12T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x18;		//设置定时初值
	TH1 = 0xFC;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
}

//**这里有两个定时器,一个是Pwm的定时器,另一个是主要函数的安放的**

time.h

# ifndef _TIME_H
# define _TIME_H

# include 

void Timer0Init(void);
void Timer1Init(void);

# endif

smg.c

# include "smg.h"

unsigned char tab[13]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF,0XC6};
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;
	P2&=0X1F;
	
	P0=(0X01<<i);
	P2&=0X1F;
	P2=0XC0;
	P2&=0X1F;
	
	P0=tab[dspbuf[i]];
	P2&=0X1F;
	P2=0XE0;
	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;
				if(P31!=1)
		       key_value=2;
				if(P32!=1)
		       key_value=3;
				if(P33!=1)
		       key_value=4;
		 }
		 else if(++i>=33)
		 {
		   i=0;
		   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

ds18b20.c

#include "ds18b20.h"

sbit DQ = P1^4;  //单总线接口

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

	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}


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

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

//从DS18B20读取一个字节
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(5);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}


unsigned int ds18b20_read(void)
{
  unsigned char TL,TH;
	unsigned int dat;
	
	init_ds18b20();
	Delay1ms();
	Write_DS18B20(0XCC);
	Write_DS18B20(0X44);
	
	
	init_ds18b20();
	Delay1ms();
	Write_DS18B20(0XCC);
	Write_DS18B20(0XBE);
	
	TL=Read_DS18B20();
	TH=Read_DS18B20();
	
	dat=((TH<<8)|TL);
	dat*=0.0625;
	
	return dat;
}

ds18b20.h

# ifndef _DS18B20_H
# define _DS18B20_H

# include 

unsigned int ds18b20_read(void);

# endif

other.c

# include "other.h"

void led1_on(void)
{
  P2=(P2&0X1F)|0X80;
	P0=0XFE;
	P2&=0X1F;
}

void led2_on(void)
{
  P2=(P2&0X1F)|0X80;
	P0=0XFD;
	P2&=0X1F;
}

void led3_on(void)
{
  P2=(P2&0X1F)|0X80;
	P0=0XFB;
	P2&=0X1F; 
}

void led_off(void)
{
  P2=(P2&0X1F)|0X80;
	P0=0XFF;
	P2&=0X1F;
}

other.h

# ifndef _OTHER_H
# define _OTHER_H

# include 

void led1_on(void);
void led2_on(void);
void led3_on(void);
void led_off(void);
	
# endif

main.c

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

unsigned char key_allow;
unsigned char work_value;
unsigned char flag_led;
unsigned char mode;
unsigned char add_time;
unsigned char temp;
unsigned char time;
unsigned char k7_count;
unsigned char flag_smg;
unsigned char flag_time;
unsigned char flag_count_down;
unsigned char pwm;

void allinit(void)
{
    P0=0X00;
	P2&=0X1F;
	P2=0XA0;
	P2&=0X1F;
	
	P0=0XFF;
	P2&=0X1F;
	P2=0X80;
	P2&=0X1F;
}

void main (void)
{
	allinit();
	Timer0Init();
	Timer1Init();
	
  while(1)
	{
/**********************key**********************/
		if(key_allow==1)
		{
		  key_allow=0;
			key_read();
		}
		
		if(key_value==4)   //s4
		{
		  key_value=0;
			
			if(++work_value==4) //按键循环更改模式
				work_value=1;
			
			switch(work_value)
			{
			  case 1:
				 	flag_led=1;
				  pwm=20;
				  mode=1;
				break;	
				
				case 2:
				 	flag_led=2;
					pwm=30;
				  mode=2;
				break;	
				
				case 3:
				 	flag_led=3;
					pwm=70;
				  mode=3;
				break;
			}
		}
			
		if(key_value==3)  //s5
		{
		   key_value=0;
			
		if(++add_time==4)
			 add_time=1;
		
		 switch(add_time)
		 {
		   case 1:
				  time=0;
			 break;
			 
			 case 2:
				 time+=60;
				 flag_led=mode;
			 break;
			 
			 case 3:
				 time+=60;
			   flag_led=mode;
			 break;			
		}
		 if(time>180)
		    time=0;
	}
				
		if(key_value==2)   //s6
		 {
			 key_value=0;
			 add_time=1;
			 time=0;
			 flag_led=0;
			 pwm=0;
		 }
		 
		if(key_value==1)	//s7
		{
			key_value=0;
			mode=4;
			if(k7_count^=1)
			  flag_smg=1;
			else
				flag_smg=0;
		}
/******************count down***********************/		
		if(time==0)
			flag_count_down=0;
		else
			flag_count_down=1;
		
		if(flag_time==1)
		{
			flag_time=0;
		  if(--time<0)
			{
			  time=0;
				flag_led=0;
			}
		}
			
/************************ds18b20************************/
	  	temp=ds18b20_read();

/************************SMG**************************/		 
		 if(flag_smg==1)		//室温
		 {
			 dspbuf[0]=10;
			 dspbuf[1]=4;
			 dspbuf[2]=10;
			 dspbuf[3]=11;
			 dspbuf[4]=11;
			 dspbuf[5]=temp/10;
			 dspbuf[6]=temp%10;
			 dspbuf[7]=12;
		 }
		 
		 	if(flag_smg==0)		//工作模式
		 {
	    dspbuf[0]=10;
		  dspbuf[1]=mode;
		  dspbuf[2]=10;
		  dspbuf[3]=11;
		  dspbuf[4]=0;
	  	dspbuf[5]=time/100;
		  dspbuf[6]=time%100/10;
		  dspbuf[7]=time%10;
		 }
		 
	}

}	

void time0(void) interrupt 1
{
  static unsigned char key_times;
	static unsigned int flag_1s_time;
	
	if(++key_times==30)
	{
	  key_times=0;
		key_allow=1;
	}
	
	if(flag_count_down==1)
	{	
	   if(++flag_1s_time==1000)
	   {
	     flag_1s_time=0;
		   flag_time=1;
	   }
  }
/*********************LED*************************/	
		if(flag_led==1)
		{
		  led1_on();
		}
		if(flag_led==2)
		{
		  led2_on();
		}
		if(flag_led==3)
		{
		  led3_on();
		}
	  if(flag_led==0)
		{
			led_off();
		}
		
		smg_display();
}

void time1(void)  interrupt 3
{
   	static unsigned char fre=0;
	
			if(fre<pwm)
				P34=1;
			else 
				P34=0;
	
			if(++fre==100)
				fre=0;
}

结语

其实这道题的难度不是很大,大家只要认真的做这道题大部分还是可以做出来的。
我最近也看了一些大佬的文章,感觉自己的代码还是有许多问题,比如代码过长,不简便,所以,我认为我自己还是要好好学习,也感谢大家的观看,如果你认为可以的话可以收藏一下哦(⊙o⊙)!实在不行也给个赞( ̄▽ ̄)"吧!谢谢大家。

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