IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【课设分享】基于51单片机的恒温控制器系统 -> 正文阅读

[嵌入式]【课设分享】基于51单片机的恒温控制器系统

恒温控制器系统概述

该恒温控制器系统包含以下几个功能:

  • 可按键设定温度
  • 可显示当前温度和用户设定温度
  • 有升温、降温模块
  • 可最终达到恒温

仿真软件

  • Keil 5
  • Proteus 8.6

系统设计

电路设计

原理图
恒温控制系统一共有6个模块,分别是主控芯片模块、按键输入模块、设定温度显示模块、当前温度显示模块、温度采集模块和升温、降温模块。

  1. 按键输入模块:该模块由4*3的矩阵键盘和1个确认按钮构成。系统刚开始启动后,用户通过矩阵键盘输入想要设定的温度(0°~99°),输入完毕后按下确认键,然后将该温度数据传送给主控芯片AT89C51;
  2. 设定温度显示模块:该模块由一个2位8段LED数码管构成,主控芯片AT89C51使用P3口控制该数码管的段选,使用P2.4和P2.5两个端口来控制该数码管的位选。主控芯片AT89C51将从矩阵键盘得到的设定温度信息,通过2位8段LED数码管显示出来;
  3. 温度采集模块;该模块由一个DS18B20温度传感器构成。使用DS18B20温度传感器采集当前的温度,并将该温度信息传送给主控芯片AT89C51;
  4. 当前温度显示模块:该模块由两个74HC573锁存器和一个4位8段LED数码管构成,主控芯片AT89C51使用P2.6和P2.7控制两个74HC573锁存器的片选,两个锁存器的输入口均与主控芯片的P0口相连,并使用一个100欧的排阻作为P0口的上拉电阻,两个锁存器的输出口分别与4位8段LED数码管的段选口与位选口相连;
  5. 升温、降温模块:该模块由一个绿色LED和一个红色LED构成,绿色LED负责降温,每闪烁一次温度下降0.5°,红色LED负责升温,每闪烁一次温度上升0.5°。主控芯片AT89C51根据当前温度和用户设定温度之间的差值,来控制升温还是降温,以达到恒温的目的。

软件代码编写

程序的具体流程如下:

  1. 硬件初始化,关闭所有的数码管;
  2. 进行两次按键扫描循环,分别获取用户设定温度的十位和个位,获取完毕后,判断确认键是否被按下,如果用户按下确认键则进入到主程序循环中;
	while(ok)	//用户设定温度
	{
		while(key1 == 15)
		{
			key1 = keyscan();
			delay(50);
		}
		while(key2 == 15)
		{
			key2 = keyscan();
			delay(50);
		}
		delay(100);//等待确认键
	}
