【单片机毕业设计】【mcuclub-yq-001】基于单片机的翻蛋器 孵化器的设计

2023-11-12

最近设计了一个项目基于单片机的翻蛋器 孵化器系统,与大家分享一下:

一、基本介绍

项目名:翻蛋器 孵化器
项目编号:mcuclub-yq-001
单片机类型:STC89C52、STM32F103C8T6
具体功能:
1、通过DS18B20测量温度,当温度超过上下限,进行加热或制冷
2、间隔固定时间,通过步进电机进行翻蛋(转30°)
3、通过按键设置温度上下限,及间隔时间、手动翻蛋
4、通过显示屏显示测量数据及倒计时时间
扩展功能:通过蓝牙模块将测量数据发送到手机端,并可以控制翻蛋

二、51实物图

单片机型号:STC89C52

板子为绿色PCB板,两层板,厚度1.2,上下覆铜接地。元器件基本上为插针式,个别降压芯片会使用贴片式。

供电接口:TYPE-C

三、51仿真图

仿真软件版本:proteus8.9

电路连线方式:网络标号连线方式

注意:部分实物元器件仿真中没有,仿真中会用其他工作原理相似的元件代替,这样可能导致实物程序和仿真程序不一样

 四、32实物图

单片机型号:STM32F103C8T6

板子为绿色PCB板,两层板,厚度1.2,上下覆铜接地。元器件基本上为插针式,个别降压芯片会使用贴片式。

供电接口:TYPE-C

 五、原理图

软件版本:AD2013

电路连线方式:网络标号连线方式

注意:原理图只是画出了模块的引脚图,而并不是模块的内部结构原理图

 六、PCB图

由原理图导出,封装很大一部分都是作者自己绘制,不提供封装库,只提供连接好的源文件。中间有一个项目编号,隐藏在单片机底座下,插入单片机后不会看到。

两层板,上下覆铜接地。

七、系统框图

本设计以STC89C52单片机为核心控制器,加上其他的模块一起组成室内环境温湿度检测系统的设计与研究的整个系统,其中包含中控部分、输入部分和输出部分。中控部分采用了STC89C52单片机,其主要作用是获取输入部分数据,经过内部处理,控制输出部分。输入由三部分组成,第一部分是DHT11温湿度检测模块,通过该模块可检测当前的温湿度值;第二部分是独立按键,通过三个独立按键切换界面和设置温湿度阈值;第三部分是供电电路,给整个系统进行供电。输出由六部分组成,第一部分是LCD1602显示模块, 通过该模块可以显示当前温度、湿度、设置的温湿度阈值等;第二部分是继电器控制加热片,当温度小于设置最小值时,加热继电器闭合,加热片工作,进行加热;第三部分是继电器控制制冷片,当温度大于设置最大值时,制冷继电器闭合,制冷片工作,进行制冷;第四部分是继电器控制加湿器,当湿度小于设置的最小值时,加湿继电器闭合,加湿器工作,进行加湿;第五部分是继电器控制风扇,当湿度大于设置的最大值时,除湿继电器闭合,风扇工作,进行除湿;第六部分是声光报警,温湿度不在设置的阈值之内时,进行声光报警提醒,第六部分为蓝牙连接手机模块,用户通过蓝牙和手机进行连接,将检测的温湿度传输到液晶显示屏上,及其当前设计的温湿度值和模式,用户也可以通过手机远程控制加热制冷、加湿除湿继电器的工作及其模式的切换。

 八、软件设计流程

系统的主流程图如图所示。在主程序中:首先对各个模块进行初始化,随后进入while主循环,在主循环中,首先进入第一个函数按键函数,该函数主要分为两部分,第一部分为调用按键扫描函数获取按键键值,第二部分通过键值进行相应的处理操作,包括切换界面、设置阈值等;紧接着进入第二个函数监测函数,该函数主要通过调用相应的驱动函数获取测量值,并通过蓝牙模块将监测的数据传输到手机端,用户也可以通过手机端发送指令,设备根据用户发送的指令执行对应的处理;紧接着进入第三个函数显示函数,该函数显示监测值及阈值;最后进入第四个函数处理函数,该函数主要判断当前温湿度是否在设置的阈值之内,如果温度大于设置的最大值,则声光报警,并且打开制冷继电器进行降温,如果温度小于设置的最小值,则声光报警,并且打开加热继电器进行加热,如果湿度大于设置的最大值,则声光报警,并且打开除湿继电器进行除湿,如果湿度小于设置的最小值,则声光报警,并且打开加湿继电器进行加湿,如果温度和湿度在设置的阈值之内,则取消声光报警,并关闭加热和制冷以及加湿和除湿继电器。

 九、部分程序展示

