蓝桥杯第三届省赛模拟试题

题目要求

设计任务及要求

  1. 数码管显示单元
    通过 8 位共阳数码管显示温度信息, 包括设定的温度上下限数值和当前温度值,显示格式如图 2 所示:
    在这里插入图片描述
  2. 温度测量单元
    通过 DS18B20 数字温度芯片测量环境温度。
  3. 按键控制单元
    独立按键 S4 设定为“加上限” 按键;每按下一次,温度上限值增加 1℃;
    独立按键 S5 设定为“加下限”按键;每按下一次,温度下限值增加 1℃;
    独立按键 S6 设定为“减上限”按键; 每按下一次,温度上限值减少 1℃;
    独立按键 S7 设定为“减下限”按键;每按下一次,温度下限值减少 1℃。
  4. EEPROM 记录单元
    系统通过 AT24C02 存储温度信息, AT24C02 内部存储地址 0x00 和 0x01 分别存储温度上下限数据信息;温度上下限数据可通过外部按键进行修改,并通过数码管实时显示。 数据存储格式如图 3 所示:
    在这里插入图片描述
  5. 直流电机驱动电路设计
    设计一个直流电机驱动电路与单片机 P34 引脚连接。
  6. 温控单元
    若当前温度数值超过 EEPROM 中存储的温度上限数据, 通过单片机 P34 口产生周期为 1KHz 占空比为 30%的 PWM 信号驱动直流电机工作。 待温度恢复到上下限阈值内时, P34 口输出高电平,直流电机停止工作若当前温度低于 EEPROM 中存储的温度下限数据, 继电器打开,当温度恢复到上3下限阈值内时,继电器自动关闭。
  7. 系统初始状态说明
    上、下限温度值需要设定在 0℃到 99℃范围内,下限值不大于上限值。 系统上电后,从 EEPROM 中读取温度上、下限数值,并实时显示当前温度。

程序代码

主函数

#include<stc15f2k60s2.h>
#include "onewire.h"
#include "iic.h"

typedef unsigned char uchar;
typedef unsigned int uint;

sbit PWM=P3^4;
sbit dealy=P0^4;
sbit beep=P0^6;
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};

uchar temperature;
uchar max=30,min=23;   //极限值
uchar limit_up=30,limit_down=23;
uchar temp_display[8];

uchar key_init();
void Timer0Init();		//1毫秒@11.0592MHz

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

   Timer0Init();
   DS18B20();
   temp_display[4]=0x00;  temp_display[5]=0x00;
   while(1)
   {
    
    
      temperature=temp_get();
	  
	  ET0=0;	  
	  max=Read(0x00);				 
	  min=Read(0x01);
	  limit_up=Read(0x00);
	  limit_down=Read(0x01);
	 	
	  ET0=1;
	  temp_display[0]=SMG_duan[max/10];	 temp_display[1]=SMG_duan[max%10];
	  temp_display[2]=SMG_duan[min/10];  temp_display[3]=SMG_duan[min%10];
	  temp_display[6]=SMG_duan[temperature%100/10];  temp_display[7]=SMG_duan[temperature%10];

	  key_val=key_init();
	  switch(key_val)
	  {
    
    
	     case 4:
		 		if(limit_up<99)
		        limit_up++;
				Write(0x00,limit_up);
				break;								//加上限
		 case 5:
				if(limit_down<99)
		        limit_down++;
				Write(0x01,limit_down);							//加下限
				break;
		 case 6:
		 		if(limit_up>0)
		 		limit_up--;
				Write(0x00,limit_up);
		 		break;
		 case 7:
		 		if(limit_down>0)
		 		limit_down--;
				Write(0x01,limit_down);
		 		break;
	  }
	  if(temperature>limit_up)
	  {
    
    
		PWM=1;
	  }
	  if(temperature<limit_down)
	  {
    
    
	     P2=0XA0;
		 dealy=1;
		 beep=0;
	  }
      if((limit_down<=temperature)&&(temperature<=limit_up))
	  {
    
    
	     P2=0XA0;
		 dealy=0;
		 beep=0;
		 PWM=0;
	  }
	  
   }
}

