蓝桥杯第六届省赛模拟试题--“简易温度采集与控制装置”

题目要求

功能简述
模拟“温度采集与控制装置” 用于实现温度的实时监测与控制。单片机采集DS18B20温度传感器的输出信号, 并送到数码管进行显示; 通过传感器得到的温度数据将与用户设定温度上限、下限值做比较, 再由单片机启动控制或报警电路。系统硬件部分主要由单片机最小系统、数码管显示、 DS18B20 温度传感器、矩阵键盘等模块组成。 系统组成框图如图 1所示:
在这里插入图片描述
单总线驱动程序、 CT107D 单片机考试平台电路原理图以及本题所涉及到的芯片数据手册,可参考计算机上的电子文档。程序流程图及相关工程文件请以考生号命名,并保存在计算机上的考生文件夹中(文件夹名为考生准考证号,文件夹位于 Windows 桌面上)。
设计任务及要求
1. 温度检测
温度检测采用 DS18B20 温度传感器, 数据经过单片机处理后,与用户设定的温度上限(TMAX)和温度下限(TMIN)比较,确定当前温度所处的区间, 数码管温度显示格式如图 2 所示:
在这里插入图片描述
关于温度区间的说明:
温度区间 0: 当前温度<TMIN
温度区间 1: TMIN≤当前温度≤TMAX
温度区间 2: 当前温度>TMAX
可设定的最大温度区间: 0℃~99℃
2. 用户输入-3X4 矩阵键盘
通过矩阵键盘设定系统的工作参数,各个按键的功能定义如图 3 所示:
在这里插入图片描述
“设置”按键按下后,进入工作参数设定界面,如图 4 所示, 依次按下设定的数值,再次按下“设置” 按键, 保存当前输入的数据,并退出工作参数设定界面。
在这里插入图片描述
以设定 TMAX 为 35 摄氏度, TMIN为 25 摄氏度为例说明参数设定过程:按下“设置”按键,然后依次按下数字按键“3” “5” “2” “5” 如图 5 所示,再次按下“设置” 按键, 完成参数设定, 并退出参数设定界面。在输入过程中,按下“清除” 按键, 将清除当前输入数据, 若设定工作参数错误,如 TMAX<TMIN, L2 常亮,修正错误设定并保存参数后, L2 熄灭。
在这里插入图片描述
3. 执行机构
执行机构由指示灯 L1 和继电器组成,用于报警和连接外部高低温执行机构。
3.1 实时温度处在温度区间 0, 继电器关闭,指示灯 L1 以 0.8 秒为间隔闪烁;
3.2 实时温度处在温度区间 1, 继电器关闭,指示灯 L1 以 0.4 秒为间隔闪烁;
3.3 实时温度处在温度区间 2, 继电器打开,指示灯 L1 以 0.2 秒为间隔闪烁。
4. 初始化状态说明
系统默认的温度上限(TMAX)为 30℃, 温度下限(TMIN)为 20℃, 可以通过矩阵键盘修改。
5. 电路原理图设计
假定一个光敏电阻, 在光线充足的状态下, 阻值为 5 KΩ ,挡光状态下阻值≥45KΩ,使用简单阻容元件、晶体管、运算放大器等设计一个光敏电阻开关电路, 挡光状态下电路驱动 5V 继电器 K1 吸合, 反之, 继电器断开。 设计过程中, 需要考虑信号抖动等因素, 简述电路的工作原理与设计思路,并绘制出电路原理图。

程序代码

主函数

#include<stc15f2k60s2.h>
#include "temperature.h"

typedef unsigned char uchar;
typedef unsigned int uint;

sbit beep=P0^6;
sbit Realy=P0^4;

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


uchar set_display[8];
uchar temp_display[8];
uchar temp_val[8];

uchar temperature;			//实时温度
uchar temp_max=50;			   //温度上限
uchar temp_min=20;			   //温度下限

uchar key_count;			 //按键计数,在设置温度上下限时使用
uchar key_return;			//键值
uchar led_flag;				//led闪烁频率选择

uchar set_flag;				//设置标志

bit blink_flag;				//闪烁
bit error_flag;				//温度下限高于上限,错误位
bit key_flag;			

void Timer0Init();
void delay(uint ms);
uchar Key_init();
void display1();		
void Led_blink();