软件版本:keil5

逻辑程序和驱动程序分开,分布于main.c和其他.c文件

/**********************************
作者:单片机俱乐部
网站:https://www.mcuclub.cn/
**********************************/


/**********************************
包含头文件
**********************************/
#include "main.h"
#include "lcd1602.h"
#include "key.h"
#include "uart.h"
#include "dht11.h"



/**********************************
变量定义
**********************************/
uchar key_num = 0;											//按键扫描标志位			
uchar flag_display = 0;									//显示界面标志位
uint time_num = 0;											//10ms计时变量
bit flag_mode = 0;                      //模式标志位

bit flag_alarm_t = 0;                   //温度声光报警标志位
uint temp_value = 0;										//温度值
uint temp_max = 30;										  //温度最大值
uint temp_min = 20;										  //温度最小值
uchar temp_ctrl = 0;										//手动控制温度标志

bit flag_alarm_h = 0;                   //湿度度声光报警标志位
uint humi_value = 0;									  //湿度值
uint humi_max = 60;										  //湿度最大值
uint humi_min = 30;										  //湿度最小值
uchar humi_ctrl = 0;										//手动控制湿度标志

uchar uart_buf[16];                     //串口发送缓存区

/**********************************
函数声明
**********************************/
void Delay_function(uint x);						//延时函数(ms)
void Key_function(void);								//按键函数
void Monitor_function(void);						//监测函数
void Display_function(void);						//显示函数
void Manage_function(void);							//处理函数


/****
*******	主函数 
*****/
void main(void)
{
	Lcd1602_Init();		 										//LCD1602初始化
	Delay_function(50);										//延时50ms
	lcd1602_clean();											//清屏
	Delay_function(50);										//延时50ms
  while(DHT11_Init());                  //DHT11初始化
  Delay_function(50);										//延时50ms
  Uart_Init();    											//串口初始化函数
  Delay_function(50);										//延时50ms


	while(1)
	{
		Key_function();											//按键函数
		Monitor_function();									//监测函数
		Display_function();									//显示函数
		Manage_function();									//处理函数

		Delay_function(10);									//延时10ms
		time_num++;													//计时变量+1
		if(time_num == 5000)
		{
			time_num = 0;
		}
	}
}

/****
*******	延时 x ms函数
*****/
void Delay_function(uint x)
{
	uint m,n;
	for(m=x;m>0;m--)
	for(n=110;n>0;n--);
}

/****
*******按键函数
*****/
void Key_function(void)
{
	key_num = Chiclet_Keyboard_Scan(0);		//按键扫描
	if(key_num != 0)											//有按键按下
	{
		switch(key_num)
		{
			case 1:														//按键1,切换设置界面
				flag_display++;
				if(flag_display >= 5)
					flag_display = 0;
				
				lcd1602_clean();								//清屏
			break;

			case 2:														//按键2
				switch(flag_display)
				{
          case 0:															//界面0:切换手动模式控制温度
						flag_mode = 1;
						temp_ctrl++;
						flag_alarm_t = 0;
					break;
          
					case 1:															//界面1:温度最大值+1
						if(temp_max < 99)
							temp_max++;
					break;
					
					case 2:															//界面2:温度最小值+1
						if(temp_min < temp_max-1)
							temp_min++;
					break;
					
          case 3:															//界面3:湿度最大值+1
						if(humi_max < 99)
							humi_max++;
					break;
            
          case 4:															//界面4:湿度最小值+1
						if(humi_min < humi_max-1)
							humi_min++;
					break; 
          
					default:
					break;
				}
			break;

			case 3:														//按键3
				switch(flag_display)
				{
					case 0:															//界面0:切换手动模式控制湿度
						flag_mode = 1;
						humi_ctrl++;
						flag_alarm_h = 0;
					break;
					
					case 1:															//界面1:温度最大值-1
						if(temp_max > temp_min+1)
							temp_max--;
					break;
					
					case 2:															//界面2:温度最小值-1
						if(temp_min > 0)
							temp_min--;
					break;
					
          case 3:															//界面3:湿度最大值-1
						if(humi_max > humi_min+1)
							humi_max--;
					break;
            
          case 4:															//界面4:湿度最小值-1
						if(humi_min > 0)
							humi_min--;
					break;
            
					default:
					break;
				}
			break;
       
      case 4:																	//切换自动模式
				if(flag_display == 0)
				{
					flag_mode = 0;
					humi_ctrl = 0;
					temp_ctrl = 0;
				}
			break;

			default:
			break;
		}
	}
}

