基于51单片机的温度控制器数码管显示仿真

仿真图:

在这里插入图片描述

功能简介:

单片机采用AT89C51,最小系统由晶振和复位电路组成
显示部分采用4位数码管用于显示该项目的参数信息
三个功能按键,分别是设置、加、减等功能,可以设置高位和低位阈值,支持低位负数阈值设置
采用DS18B20作为温度传感器,支持负数温度值显示
具有LED和蜂鸣器组成的声光报警电路,当温度值超过阈值时触发报警

芯片/模块的特点:

DS18B20特点:

  1. 单总线接口:DS18B20使用单总线接口进行通信,只需要一个引脚就可以连接多个传感器,简化了电路设计和连接。
  2. 数字输出:DS18B20以数字形式输出温度值,不需要额外的模数转换器。它使用12位的分辨率来表示温度值,可以实现高精度的温度测量。
  3. 高精度:DS18B20可以提供从-55°C到+125°C的温度测量范围,并具有±0.5°C的温度精度。因此,在许多应用中,它可以提供可靠和准确的温度测量结果。
  4. 多功能性:除了测量温度,DS18B20还可以执行其他功能,如温度报警功能。它可以设置上下限温度阈值,并在温度超过或低于这些阈值时触发报警。
  5. 低功耗:DS18B20采用低功耗设计,工作电流极低,只需要很少的能量来进行温度测量和通信。
  6. 耐用性:DS18B20具有良好的耐用性和可靠性,其封装材料和结构设计使其适用于各种环境条件下的应用。

主程序:

#include "reg52.h"  
//---重定义关键词---//
#define uchar unsigned char
#define uint unsigned int


//--定义使用的IO口--//
sbit DQ =P1^1;
sbit BEEP=P3^7;               //定义蜂鸣器   
sbit ALAM=P1^0;                //定义灯光报警
sbit SET=P3^1;                 //定义调整键
sbit ADD=P3^3;
sbit DEC=P3^2;

bit shanshuo_st;                            //闪烁间隔标志
bit beep_st;                                     //蜂鸣器间隔标志
char shangxian=38;                  //上限报警温度,默认值为38
char xiaxian=-6;                   //下限报警温度,默认值为-6
uchar set_st=0;                             //状态标志

uchar m;                    //温度值全局变量(整数)
char Signed_Current_temp;
uchar n;                             //温度值全局变量(小数)

char num=0;
uchar DisplayData[8];