void main()
{
    
    
   uchar key_val;

   P2=0XA0;P0=0X00;
   P2=0X80;P0=0XFF;
   Timer0Init();
   temp_display[0]=0x40; temp_display[2]=0x40; temp_display[3]=0x00;
   temp_display[4]=0x00; temp_display[5]=0x00;

   set_display[0]=0x40;	 set_display[5]=0x40;
   set_display[3]=0x00;  set_display[4]=0x00;
  
   while(1)
   {
    
    
	  temperature=temp_get();
	  	  
	  temp_display[6]=SMG_duan[temperature%100/10];
	  temp_display[7]=SMG_duan[temperature%10];	 
	   
	  temp_display[1]=SMG_duan[led_flag];
	  temp_display[1]=SMG_duan[led_flag];
	  temp_display[1]=SMG_duan[led_flag]; 
	  //display1();	
	  if(temperature<temp_min)
	  {
    
    
	    led_flag=0;	        
	  }
	  if((temp_min<=temperature)&&(temperature<=temp_max))
	  {
    
    
	    led_flag=1;	    	    
	  }
	  if(temperature>temp_max)
	  {
    
    
	    led_flag=2;		  
	  }
	  
	  if(key_count==2)
	     key_count=5;	  
	  if(key_count>7)
	     key_count=8;

	  if(key_flag)
	  {
    
    
	     
	     key_flag=0;
	     key_val=Key_init();
	   switch(key_val)
	   {
    
    
	    case 4: key_count++; set_display[key_count]=SMG_duan[9];temp_val[key_count]=9;		
		        break;
		case 5: key_count++; set_display[key_count]=SMG_duan[6];temp_val[key_count]=6;
		        break;
		case 6: key_count++; set_display[key_count]=SMG_duan[3];temp_val[key_count]=3;
		        break;
		case 7: key_count++; set_display[key_count]=SMG_duan[0];temp_val[key_count]=0;
		        break;
		case 8: set_flag++;									  //设置
				if(set_flag==2)
				{
    
    
				   set_flag=0;
				   temp_max=temp_val[1]*10+temp_val[2];
				   temp_min=temp_val[6]*10+temp_val[7];
				}
				if(temp_min>temp_max)
				{
    
    
				   P2=0X80;P0=0xfd;P2=0X00;
				   error_flag=1;
				}
				else
				{
    
    
				   P2=0X80;P0=0xff;P2=0X00;
				   error_flag=0;
				}
		        break;
		case 9:  key_count++; set_display[key_count]=SMG_duan[7];temp_val[key_count]=7;
		        break;
		case 10: key_count++; set_display[key_count]=SMG_duan[4];temp_val[key_count]=4;
		        break;
		case 11: key_count++; set_display[key_count]=SMG_duan[1];temp_val[key_count]=1;
		        break;
		case 12: key_count=0;
		         set_display[1]=0x00;
				 set_display[2]=0x00;
				 set_display[6]=0x00;
				 set_display[7]=0x00;
		        break;
		case 13: key_count++; set_display[key_count]=SMG_duan[8];temp_val[key_count]=8;
		        break;
		case 14: key_count++; set_display[key_count]=SMG_duan[5];temp_val[key_count]=5;
		        break;		        
		case 15: key_count++; set_display[key_count]=SMG_duan[2];temp_val[key_count]=2;
		         break;
		case 16:break;
		case 17:break;
		case 18:break;
		case 19:break;
	  }
	 }
	  if(led_flag==0)
	  {
    
    
		P2=0XA0;Realy=0;beep=0;P2=0X00;			
	  }
	  if(led_flag==1)
	  {
    
    
		P2=0XA0;Realy=0;beep=0;P2=0X00;
	  }
	  if(led_flag==2)
	  {
    
    
		P2=0XA0;Realy=1;beep=0;P2=0X00;	
	  }
   }
}
void Timer0Init()		//1毫秒@11.0592MHz
{
    
    
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xCD;		//设置定时初值
	TH0 = 0xD4;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时

	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xCD;		//设置定时初值
	TH1 = 0xD4;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;

	EA=1;
	ET0=1;
	ET1=1;
}