/****
*******监测函数
*****/
void Monitor_function(void)
{
	if(time_num % 10 == 0)								//100ms检测一次
	{
		Dht11_Get_Temp_Humi_Value(&temp_value,&humi_value); //获取温湿度
    
    if(time_num % 300 == 0)             //发送温湿度值、模式
    {
      sprintf(uart_buf,"\r\nTemp:%d.%dC\r\n",temp_value/10,temp_value%10);
      Uart_Sent_Str(uart_buf);
      sprintf(uart_buf,"Humi:%d.%d%%\r\n",humi_value/10,humi_value%10);
      Uart_Sent_Str(uart_buf);
      
      if(flag_mode == 0)
        Uart_Sent_Str("Mode:Auto\r\n");
      else
        Uart_Sent_Str("Mode:Manu\r\n");
    }
	}
}

/****
*******显示函数
*****/
void Display_function(void)
{
	switch(flag_display)									//根据不同的显示模式标志位,显示不同的界面
	{
		case 0:															//界面0:显示
      lcd1602_display_str(1,0,"Temp:");								//显示温度
			lcd1602_display_temp(1,5,temp_value);
			
			lcd1602_display_str(2,0,"Humi:");								//显示湿度
			lcd1602_display_humi(2,5,humi_value);
    
      if(flag_mode == 0)                              //显示当前模式
        lcd1602_display_str(2,12,"Auto");
      else
        lcd1602_display_str(2,12,"Manu");
		break;

		case 1:															//界面1:显示设置温度最大值
			lcd1602_display_str(1,2,"Set Temp Max");
			if(time_num % 20 == 0)
			{
				lcd1602_display_num(2,7,temp_max);
			}
			if(time_num % 40 == 0)
			{
				lcd1602_display_str(2,7,"    ");
			}
		break;
		
		case 2:															//界面2:显示设置温度最小值
			lcd1602_display_str(1,2,"Set Temp Min");
			if(time_num % 20 == 0)
			{
				lcd1602_display_num(2,7,temp_min);
			}
			if(time_num % 40 == 0)
			{
				lcd1602_display_str(2,7,"    ");
			}
		break;

    case 3:																						//界面3:显示设置湿度最大值
			lcd1602_display_str(1,2,"Set Humi Max");
			if(time_num % 20 == 0)
			{
				lcd1602_display_num(2,7,humi_max);
			}
			if(time_num % 40 == 0)
			{
				lcd1602_display_str(2,7,"    ");
			}
		break;
      
    case 4:																						//界面4:显示设置湿度最小值
			lcd1602_display_str(1,2,"Set Humi Min");
			if(time_num % 20 == 0)
			{
				lcd1602_display_num(2,7,humi_min);
			}
			if(time_num % 40 == 0)
			{
				lcd1602_display_str(2,7,"    ");
			}
		break;
      
		default:
		break;
	}
}