#define KEY P3
#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_press;
   key_press=KEY&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()		//100us @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=0,PWM_count=0;
   SMG_count++,PWM_count++;
   if(SMG_count==30)
   {
    
    
	  SMG_count=0;
	  P2=0XC0;P0=0X00;
	  P2=0XC0;P0=SMG_wei[i];
	  P2=0XE0;P0=~temp_display[i];
	  i++;
	  if(i==8)
	  i=0;
   }
   if(PWM_count==7)
   {
    
    
	  PWM=1;
   }
   if(PWM_count==10)
   {
    
    
	  PWM=0;
   }
}

DS18B20温度传感器

#include "onewire.h"
#include "intrins.h"
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
    
    
  while(t--);
}
void Delay500us();
void Delay100us();
void Delay60us();
void Delay15us();

void delayms(unsigned char ms)
{
    
    
   int i,j;
   for(i=0;i<ms;i++)
     for(j=850;j>0;j--);
}
//DS18B20芯片初始化
bit Init_DS18B20(void)
{
    
    
	bit initflag = 0;
	DQ = 1;
	Delay_OneWire(12);
	DQ = 0;
	Delay500us(); 
	DQ = 1;
	Delay15us(); 
	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;		
		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;
		}	    
		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 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);
}

EEPROM

/*
  程序说明: IIC总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台(12MHz)
  日    期: 2011-8-9
*/

#include "iic.h"

void iic_delay(unsigned char i)
{
    
    
    do
	{
    
    
	   _nop_();
	}while(i--);
}
void IIC_Start(void)
{
    
    
	SDA = 1;
	SCL = 1;
	iic_delay(5);
	SDA = 0;
	iic_delay(5);
	SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
    
    
	SDA = 0;
	SCL = 1;
	iic_delay(5);
	SDA = 1;
}
/*
//应答位控制
void IIC_Ack(unsigned char ackbit)
{
	if(ackbit) 
	{	
		SDA = 0;
	}
	else 
	{
		SDA = 1;
	}
	iic_delay(5);
	SCL = 1;
	iic_delay(5);
	SCL = 0;
	SDA = 1; 
	iic_delay(5);
}
*/
//等待应答
bit IIC_WaitAck(void)
{
    
    
	SDA = 1;
	iic_delay(5);
	SCL = 1;
	iic_delay(5);
	if(SDA)    
	{
    
       
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else  
	{
    
     
		SCL = 0;
		return 1;
	}
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    
    
	unsigned char i;
	for(i=0;i<8;i++)
	{
    
       
		if(byt&0x80) 
		{
    
    	
			SDA = 1;
		}
		else 
		{
    
    
			SDA = 0;
		}
		iic_delay(5);
		SCL = 1;
		byt <<= 1;
		iic_delay(5);
		SCL = 0;
	}
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
    
    
	unsigned char da;
	unsigned char i;
	
	for(i=0;i<8;i++)
	{
    
       
		SCL = 1;
		iic_delay(5);
		da <<= 1;
		if(SDA) 
		da |= 0x01;
		SCL = 0;
		iic_delay(5);
	}
	return da;
}

void Write(unsigned char add,unsigned char dat)
{
    
    
   IIC_Start();
   IIC_SendByte(0xa0);
   IIC_WaitAck();
   IIC_SendByte(add);
   IIC_WaitAck();
   IIC_SendByte(dat);
   IIC_WaitAck();
   IIC_Stop();
}

unsigned char Read(unsigned char dat)
{
    
    
   unsigned char  temp;
   IIC_Start();
   IIC_SendByte(0xa0);						 //写入  为0
   IIC_WaitAck();
   IIC_SendByte(dat);
   IIC_WaitAck();

   IIC_Start();
   IIC_SendByte(0xa1);					   //读出为1
   IIC_WaitAck();
   temp=IIC_RecByte();
   IIC_Stop();

   return temp;
}

以上就是代码的全部内容,欢迎大家批评指正,共同学习~

猜你喜欢

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