void Timer0() interrupt 1
{
    
    
   static int key=0,led=0;
     key++;
	 led++;
   if(key>10)
   {
    
    
	  key=0;
	  key_flag=1;
   }
   TR0=0;
   if(error_flag==0)
   {
    
    
     if(led_flag==0)
     {
    
    
   	  if(led>800)
	  {
    
    
	    led=0;
		blink_flag=~blink_flag;		
	  }
	    if(blink_flag)
	     {
    
    
	      P2=0X80;P0=0xfe;P2=0X00;
	     }
	    else
	     {
    
    
		  P2=0X80;P0=0Xff;P2=0X00;
	     }
     }
     if(led_flag==1)
     {
    
    
   	  if(led>400)
	  {
    
    
	    led=0;
		blink_flag=~blink_flag;		
	  }
	  if(blink_flag)
	    {
    
    	     
	     P2=0X80;P0=0xfe;P2=0X00;
	    }
	    else
	   {
    
    
		 P2=0X80;P0=0Xff;P2=0X00; 
	   }
     }
    
     if(led_flag==2)
     {
    
    
   	  if(led>200)
	  {
    
    
	    led=0;
		blink_flag=~blink_flag;		
	  }
	  if(blink_flag)
	    {
    
    
	     P2=0X80;P0=0xfe;P2=0X00;
	    }
	    else
	    {
    
    
		 P2=0X80;P0=0Xff;P2=0X00;  
	    }
     }    
   }
   TR0=1;   	     
}
void Timer1() interrupt 3
{
    
    
   
   uchar i;
   static unsigned int SMG_count=0;
   TL1 = 0xCD;		//设置定时初值
	TH1 = 0xD4;
   //TR1=0;
   SMG_count++;
   
   if(SMG_count==3)
   {
    
    
   	  SMG_count=0;
	  P2=0XC0;P0=0X00;P2=0X00;
	  P2=0XC0;P0=SMG_wei[i];P2=0X00;
	  if(set_flag==0)
	  {
    
    
	    P2=0XE0;P0=~temp_display[i];P2=0X00;
	  }
	  else
	  {
    
    
		P2=0XE0;P0=~set_display[i];P2=0X00;
	  }
	  i++;
	  if(i==8)
	  i=0;
   }   
}

#define KEY P3
#define NO_KEY 0XFF			   //无按键按下
#define key_state0 0		   //判断按键是否按下
#define key_state1 1		   //确认按下
#define key_state2 2		  //释放

uchar Key_init()
{
    
    
   static uchar key_state=0;
   uchar key_return=0,key_temp;
   uchar key1,key2;

   P30=0;P31=0;P32=0;P33=0;P34=1;P35=1;P42=1;P44=1;
   if(P44==0) key1=0x70;
   if(P42==0) key1=0xb0;
   if(P35==0) key1=0xd0;
   if(P34==0) key1=0xe0;
   if((P34==1)&&(P35==1)&&(P42==1)&&(P44==1))
   key1=0xf0;

   P30=1;P31=1;P32=1;P33=1;P34=0;P35=0;P42=0;P44=0;
   if(P30==0) key2=0x0e;
   if(P31==0) key2=0x0d;
   if(P32==0) key2=0x0b;
   if(P33==0) key2=0x07;
   if((P30==1)&&(P31==1)&&(P32==1)&&(P33==1))
   key2=0x0f;
   key_temp=key1|key2;

   switch(key_state)
   {
    
    
	  case key_state0:
	  if(key_temp!=0xff)
	  key_state=key_state1;
	  break;
	  case key_state1:
	  if(key_temp!=0xff)
	  {
    
    
	     switch(key_temp)
		 {
    
    
		    case 0x77: key_return=4;break;
			case 0x7b: key_return=5;break;
			case 0x7d: key_return=6;break;
			case 0x7e: key_return=7;break;

			case 0xb7: key_return=8;break;
			case 0xbb: key_return=9;break;
			case 0xbd: key_return=10;break;
			case 0xbe: key_return=11;break;

			case 0xd7: key_return=12;break;
			case 0xdb: key_return=13;break;
			case 0xdd: key_return=14;break;
			case 0xde: key_return=15;break;

			case 0xe7: key_return=4;break;
			case 0xeb: key_return=4;break;
			case 0xed: key_return=4;break;
			case 0xee: key_return=4;break;
			
		 }
		 key_state=key_state2;
	  }
	  else
	    key_state=key_state0;
	  break;
	  case key_state2:
	       if(key_temp==0xff)
		   key_state=key_state0;
		   break;

   }
   return key_return;
}

DS18B20温度传感器模块

#include "temperature.h"


void Delay500us();
void Delay15us();
void Delay60us();		
void Delay100us();

void Delay_OneWire(unsigned int t)
{
    
    
  while(t--);
}

void delayms(unsigned int ms)
{
    
    
  int i,j;
  for(i=0;i<=ms;i++)
   for(j=845;j>0;j--);
}

//DS18B20芯片初始化
bit Init_DS18B20(void)
{
    
    
	bit initflag = 0;
	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;
		Delay15us();
		DQ = dat&0x01;
		Delay60us();
		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;
		_nop_();
		_nop_();
		_nop_();
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
    
    
			dat |= 0x80;
		}	    
		Delay100us();
	}
	return dat;
}

void DS18b20()
{
    
    
   Init_DS18B20();
   delayms(1);
   Write_DS18B20(0xcc);
   Write_DS18B20(0x44);

   Init_DS18B20();
   delayms(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 Delay15us()		//@11.0592MHz
{
    
    
	unsigned char i;

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

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

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

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

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


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

猜你喜欢

转载自blog.csdn.net/qq_43280087/article/details/104630638
今日推荐