项目四 基于stc89c52系列单片机恒温箱(不包含pid算法)

前言:作者想要帮助一些童鞋和爱好者进行项目构建,但自知能力有限,不喜可论,创作不易,勿喷。
系统采用STC12C5A60S2芯片进行的单片机恒温箱,能够实现恒温加热,超温报警。上代码。
main.c

#include <STC12C5A60S2.H>
#include <ds1602.c>
uchar cp,cp1,cp2,cp3,mode=0,sec,min,hour,mode1=0;
uchar temp,ad0,temp_x;

unsigned char TL=0,TH=0,TD=0,TN=0,count;


#include <18b20.c>

uchar bit0=0,bit1=0,bit2=0,bit3=0,flag=0;
#include "key.c"
//uint T0_H,T0_L,T1_H,T1_L;
#include <display.c>

void Timer_isr(void)interrupt 1
{
	
	
		TH0 =64535/256;
	TL0 =64535%256;
	cp++;

	
	if(cp >= 250)
	{
		
			cp = 0;
			cp1++;
			key();
			ReadTemp();
	

	
	
		if(cp1 >= 240)//min 240=1min 
		{
				cp1 = 0;
			
				
				min++;
		
				if(min >= 2)
				{
					min = 0;
					if(bit0 == 1)bit0 = 0;
					if(bit1 == 1)bit1 = 0;
					if(bit2 == 1)bit2 = 0;
					if(bit3 == 1)bit3 = 0;
			}

		
		}
	}
	
}
void Timer_Init()
{
		TMOD = 0x01;
	TH0 =64535/256;
	TL0 =64535%256;


	TR0 = 1;

	ET0 = 1;

	EA =1;
}

void T_mode()
{
		if(flag == 0)
			{
//				mode1 = 0;
				cp1 = 0;
				flag = 1;
				bit0 = 1;
			}
			if(bit0 == 0){			
												
												if(flag == 1)
														{
//															mode1 = 1;
																		cp1 = 0;
															flag = 2;
															bit1 = 1;
														}
												if(bit1 == 0){
																				
																				if(flag == 2)
																					{
//																						mode1 = 2;
																									cp1 = 0;
																						flag = 3;
																						bit2 = 1;
																					}
																						if(bit2 == 0){
																												
																														if(flag == 3)
																														{	
																															
																																		cp1 = 0;
																															flag = 4;
																															bit3 = 1;
																														}
																														if(bit3 == 0){
																																						flag = 0;
																																							mode = 0;
																																							
																															
																																					}
																						}
																					
																			}
													
												

											
											}
}
void temp_mode(uchar aa,bb,cc,dd)
{
		if( bit0 == 1)
		{
			if(TN > aa)	P20 = 0;
			if(TN <= aa)	P20 = 1;		
		}
		
			if( bit1 == 1)
		{
			if(TN > bb)	P20 = 0;
			if(TN <= bb)	P20 = 1;		
		}
			if( bit2 == 1)
		{
			if(TN > cc)	P20 = 0;
			if(TN <= cc)	P20 = 1;		
		}
		
			if( bit3 == 1)
		{
			if(TN > dd)	P20 = 0;
			if(TN <= dd)	P20 = 1;		
		}



}
void main()
{
	Timer_Init();
	 init_1602();
	LCD_clr1602();
	delayus(20);


	
//			
ReadTemp();

	while(1)
	{
		if(mode == 0)P20= 0;
		else T_mode();
		if(mode == 1)temp_mode(100,90,80,70);
		if(mode == 2)temp_mode(90,80,70,60);
		if(mode == 3)temp_mode(80,70,60,50);
		if(mode == 4)temp_mode(70,60,50,40);
		

		
		display();

}
	}

DS1602.c

#define uchar unsigned char 
#define uint  unsigned int
 
sbit RS = P2^5;//数据/命令
sbit RW = P2^6;//读/写
sbit E  = P2^7;//使能
uchar i;
uchar str[] = {"Internet of Things00"};
uchar num[] = {"0123456789"};

void delayus(uint x)  //延时函数
{
	while(x--);
}

void write_com(uchar com)//写命令
{
	RW = 0;
	RS = 0;
	E = 1;
	P0 = com;
	delayus(100);
	E = 0;
}
void write_data(uchar da)//写入数据
{
	RW = 0;
	RS = 1;
	E = 1;
	P0 = da;
	delayus(100);
	E = 0;
}


void init_1602()	//LCD1602  初始化
{
	write_com(0x3c);//设定数据总线的个数4/8,显示一行/两行
	write_com(0x0c);//	  //光标不显示
	write_com(0x06);//	   //光标随字符右移
}
void LCD_clr1602()	//LCD1602  清屏
{
	write_com(0x01);	// 对字符串清0
	write_com(0x02);   //对光标清0
}

void goto_xy(uchar y,uchar x)    //定位显示位置
{
	if(y == 1)
		write_com(x + 0x80);		 //定位第一行
	else
		write_com(x + 0x80 + 0x40);	 //定位第二行
}

