蓝桥杯第七届省赛试题--“模拟风扇控制系统”

题目要求

功能简述
“模拟风扇控制系统”能够模拟电风扇工作,通过按键控制风扇的转动速度和定时时间,数码管实时显示风扇的工作模式,动态倒计时显示剩余的定时时间,系统主要由数码管显示、单片机最小系统、按键输入和电机控制保护电路组成,系统框图如图 1 所示:
在这里插入图片描述
单总线驱动程序、CT107D 单片机考试平台电路原理图以及本题所涉及到的芯片数据手册,可参考计算机上的电子文档。程序流程图及相关工程文件请以考生号命名,并保存在计算机上的考生文件夹中(文件夹名为考生准考证号,文件夹保存在监考员指定位置)。
设计任务及要求
1. 工作模式
设备具有“睡眠风”、“自然风”和“常风”三种工作模式可以通过按键切换,通过
单片机 P34 引脚输出脉宽调制信号控制电机运行状态,信号频率为 1KHz。
1.1 “睡眠风”模式下,对应 PWM 占空比为 20%;
1.2 “自然风”模式下,对应 PWM 占空比为 30%;
1.3 “常风”模式下,对应 PWM 占空比为 70%;
2. 数码管显示
数码管实时显示设备当前工作模式和剩余工作时间(倒计时),如图 2 所示。
在这里插入图片描述
“睡眠风”状态下,对应数码管显示数值为 1,自然风模式下,显示数值为 2,常
风模式下,显示数值为 3。
3. 按键控制
使用 S4、S5、S6、S7 四个按键完成按键控制功能。
2.1 按键 S4 定义为工作模式切换按键,每次按下 S4,设备循环切换三种工作模式。工作过程如下:
在这里插入图片描述
2.2 按键 S5 定义为“定时按键”每次按下 S5,定时时间增加 1 分钟,设备的剩余
工作时间重置为当前定时时间,重新开始倒计时,工作过程如下:
在这里插入图片描述
设备剩余工作时间为 0 时,停止 PWM 信号输出。
2.3 按键 S6 定义为“停止”按键,按下 S6 按键,立即清零剩余工作时间,PWM
信号停止输出,直到通过 S5 重新设置定时时间。
2.4 按键 S7 定义为“室温”按键,按下 S7,通过数码管显示当前室温,数码管显
示格式如图 3 所示,再次按下 S7,返回图 2 所示的工作模式和剩余工作时间显示界面,如此往复。
在这里插入图片描述
室温测量、显示功能不应影响设备正在执行的 PWM 信号输出、停止、模式切
换和计时等功能。
4. LED 指示灯
“睡眠风”模式下,L1 点亮,“自然风”模式下 L2 点亮,“常风”模式下 L3 点亮;
按下停止按键或倒计时结束时,LED 全部熄灭。
5. 电路原理图设计
电机过热检测及驱动电路设计:
假定设备使用的是 12V 直流电机,过热检测传感器输出为小电压信号 Vs,设计过热检测及电机驱动电路,当检测到 Vs 信号幅度大于 10mV 时,电机停止转动,简述电路的工作原理与设计思路,并绘制出电路原理图。

程序代码

主函数

#include"stc15f2k60s2.h"
#include"onewire.h"

typedef unsigned char uchar;
typedef unsigned int uint;