//键盘扫描
uchar keyscan()
{
	uchar temp,key;
	key = 15;	//	默认值,如果没有按键按下key就为该默认值
	
	P1 = 0xfe;	//扫描第一行
	temp = P1;
	temp = temp & 0xf0;
	if(temp!=0xf0)
	{
		delay(10);	//	延时消抖
		temp = P1;
		temp = temp & 0xf0;
		if(temp!=0xf0)	
		{
			temp = P1;
			switch(temp)	//扫描列
			{
				case 0xee:
					key = 1;
					break;
				case 0xde:
					key = 2;
					break;
				case 0xbe:
					key = 3;
					break;
			}
			
			while(temp!=0xf0)	//等待按键释放
			{
				temp = P1;
				temp = temp & 0xf0;
			}
		}
	}
	
	P1 = 0xfd;	//扫描第二行
	temp = P1;
	temp = temp & 0xf0;
	if(temp!=0xf0)
	{
		delay(10);	//	延时消抖
		temp = P1;
		temp = temp & 0xf0;
		if(temp!=0xf0)
		{
			temp = P1;
			switch(temp)	//扫描列
			{
				case 0xed:
					key = 4;
					break;
				case 0xdd:
					key = 5;
					break;
				case 0xbd:
					key = 6;
					break;
			}
			
			while(temp!=0xf0)	//等待按键释放
			{
				temp = P1;
				temp = temp & 0xf0;
			}
		}
	}
	
	P1 = 0xfb;	//扫描第三行
	temp = P1;
	temp = temp & 0xf0;
	if(temp!=0xf0)
	{
		delay(10);	//	延时消抖
		temp = P1;
		temp = temp & 0xf0;
		if(temp!=0xf0)
		{
			temp = P1;
			switch(temp)	//扫描列
			{
				case 0xeb:
					key = 7;
					break;
				case 0xdb:
					key = 8;
					break;
				case 0xbb:
					key = 9;
					break;
			}
			
			while(temp!=0xf0)	//等待按键释放
			{
				temp = P1;
				temp = temp & 0xf0;
			}
		}
	}
	
	P1 = 0xf7;	//扫描第四行
	temp = P1;
	temp = temp & 0xf0;
	if(temp!=0xf0)
	{
		delay(10);	//	延时消抖
		temp = P1;
		temp = temp & 0xf0;
		if(temp!=0xf0)
		{
			temp = P1;
			switch(temp)	//扫描列
			{
				case 0xe7:
					key = 0;
					break;
				case 0xd7:
					key = 0;
					break;
				case 0xb7:
					key = 0;
					break;
			}
			
			while(temp!=0xf0)	//等待按键释放
			{
				temp = P1;
				temp = temp & 0xf0;
			}
		}
	}
	return key;
}
  1. 在主程序循环中,首先调用dis_set()函数显示用户设定温度;
for(i=20;i>0;i--)	
	dis_set(key1, key2);	//显示用户设定的温度
//显示设定温度函数
void dis_set(uchar k1, uchar k2)
{
		display2(1, k1);
		display2(2, k2);
		display2(0, k1);
}
//设定温度数据显示函数
void display2(uchar num, uchar tem_data)
{
	if(num==0)
	{
		S1 = 1;
		S2 = 1;
		delay(5);
	}
	if(num==1)
	{
		S1 = 0;
		S2 = 1;
		P3 = table[tem_data]; //table为 0-9的16进制编码表
		delay(5);
	}
	else if(num==2)
	{
		S1 = 1;
		S2 = 0;
		P3 = table[tem_data];
		delay(5);
	}
}

然后再从温度传感器获取当前温度,获取当前温度的流程如下图所示,先调用DSreset()函数进行温度传感器的初始化,再调用temwrite()函数,对传感器写入温度转换的指令,进行温度获取和转换,然后调用get_tem()函数对传感器写入读取寄存器指令,从寄存器中读取存储的温度数据,并对该数据进行精度转换处理,最后获得一个保留了1位小数的当前温度数据;

temchange();				//获取当前温度
//温度获取和转换函数
void temchange(void)
{
	DSreset();
	delay(1);
	temwrite(0xcc);	//写跳过ROM指令
	temwrite(0x44);	//写温度转换指令
}	

//读取寄存器中存储的温度数据
uint get_tem(void)
{
	uchar l8,h8;
	DSreset();
	delay(1);
	
	temwrite(0xcc);	//写跳过ROM指令
	temwrite(0xbe);	//写读寄存器指令
	l8 = temread();	//读低8位数据
	h8 = temread();	//读高8位数据
	
	tem = h8;
	tem = tem<<8;
	tem = tem|l8; //合成一个16位数据
	f_tem = tem*0.0625;
	tem = f_tem*10+0.5;	//*10用于保留1位小数点,+0.5用于四舍五入
	return (tem);
}

DS18B20温度传感器的基本操作代码如下,各项操作要严格遵守DS18B20温度传感器的时序图,延时时间要足够,可以根据使用的主控芯片适当地修改循环的次数来调整延时。

初始化

//温度传感器初始化
uint DSreset(void)
{
	uint i;
	DS = 0;
	i = 73;
	while(i>0)
		i--;
	DS = 1;
	i = 0;
	while(DS)	
	{//等待DS18B20拉低总线
		delay(1);
		i++;
		if(i>10)
		{
			return 0;//初始化失败
		}
	}
	DS = 1;
	return 1;//初始化成功
}