/****
*******处理函数
*****/
void Manage_function(void)
{
	if(flag_display == 0)									//测量界面
	{
		if(flag_mode == 0)                  //如果处于自动模式
    {
      if(temp_value > temp_max*10)													//温度大于设置最大值,制冷继电器闭合,开启报警
      {
        RELAY_ZL = 0;
        RELAY_JR = 1;
        flag_alarm_t = 1;
      }
      else if(temp_value < temp_min*10)											//温度小于设置最小值,加热继电器闭合,开启报警
      {
        RELAY_ZL = 1;
        RELAY_JR = 0;
        flag_alarm_t = 1;
      }
      else																									//温度处于设置的上下限值之间,两个继电器断开,关闭报警
      {
        RELAY_ZL = 1;
        RELAY_JR = 1;
        flag_alarm_t = 0;
      }
      
      if(humi_value > humi_max*10)													//湿度大于设置最大值,除湿继电器闭合
      {
        RELAY_CS = 0;
        RELAY_JS = 1;
        flag_alarm_h = 1;
      }
      else if(humi_value < humi_min*10)											//湿度小于设置最小值,加湿继电器闭合
      {
        RELAY_CS = 1;
        RELAY_JS = 0;
        flag_alarm_h = 1;
      }
      else																									//湿度处于设置的上下限值之间,两个继电器断开
      {
        RELAY_CS = 1;
        RELAY_JS = 1;
        flag_alarm_h = 0;
      }
    }
    else                  //手动模式下,关闭声光报警、根据按键按下控制继电器
    {
      flag_alarm_h = 0;
      flag_alarm_t = 0;
      if(temp_ctrl == 1)
			{
				RELAY_JR = 0;
				RELAY_ZL = 1;
			}
			else if(temp_ctrl == 2)
			{
				RELAY_JR = 1;
				RELAY_ZL = 0;
			}
			else
			{
				temp_ctrl = 0;
				RELAY_JR = 1;
				RELAY_ZL = 1;
			}

			if(humi_ctrl == 1)
			{
				RELAY_JS = 0;
				RELAY_CS = 1;
			}
			else if(humi_ctrl == 2)
			{
				RELAY_JS = 1;
				RELAY_CS = 0;
			}
			else
			{
				humi_ctrl = 0;
				RELAY_JS = 1;
				RELAY_CS = 1;
			}
    }
    if(flag_alarm_h == 1 || flag_alarm_t == 1)            //温度或湿度过高或过低,声光报警
    {
      if(time_num % 40 == 0)
      {
        LED = ~LED;
        BEEP = ~BEEP;
      }
    }
    else
    {
      LED = 1;
      BEEP = 1;
    }
	}
	else																	//设置界面,关闭所有继电器及声光报警
	{
		LED = 1;
    BEEP = 1;
    RELAY_CS = 1;
    RELAY_JS = 1;
    RELAY_ZL = 1;
    RELAY_JR = 1;
	}
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【单片机毕业设计】【mcuclub-yq-001】基于单片机的翻蛋器 孵化器的设计 的相关文章

  • verilog中给变量指定的位赋值

    reg 15 0 Data reg 3 0 i reg 1 0 data r begin Data i i 1 lt data r end 此类赋值是错误的 我自己修改了语句 如下 begin Data i lt data r 1 Data
  • ELK 日志分析搭建

    目录 一 ELK概述 1 1 概述 1 1 1 Elasticsearch概述 1 1 2 Logstash概述 1 1 3 kibana概述 1 2 ELK解决处理的事务 1 3 ELK优点 二 ELK 搭建操作 2 1 实验配置环境 2

随机推荐

  • Android Studio 打正式包

    第一步 第二步 第三步 第四步 第五步
  • v3

    hfd gd size 127152 size data 785449D1D343094895706D2DB2745030C466BEDCB9A26FC112F8C23E67BAF657 A5E4B40F93ADFDEBECBC0BB83F
  • JAVA设计模式(二)工厂模式与观察者模式

    工厂模式 工厂模式顾名思义则是类似于一个工厂制造产品的模式 如富士康需要制造自己的产品 而同类产品有多种 如手机有各个品牌和型号一样 明白了工厂模式的含义 我们来想想这个模式具体是怎么回事 首先需要的是一个工厂于是就需要一个Factory类
  • 【JavaWeb】HTML

    HTML 1 HTML概念 1 1 超文本 1 2 标记语言 2 HTML的入门程序 3 HTML语法规则 4 使用idea创建StaticWeb工程 5 HTML的各个标签的使用 5 1标题标签 5 2段落标签 5 3换行标签 5 4无序
  • mybatis代码自动生成器,可实现entity、mapper、service层代码生成

    mybatis对实体类的操作基本重复 公司的框架又已经定型 只能自己写一个代码自动生成器来减轻工作量 这里的实体类属性来自数据库中的表的列 可以根据需要自由更改 package oamanager entity import com bao
  • True Liars 【POJ - 1417】【种类并查集+0-1背包】

    题目链接 题目想要知道有P个好人 说真话的人 和Q个坏人 说假话的人 并且有N条信息 代表A说B是好人 yes 坏人 no 那么 在保证答案唯一的情况下输出这P个好人 并且最后的时候输出 end 否则 输出 no 坑点 答案唯一指的是最后你
  • python:冒泡排序(Bubble Sort)超详细教程!

    关于排序 真的非常的重要 数据可以从小到大排序 也可以从大到小排序 这样对于一个有序的数据 我们处理起来就很方便 这对于我们的工作帮助是很大的 那么你拿到一组无序的数据 你将要如何去处理它呢 冒泡排序就是从一个可迭代容器里 用某一索引去和它
  • 经销商订单系统,搭建中的功能介绍(感想)

    一 关于需求方对订货系统的解释 经销商订单系统 也可以叫做企业订货软件 企业订单软件 这是需求商说的 这套系统甲方说是属于企业内部系统 并不属于商城范畴 属于是企业内部单机的订单管理系统演变而来 二 经销商订单系统的流程 2 1 第一步 通
  • 【无标题】黑群辉DSM 6.2.3 系统安装图文教程 (2020-12-27更新)

    https www openos org threads dsm 6 2 3 2020 12 27 29 黑群晖系统其实是指在普通电脑运行Synology DSM系统 事实上在普通PC电脑上安装黑群晖 Synology DSM 也非常方便
  • 2.5.8 构架虚拟SCSI(存储)

    最后更新2021 07 29 架构虚拟SCSI与虚拟Ethernet类似 也需要如下四个步骤 首先 设定需要映射的设备类型 包括LV方式的虚拟磁盘 LUN方式的虚拟磁盘 虚拟光盘 磁带机 并确认VIO分区可以正确使用要映射设备 物理资源 本
  • 讯飞语音识别_讯飞输入法持续功能创新 语音输入最受用户认可

    犹记得10多年前功能机上的输入法 无论是拼音还是笔画 通过物理键盘按部就班地进行输入 效率异常低下 所幸那时候网络没有那么发达 手机聊天应用并不怎么丰富 而且彼时手机还只是 通讯设备 输入法的作用并未体现出来 时至今日 移动应用的兴盛以及手
  • 剑指offer15替换空格字符串

    package heima study day3 import java util Scanner public class 替换空格剑指offer public static void main String args Scanner i
  • Java安全代码扫描问题:不允许使用自动加载类

    解决问题 代码安全扫描 Classes should not be loaded dynamically 要求 Remove this use of dynamic class loading 解决方法 使用jdk自带方法 ClassLoa
  • 【因果学习】VC RCNN(CVPR 2020)代码

    作者基于MaskRCNN框架 Detectron2的前身 开发 受Bottom Up and Top Down Attention for Image Captioning and VQA启发 使用Mask RCNN作为Bottom Up的
  • java spring scope_java – Spring和scope属性

    我在Spring学习中遇到问题 需要一些帮助 我正在学习bean的原型范围 这基本上意味着每次有人或其他bean需要这个bean时 Spring会创建一个新bean而不使用相同的bean 所以我尝试了这段代码 假设我有这个Product类
  • DPDK+Pktgen 高速发包测试

    Pktgen概述 Pktgen Packet Gen erator 是一个基于DPDK的软件框架 发包速率可达线速 提供运行时管理 端口实时测量 可以控制 UDP TCP ARP ICMP GRE MPLS and Queue in Que
  • 在微软工作365天,还你一个我眼中更加真实的微软

    去年12月28日 我正式成为了微软中国的一名员工 今天又是12月28日 不知不觉我已经在这里工作365天了 其实在入职100天的时候我就写过一篇关于微软的文章 详见 在微软工作100天 谈谈我眼中的微软 但那个时候毕竟待的时间还比较短 所以
  • 零基础入门金融风控 Task2 数据分析

    文章目录 1 导入数据分析及可视化过程需要的库 2 读取文件 3 总体了解 4 查看数据集中特征缺失值 唯一值等 5 查看特征的数值类型有哪些 对象类型有哪些 6 变量分布可视化 6 时间格式数据处理及查看 7 掌握透视图可以让我们更好的了
  • 【Linux工具】-yum/gdb

    yum gdb 一 yum 1 简介 2 软件下载 3 软件删除 4 yum源与扩展yum源 5 常见选项 二 gdb 1 简介 2 gdb相关指令 一 yum 1 简介 在Linux下 下载软件通常的方法是下载源代码 然后进行编译得到可执
  • 【单片机毕业设计】【mcuclub-yq-001】基于单片机的翻蛋器 孵化器的设计

    最近设计了一个项目基于单片机的翻蛋器 孵化器系统 与大家分享一下 一 基本介绍 项目名 翻蛋器 孵化器 项目编号 mcuclub yq 001 单片机类型 STC89C52 STM32F103C8T6 具体功能 1 通过DS18B20测量温