uchar code DSY_CODE[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
uchar data DSY_IDX[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar code df_table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
void Alarm();

/*******************************************************************************
* 函 数 名         : delay
* 函数功能		   : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(uint i)
{
	while(i--);	
}

void Delay1ms(uint y)
{
	uint x;
	for( ; y>0; y--)
	{
		for(x=110; x>0; x--);
	}
}

void datapros(void) 	 
{
   
	
	DisplayData[1] = DSY_CODE[m/10];
	DisplayData[2] = DSY_CODE[m%10]&0x7F;
	DisplayData[3] = DSY_CODE[n];

}
//=====================================================================================
//=====================================================================================
//=====================================================================================

/*****延时子程序*****/
void Delay_DS18B20(int num)
{
  while(num--) ;
}
/*****初始化DS18B20*****/
void Init_DS18B20(void)
{
  unsigned char x=0;
  DQ = 1;         //DQ复位
  Delay_DS18B20(28);    //稍做延时
  DQ = 0;         //单片机将DQ拉低
  Delay_DS18B20(80);   //精确延时,大于480us
  DQ = 1;         //拉高总线
  Delay_DS18B20(14);
  x = DQ;           //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
  Delay_DS18B20(20);
}
/*****读一个字节*****/
unsigned char ReadOneChar(void)
{
  unsigned char i=0;
  unsigned char dat = 0;
  for (i=8;i>0;i--)
  {
    DQ = 0;     // 给脉冲信号
    dat>>=1;
    DQ = 1;     // 给脉冲信号
    if(DQ)
    dat|=0x80;
    Delay_DS18B20(4);
  }
  return(dat);
}
/*****写一个字节*****/
void WriteOneChar(unsigned char dat)
{
  unsigned char i=0;
  for (i=8; i>0; i--)
  {
    DQ = 0;
    DQ = dat&0x01;
    Delay_DS18B20(5);
    DQ = 1;
    dat>>=1;
  }
}
/*****读取温度*****/
void ReadTemperature(void)
{
  unsigned char a=0;
  unsigned char b=0;
  //unsigned int t=0;

  uchar ng=0;
  //float tt=0;
  Init_DS18B20();
  WriteOneChar(0xCC);  //跳过读序号列号的操作
  WriteOneChar(0x44);  //启动温度转换
  	Delay1ms(15);

  Init_DS18B20();
  WriteOneChar(0xCC);  //跳过读序号列号的操作
  WriteOneChar(0xBE);  //读取温度寄存器
  a=ReadOneChar();     //读低8位
  b=ReadOneChar();    //读高8位
    if((b&0XF8)==0XF8)
   {
      b=~b;
      a=~a+1;
      if(a==0X00)b++;
      ng=1;               //为负数
     
   }
    n=df_table[a&0X0F];
   if(ng==1)
   {
       DisplayData[0] = 0xbf;
   }
   else
   {
      DisplayData[0] = 0xff;
   }
   m=((a&0Xf0)>>4)|((b&0X07)<<4);
   Signed_Current_temp=ng?-m:m;
  

  //t=b;                                   //高8位转移到t
 // t<<=8;                           //t数据左移8位
 // t=t|a;                           //将t和a按位或,得到一个16位的数
  //tt=t*0.0625;                   //将t乘以0.0625得到实际温度值(温度传感器设置12位精度,最小分辨率是0.0625)
 // t= tt*10+0.5;     //放大10倍(将小数点后一位显示出来)输出并四舍五入
  //return(t);                   //返回温度值
}

/*****读取温度*****/
void check_wendu(void)
{
    //uint a,b,c,i;
     uint i;
    for( i=2;i>0;i--){          //重复3次
	     ReadTemperature();                          //获取温度值
        //a=c/100;                                                     //计算得到十位数字
        //b=c/10-a*10;                                            //计算得到个位数字
       // m=c/10;                                                      //计算得到整数位
       // n=c-a*100-b*10;                                    //计算得到小数位
       // if(m<0){m=0;n=0;}                                   //设置温度显示上限
        if(m>99){m=99;n=9;}                                   //设置温度显示上限    
	 } 
}

/*******************************************************************************
* 函数名         :DigDisplay()
* 函数功能		 :数码管显示函数
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/
void DigDisplay()
{

	uint i;
	P0=0xff;
	P2=0x00;
	for(i=30;i>0;i--){
	
				P2=DSY_IDX[0];
					P0=DisplayData[0];//发送数据
		delay(150); //间隔一段时间扫描	
		P0=0xff;//消隐
	
			P2=DSY_IDX[1]; 
				P0=DisplayData[1];//发送数据
		delay(150); //间隔一段时间扫描	
		P0=0xff;//消隐
		
				P2=DSY_IDX[2];
					P0=DisplayData[2];//发送数据
		delay(150); //间隔一段时间扫描	
		P0=0xff;//消隐
			
				P2=DSY_IDX[3];
					P0=DisplayData[3];//发送数据
		delay(250); //间隔一段时间扫描	
		P0=0xff;//消隐
	
	 Alarm();   //报警检测
	}
 

}

/*****报警子程序*****/
void Alarm()
{
        float tem,xiaoshu;
		  tem=Signed_Current_temp;
		  xiaoshu=n;
		  xiaoshu=xiaoshu*0.1;
        if(((tem+xiaoshu)>=shangxian)||((tem-xiaoshu)<xiaxian))
        {
		  
				 BEEP=!BEEP;
                ALAM=0;
               
        }
        else
        {
                BEEP=1;
                ALAM=1;
        }
}

/*****显示报警温度子程序*****/
void Disp_alarm(char baojing)
{
	uint i;
	P0=0xff;
	P2=0x00;

   for(i=2;i>0;i--){
       P2=DSY_IDX[0];
      if(set_st==1)P0=0x89;       //上限H
        else if(set_st==2)P0=0xC7; //下限L标示
        
        delay(100);
    	P0=0xff;//消隐

 P2=DSY_IDX[1];
 if(baojing<0)
   {
       P0 = 0xbf;
		 baojing=-baojing;
   }
   else
   {
      P0 = 0xff;

   }
 delay(100);
	 P0=0xff;//消隐

     P2=DSY_IDX[2];
     P0=DSY_CODE[baojing/10];
     delay(100);
	 P0=0xff;//消隐

     P2=DSY_IDX[3];
     P0=DSY_CODE[baojing%10];
     delay(200);
	 P0=0xff;//消隐

    }

}



/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	
   EA=1;
  
  IT0=1;     //外部中断的触发方式,下降沿触发      
   IT1=1;
		check_wendu();
		Delay1ms(900); 
		check_wendu();
		datapros();
	 BEEP=1;
    ALAM=1;
	while(1)
	{
        if(SET==0)
      {
          delay(2000);
          do{}while(SET==0);
          set_st++;shanshuo_st=1;
          if(set_st>2)set_st=0;
      }
       if(set_st==0)
      {
		 BEEP=1;
   
          EX0=0;    //关闭外部中断0
          EX1=0;    //关闭外部中断1
       	   check_wendu();
	    datapros();
    	DigDisplay();
        //Alarm();   //报警检测
       }
       else if(set_st==1)
      {
          BEEP=1;    //关闭蜂鸣器
          ALAM=1;
          EX0=1;    //开启外部中断0
          EX1=1;    //开启外部中断1
         
         if(shanshuo_st) {Disp_alarm(shangxian);}
      }
      else if(set_st==2)
      {
          BEEP=1;    //关闭蜂鸣器
          ALAM=1;
          EX0=1;    //开启外部中断0
          EX1=1;    //开启外部中断1
         
          if(shanshuo_st) {Disp_alarm(xiaxian);}
      }

   }

}



/*****外部中断0服务程序*****/
void int0(void) interrupt 0
{

       EX0=0;      //关外部中断0
     if(DEC==0&&set_st==1)
      {
          do{
                Disp_alarm(shangxian);
        }while(DEC==0);
         
          shangxian--;
          if(shangxian<xiaxian)shangxian=xiaxian;
      }
      else if(DEC==0&&set_st==2)
     {
          do{
                Disp_alarm(xiaxian);
        }while(DEC==0);
        
         xiaxian--;
          //if(xiaxian<0)xiaxian=0;
     }
}

设计文件:
链接:https://pan.baidu.com/s/1Z83iGcX9S9UORFQQ6GvTCg?pwd=z3oc

  • 4
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 基于51单片机的电子时钟项目需要通过Keil编写程序,并使用Proteus进行仿真电路搭建。该项目主要包括以下几个步骤: 1. 硬件搭建:按照电子时钟的设计需求,连接51单片机和相关的电子元件,如晶体振荡器、数码管、按键等。通过Proteus软件,可以将这些元件连接起来,搭建出完整的电路。 2. Keil程序编写:使用Keil软件,编写51单片机的C语言程序。该程序需要实现时钟的功能,包括时、分、秒的显示和计时、调整时间、闹钟功能等。通过编程,可以控制数码管的显示,以及对按键进行响应。 3. Proteus仿真:将编写好的程序通过Proteus软件连接至搭建好的电路。进行仿真测试时,可以通过模拟时钟的不同状态,调试和验证编写的程序的正确性和稳定性。仿真过程中,可以检查数码管的显示情况,以及程序对按键输入的响应。 4. 优化和调试:根据仿真过程中的结果,对程序进行优化和调试。可能需要根据具体的需求,修改程序中的一些逻辑或代码,确保电子时钟的功能正常运行,并符合设计要求。 总的来说,基于51单片机的电子时钟项目需要通过Keil编写程序,并结合Proteus进行仿真电路搭建和测试。通过这样的开发流程,可以实现一个功能完善、稳定可靠的电子时钟。 ### 回答2: 基于51单片机的电子时钟keil程序和protues仿真电路组成了一个完整的设计方案。 首先,keil程序是用于开发51单片机的集成开发环境,它提供了编译、调试和仿真等功能,能够帮助程序员快速开发出51单片机的应用程序。在电子时钟的设计中,我们可以使用keil来编写单片机的程序代码,实现时钟的各种功能。 其次,protues是一款电子设计自动化软件,它提供了电子电路仿真和PCB布局设计等功能,能够帮助我们快速验证电路的正确性。在电子时钟的设计中,我们可以使用protues来建立电子时钟的仿真电路,验证单片机代码的正确性和稳定性。 基于51单片机的电子时钟设计,我们可以使用keil来编写单片机的程序代码,实现时钟的各种功能,包括时间显示、报时功能、闹钟功能等。通过keil的编译、调试和仿真功能,我们可以验证代码的正确性和稳定性。 在电路设计方面,我们可以使用protues来建立电子时钟的仿真电路,通过仿真可以验证电路的正确性和稳定性,包括时钟电路、数码管驱动电路、按钮输入电路等。通过protues的电路仿真功能,我们可以检查电路设计的错误和漏洞,提前解决电路问题。 基于51单片机电子时钟keil程序和protues仿真电路的组合,我们可以全面验证电子时钟的功能和性能,确保设计的准确性和可靠性,为最终实现一个完整的电子时钟设计提供了有力的支持。 ### 回答3: 基于51单片机的电子时钟keil程序和protues仿真电路可以实现以下功能: 1. 显示当前时间:我们可以使用数码管或LCD显示模块来显示当前的时、分和秒。通过编写相应的程序,我们可以从单片机的时钟源获取当前时间,并将其转换为可以在数码管或LCD上显示的格式。 2. 时间调整功能:可以通过按钮或旋钮等输入设备来调整电子时钟的时间。当用户按下或旋转输入设备时,我们可以响应用户的操作,并对时钟的时间进行相应的调整。 3. 闹钟功能:我们可以设置闹钟功能,让电子时钟在特定的时间点发出警报声。通过在程序中设置闹钟时间和警报声的播放方式,我们可以实现这一功能。 4. 温湿度监测:如果我们希望电子时钟能够同时监测室内的温度和湿度,我们可以连接温湿度传感器,并在程序中读取传感器的数据。然后,我们可以将这些数据显示数码管或LCD上。 程序开发过程中,我们可以使用keil来编写51单片机的程序,通过keil提供的调试工具来测试和调试程序的正确性。同时,我们可以在protues中设计和仿真电子时钟的电路,包括单片机、显示模块、输入设备和传感器等所有的硬件组件。这样,我们可以在protues中验证电路的功能和效果,并进行性能优化和调试。当电路和程序都满足我们的要求后,我们就可以将程序烧录到实际的硬件上,并使用它作为一台完整的电子时钟了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值