读1位数据

//读1位数据
bit temreadbit(void)
{
	uint i;
	bit tem_bitdata;
	DS = 0;
	i++;	//延时
	DS = 1;
	i++;
	i++;
	tem_bitdata = DS;
	i = 10;
	while(i>0)
		i--;
	return(tem_bitdata);
}

读1字节数据

//读1字节数据
uchar temread(void)
{
	uint i;
	uchar j,tem_data;
	for(i=1;i<=8;i++)
	{
		j = temreadbit();
		tem_data = (j<<7)|(tem_data>>1);	//移位,让最低位在最后面
	}
	return (tem_data);
}

写1字节数据

//写1字节数据
void temwrite(uchar tem_data)
{
	uint i;
	uchar j;
	bit send_bitdata;
	for(j=1;j<=8;j++)
	{
		send_bitdata = tem_data&0x01;	//取要发送数据的最低位
		tem_data = tem_data>>1;	//右移一位
		
		if(send_bitdata)	//写1
		{
			DS = 0;
			i++;
			i++;
			DS = 1;
			i = 10;
			while(i>0)
				i--;
		}
		else					//写0
		{
			DS = 0;
			i = 10;
			while(i>0)
				i--;
			DS = 1;
			i++;
			i++;
		}
	}
}
  1. 获取完当前温度,调用dis_tem()函数显示当前温度;
for(i=20;i>0;i--)		//显示当前温度
	dis_tem(get_tem());
//显示当前温度函数
void dis_tem(uint t)
{
	uchar i;
	i = t/100;	//取温度的十位
	display1(1,i);
	i = t%100/10;	//取温度的个位
	display1(2,i+10);
	i = t%10;	//取温度的小数点后一位
	display1(3,i);
}
//当前温度数据显示函数
void display1(uchar num, uchar tem_data)
{
	WE = 1;	//选位,低电平有效
	P0 = ~((0x01)<<(num));
	WE = 0;
	
	DU = 1;	//选段,高电平有效
	P0 = table[tem_data];
	DU = 0;
	delay(10);
}
  1. 将当前温度和用户设定温度传入deal()函数,进行恒温控制,在恒温控制函数deal()中,根据判断当前温度和用户设定温度之间的差值进行不同的处理,如果当前温度小于用户设定温度,就进行升温处理,即红灯闪烁一次,每闪烁一次温度上升0.5°,如果当前温度大于用户设定温度,就进行降温处理,即绿灯闪烁一次,每闪烁一次温度下降0.5°,如果当前温度与用户设定温度想等,则不做处理,只显示温度;
void deal(uint t, uint t_set)
{
	uchar i;
	if(t<t_set)
	{
		work(15, 0x20);	//升温
	}
	else if(t>t_set)
	{
		work(15, 0x40);	//降温
	}
	else
	{
		i = 15;
		while(i--)
			{
				dis_tem(tem_set);
				dis_set(key1, key2);
			}
	}
}
//升温、降温模块
void work(uint s, uchar led)
{
	uchar i;
	if(led==0x20)
	{
		i = s;
		led0 = ~(led0);	//灯亮
		tem = tem+5;
		while(i--)
		{
			dis_tem(tem);
			dis_set(key1, key2);
		}
		led0 = ~(led0);	//灯灭
		i = s;
		while(i--)
		{
			dis_tem(tem);
			dis_set(key1, key2);
		}
	}
	else
	{
		i = s;
		led1 = ~(led1);	//灯亮
		tem = tem-5;
		while(i--)
		{
			dis_tem(tem);
			dis_set(key1, key2);
		}
		led1 = ~(led1);	//灯灭
		i = s;
		while(i--)
		{
			dis_tem(tem);
			dis_set(key1, key2);
		}
	}
}
  1. 进行一次恒温控制后,系统又回到主程序循环的起始点,不断重复上述3-5步骤,使温度保持在用户设定的温度,达到恒温的效果。

代码下载

完整仿真代码下载:基于51单片机的恒温控制器系统

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-04 11:22:45  更:2021-08-04 11:23:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:21:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码