void display_num(unsigned char x)		 //显示数字
{
	write_data(num[x / 10%10]);	 
	write_data(num[x % 10]);
}

void display_num1(unsigned int x)		 //显示数字
{
	write_data(num[x / 1000 % 10]);
	write_data(num[x / 100 % 10]);
	write_data(num[x / 10 % 10]);		 
	write_data(num[x % 10]);
}

void display_string(uchar *p)	 //显示字符
{
	while(*p)
	{
		write_data(*p);
		p++;	
	}
}
void display_xnum2(float x)		 //显示数字
{
	uint y,x1;
	
	y = (int)x;
	write_data(num[y / 10]);	 
	write_data(num[y % 10]);
	x1 = (int)((x -(float)y)*1000);
	display_string(".");
	write_data(num[x1 / 100 % 10]);
//	write_data(num[x1 / 10 % 10]);		 
//	write_data(num[x1 % 10]);
}
void display_xnum1(float x)		 //显示数字
{
	uint y,x1;
	
	y = (int)x;
	write_data(num[y / 100%10]);	 
	write_data(num[y / 10%10]);	 
	write_data(num[y % 10]);
	x1 = (int)((x -(float)y)*1000);
	display_string(".");
	write_data(num[x1 / 100 % 10]);
	write_data(num[x1 / 10 % 10]);		 

}

18b20.c

/
/***********ds18b20子程序*************************/
sbit DQ = P2^4;  
/***********ds18b20延迟子函数(晶振12MHz )*******/ 

void delay_18B20(unsigned int i)
{
	while(i--);
}

/**********ds18b20初始化函数**********************/

void Init_DS18B20(void) 
{
	 unsigned char x=0;
	 DQ = 1;          						//DQ复位
	 delay_18B20(8);  						//稍做延时
	 DQ = 0;          						//单片机将DQ拉低
	 delay_18B20(80); 						//精确延时 大于 480us
	 DQ = 1;          						//拉高总线
	 delay_18B20(14);
	 x=DQ;            						//稍做延时后 如果x=0则初始化成功 x=1则初始化失败
	 delay_18B20(20);
}

/***********ds18b20读一个字节**************/  

unsigned char ReadOneChar(void)
{
	uchar i=0;
	uchar dat = 0;
	for (i=8;i>0;i--)
	 {
		  DQ = 0; 							// 给脉冲信号
		  dat>>=1;
		  DQ = 1; 							// 给脉冲信号
		  if(DQ)
		  dat|=0x80;
		  delay_18B20(4);
	 }
 	return(dat);
}

/*************ds18b20写一个字节****************/  

void WriteOneChar(uchar dat)
{
 	unsigned char i=0;
 	for (i=8; i>0; i--)
 	{
  		DQ = 0;
 		DQ = dat&0x01;
    	delay_18B20(5);
 		DQ = 1;
    	dat>>=1;
 }
}

/**************读取ds18b20当前温度************/

void ReadTemp()
{
	

	Init_DS18B20();
	WriteOneChar(0xCC);    	// 跳过读序号列号的操作
	WriteOneChar(0x44); 	// 启动温度转换

	delay_18B20(100);       // this message is wery important

	Init_DS18B20();
	WriteOneChar(0xCC); 	//跳过读序号列号的操作
	WriteOneChar(0xBE); 	//读取温度寄存器等(共可读9个寄存器) 前两个就是温度

	TL=ReadOneChar();    //先读的是温度值低位
	TH=ReadOneChar();    //接着读的是温度值高位
	TN=TH*16+TL/16;         //实际温度值=(TH*256+TL)/16,即:TH*16+TL/16
			                                //这样得出的是温度的整数部分,小数部分被丢弃了
					   
	TD=(TL%16)*100/16;       //计算温度的小数部分,将余数乘以10再除以16取整,
			                                //这样得到的是温度小数部分的第一位数字(保留1位小数)
}

key.c



void key()
{


		if(P32 == 0)
	{
		
		while(P32 == 0);
			mode = 1;
		
		
		
	}
		if(P33 == 0)
	{
		
		while(P33 == 0);
			mode = 2;
		
		
	}
		if(P34 == 0)
	{
		
		while(P34 == 0);
			mode = 3;

		
	}
		if(P35 == 0)
	{
		
		while(P35 == 0);
			mode = 4;

		
	}

}

display.c

void display()
{
			goto_xy(1,0);	

		display_string("temp:");
		display_num(TN);
		display_string(".");
			display_num(TD);
				display_string(" ");
				display_num(mode);

			goto_xy(2,5);
		display_num(bit0);
		display_num(bit1);
		display_num(bit2);
		display_num(bit3);

}

原理图
在这里插入图片描述
Pcb
在这里插入图片描述
资源区会上传相关资源,积分下载

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

(~ ̄▽ ̄)~凤凰涅槃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值