uchar code SMG_duan[]={
    
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
uchar code SMG_wei[]={
    
    0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

sbit PWM=P3^4;

uchar mode_display[8];			   //工作模式显示
uchar temp_display[8];

uchar mode=1;						   //风速模式
uchar temperature;
uchar work_time;
uchar temp_flag;
uchar S5_count;

bit out_flag;
bit led_flag=1;
bit count;						  //计时模式下

void Timer0Init();		
uchar KEY_init();

void main()
{
    
    
  uchar key_val;
  P2=0XA0;P0=0X00;
  P2=0X80;P0=0XFF;

  Timer0Init();
  DS18B20();
  mode_display[0]=0x40; mode_display[2]=0x40; mode_display[3]=0x00;

  temp_display[0]=0x40;	temp_display[1]=SMG_duan[4]; temp_display[2]=0x40;
  temp_display[3]=0x00; temp_display[4]=0x00;	   temp_display[7]=0x39;
  while(1)
  {
    
    
     
	 temperature=temp_get();
	 temp_display[5]=SMG_duan[temperature%100/10];
	 temp_display[6]=SMG_duan[temperature%10];

	 mode_display[1]=SMG_duan[mode];
	 mode_display[4]=SMG_duan[0];
	 mode_display[5]=SMG_duan[work_time/100];
	 mode_display[6]=SMG_duan[work_time%100/10];
	 mode_display[7]=SMG_duan[work_time%10];

	 key_val=KEY_init();
	 switch(key_val)
	 {
    
    
	    case 4:
			   led_flag=1;
		       mode++;
			   if(mode==4)
			   mode=1;
			   break;
		case 5:
			   led_flag=1;
			   count=1;
			   S5_count++;
			   if(S5_count==3)
			   {
    
    
				  S5_count=0;
				  work_time=0;
			   }
			   if(S5_count==1)
			   work_time=60;
			   if(S5_count==2)
			   work_time=120;
			   break;
		case 6:
		       led_flag=0;
			   work_time=0;
			   out_flag=0;
			   break;
		case 7:
			   led_flag=1;
			   temp_flag++;
			   if(temp_flag==2)
			   temp_flag=0;
			   break;

	 }
	 if(work_time>0)
	 {
    
    
	   out_flag=1;
	 }
	 if(count)
	 {
    
    
		 if(work_time==0)
		 {
    
     
		   out_flag=0;
		   led_flag=0;
		 }
	 }
	if(led_flag)
	{
    
    
	  switch(mode)
	  {
    
    
	     case 1:
		 P2=0X80;P0=~0X01;P2=0X00;
		 break;
		 case 2:
		 P2=0X80;P0=~0X02;P2=0X00;
		 break;
		 case 3:
		 P2=0X80;P0=~0X04;P2=0X00;
		 break;     
	  }
	}
	 if(led_flag==0)
	 {
    
    
	   P2=0X80;P0=0xff;P2=0X00;
	 }
  }
}

#define key_input P3
#define key_state0 0
#define key_state1 1
#define key_state2 2
uchar KEY_init()
{
    
    
  static uchar key_state=0;
  uchar key_press,key_return=0;

  key_press=key_input&0X0F;

  switch(key_state)
  {
    
    
     case key_state0:
		  if(key_press!=0x0f)
		  key_state=key_state1;
		  break;
	 case key_state1:
		  if(key_press!=0x0f)
		  {
    
    
		    if(key_press==0x0e) key_return=7;
			if(key_press==0x0d) key_return=6;
			if(key_press==0x0b) key_return=5;
			if(key_press==0x07) key_return=4;

			key_state=key_state2;
		  }
		  else 
		  key_state=key_state0;
		  break;
	 case key_state2:
		  if(key_press==0x0f)
		  key_state=key_state0;
		  break;
  }

  return key_return;
}

void Timer0Init(void)		//100微秒@11.0592MHz
{
    
    
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xAE;		//设置定时初值
	TH0 = 0xFB;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA=1;
	ET0=1;
}
void Timer0() interrupt 1
{
    
    
   uchar i;
   static uint SMG_count,PWM_count=0,work_count=0;
   SMG_count++;  PWM_count++;  work_count++;

   if(SMG_count==30)
   {
    
    
	  SMG_count=0;
	  P2=0XC0;P0=0X00;P2=0X00;
	  P2=0XC0;P0=SMG_wei[i];P2=0X00;
	  if(temp_flag==1)
	  {
    
    
		P2=0XE0;P0=~temp_display[i];P2=0X00;
	  }
	  else
	  {
    
    
	    P2=0XE0;P0=~mode_display[i];P2=0X00;
	  }
	  i++;
	  if(i==8)
	  i=0;	  
   }
   if(work_count==10000)
   {
    
    
	 work_count=0;	 
	 if(work_time>0)
	 work_time--;
   }
   if(out_flag)
   {
    
    
     if(mode==1)
	 {
    
    
	  if(PWM_count==8)
	  PWM=1;
	  if(PWM_count==10)
	  {
    
    
	    PWM=0;
		PWM_count=0;
	  }
	 }

	 if(mode==2)
	 {
    
    
	  if(PWM_count==7)
	  PWM=1;
	  if(PWM_count==10)
	  {
    
    
	    PWM=0;
		PWM_count=0;
	  }
	 }

	 if(mode==3)
	 {
    
    
	  if(PWM_count==3)
	  PWM=1;
	  if(PWM_count==10)
	  {
    
    
	    PWM=0;
		PWM_count=0;
	  }
	 }
   }
}

DS18B20模块

#include "onewire.h"

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

void delay(unsigned char ms);
void Delay500us();		//@11.0592MHz
void Delay100us();		//@11.0592MHz
void Delay60us();		//@11.0592MHz
void Delay15us();		//@11.0592MHz

//DS18B20芯片初始化
bit Init_DS18B20(void)
{
    
    
	bit initflag = 0;
	DQ = 1;
	Delay_OneWire(12);
	DQ = 0;
	Delay500us(); 
	DQ = 1;
	Delay_OneWire(10); 
	initflag = DQ;    
	Delay_OneWire(5);
  
	return initflag;
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
    
    
	unsigned char i;
	for(i=0;i<8;i++)
	{
    
    
		DQ = 0;
		DQ = dat&0x01;
		Delay60us();		
		DQ = 1;
		Delay15us();
		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;
		_nop_();
		_nop_();
		_nop_();
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
    
    
			dat |= 0x80;
		}	    
		Delay100us();
	}
	return dat;
}

void DS18B20()
{
    
    
  Init_DS18B20();
  delay(1);
  Write_DS18B20(0xcc);
  Write_DS18B20(0x44);

  Init_DS18B20();
  delay(1);
  Write_DS18B20(0xcc);
  Write_DS18B20(0xbe);  
}
int temp_get()
{
    
    
  unsigned char low,high;
  unsigned char temp;

  DS18B20();
  low=Read_DS18B20();
  high=Read_DS18B20();

  temp=high<<4;
  temp|=low>>4;
  return temp;
}
void Delay500us()		//@11.0592MHz
{
    
    
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 6;
	j = 93;
	do
	{
    
    
		while (--j);
	} while (--i);
}
void Delay100us()		//@11.0592MHz
{
    
    
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 2;
	j = 15;
	do
	{
    
    
		while (--j);
	} while (--i);
}

void Delay60us()		//@11.0592MHz
{
    
    
	unsigned char i, j;

	i = 1;
	j = 162;
	do
	{
    
    
		while (--j);
	} while (--i);
}

void Delay15us()		//@11.0592MHz
{
    
    
	unsigned char i;

	i = 39;
	while (--i);
}

void delay(unsigned char ms)
{
    
    
   int i,j;
   for(i=0;i<ms;i++)
    for(j=850;j>0;j--);
}

以上就是代码全部内容,欢迎交流,共同学习~

猜你喜欢

转载自blog.csdn.net/qq_43280087/article/details/104735093