【STM32单片机】宠物定时喂食器设计

news2025/6/21 14:40:00

文章目录

  • 一、功能简介
  • 二、软件设计
  • 三、实验现象
  • 联系作者


一、功能简介

本项目使用STM32F103C8T6单片机控制器,使用按键、IIC OLED液晶、蜂鸣器、继电器投喂控制等。
主要功能:
系统运行后,OLED液晶显示初始时间,默认工作在自动投喂模式,可通过矩阵按键S4切换自动/手动模式;当处于手动模式,按下S1键进行投喂开关控制;
当处于自动模式,按下S3键进入投喂时间设置,系统支持3组投喂时间,可按下S3键切换哪一组,再按下S5键选择该组对应的时间位置,按下S1或S2键调节数值,只有设置该组投喂状态为Y时,定时投喂有效。设定好后,按下S6键确定。当时间到达投喂时间,蜂鸣器报警,开启投喂装置,一段时间后自动关闭。


二、软件设计

/*
作者:嗨小易(QQ:3443792007)

*/



//系统数据设置
void sys_data_set(void)
{
	u8 key=0;
	key=KEY_Matrix_Scan();
	//自动手动模式
	if(key==4)
	{
		sys_ctrl.autoflag=!sys_ctrl.autoflag;
		if(sys_ctrl.autoflag==1)
		{
			sys_ctrl.mode=0;
			OLED_ShowString(3*8,16, " ",16);
			OLED_ShowString(3*8,32, " ",16);
			OLED_ShowString(3*8,48, " ",16);
		}
	}
	//手动模式
	if(sys_ctrl.autoflag)
	{
		//投喂开关
		if(key==1)
		{
			if(sys_ctrl.feedflag[0])
			{
				sys_ctrl.feedflag[0]=0;
				LED1=1;//关闭投喂装置
			}
			else
			{
				sys_ctrl.feedflag[0]=1;
				LED1=0;//打开投喂装置
			}
		}
	}
	//自动模式
	else
	{
		//选择要修改的投喂时间模式
		if(key==3)
		{
			sys_ctrl.mode++;
			if(sys_ctrl.mode>3)sys_ctrl.mode=1;
		}
		//进入设置模式
		if(sys_ctrl.mode!=0)
		{
			//在对应模式选择位置
			if(key==5)
			{
				sys_ctrl.cnt++;
				if(sys_ctrl.cnt>2)sys_ctrl.cnt=0;
			}
			//加
			else if(key==1)
			{
				switch(sys_ctrl.mode)
				{
					case 1://投喂1
						switch(sys_ctrl.cnt)
						{
							case 0://时
								sys_ctrl.time[0][0]++;
								if(sys_ctrl.time[0][0]>23)sys_ctrl.time[0][0]=0;
								break;
							case 1://分
								sys_ctrl.time[0][1]++;
								if(sys_ctrl.time[0][1]>59)sys_ctrl.time[0][1]=0;
								break;
							case 2://开关
								sys_ctrl.timeflag[0]=!sys_ctrl.timeflag[0];
								break;
						}
						break;
					case 2://投喂2
						switch(sys_ctrl.cnt)
						{
							case 0://时
								sys_ctrl.time[1][0]++;
								if(sys_ctrl.time[1][0]>23)sys_ctrl.time[1][0]=0;
								break;
							case 1://分
								sys_ctrl.time[1][1]++;
								if(sys_ctrl.time[1][1]>59)sys_ctrl.time[1][1]=0;
								break;
							case 2://开关
								sys_ctrl.timeflag[1]=!sys_ctrl.timeflag[1];
								break;
						}
						break;
					case 3://投喂3
						switch(sys_ctrl.cnt)
						{
							case 0://时
								sys_ctrl.time[2][0]++;
								if(sys_ctrl.time[2][0]>23)sys_ctrl.time[2][0]=0;
								break;
							case 1://分
								sys_ctrl.time[2][1]++;
								if(sys_ctrl.time[2][1]>59)sys_ctrl.time[2][1]=0;
								break;
							case 2://开关
								sys_ctrl.timeflag[2]=!sys_ctrl.timeflag[2];
								break;
						}
						break;
				}
			}
			//减
			else if(key==2)
			{
				switch(sys_ctrl.mode)
				{
					case 1://投喂1
						switch(sys_ctrl.cnt)
						{
							case 0://时
								sys_ctrl.time[0][0]--;
								if(sys_ctrl.time[0][0]<0)sys_ctrl.time[0][0]=23;
								break;
							case 1://分
								sys_ctrl.time[0][1]--;
								if(sys_ctrl.time[0][1]<0)sys_ctrl.time[0][1]=59;
								break;
							case 2://开关
								sys_ctrl.timeflag[0]=!sys_ctrl.timeflag[0];
								break;
						}
						break;
					case 2://投喂2
						switch(sys_ctrl.cnt)
						{
							case 0://时
								sys_ctrl.time[1][0]--;
								if(sys_ctrl.time[1][0]<0)sys_ctrl.time[1][0]=23;
								break;
							case 1://分
								sys_ctrl.time[1][1]--;
								if(sys_ctrl.time[1][1]<0)sys_ctrl.time[1][1]=59;
								break;
							case 2://开关
								sys_ctrl.timeflag[1]=!sys_ctrl.timeflag[1];
								break;
						}
						break;
					case 3://投喂3
						switch(sys_ctrl.cnt)
						{
							case 0://时
								sys_ctrl.time[2][0]--;
								if(sys_ctrl.time[2][0]<0)sys_ctrl.time[2][0]=23;
								break;
							case 1://分
								sys_ctrl.time[2][1]--;
								if(sys_ctrl.time[2][1]<0)sys_ctrl.time[2][1]=59;
								break;
							case 2://开关
								sys_ctrl.timeflag[2]=!sys_ctrl.timeflag[2];
								break;
						}
						break;
				}
			}
			//确定
			else if(key==6)
			{
				sys_ctrl.mode=0;
				OLED_ShowString(3*8,16, " ",16);
				OLED_ShowString(3*8,32, " ",16);
				OLED_ShowString(3*8,48, " ",16);
			}
		}
	}
}

//系统功能控制
void sys_fun_ctrl(void)
{
	static u8 oneflag=0;
	//自动模式下
	if(sys_ctrl.autoflag==0)
	{
		//第1组投喂时间开启
		if(sys_ctrl.timeflag[0]==1)
		{
			if(oneflag==0)
			{
				//投喂时间达到
				if(sys_ctrl.time[0][0]==sys_ctrl.hour && sys_ctrl.time[0][1]==sys_ctrl.min)
				{
					sys_ctrl.feedflag[0]=1;
					LED1=0;//打开投喂装置
					BEEP_Alarm(100,100);
					sys_ctrl.alarm_cnt++;
					if(sys_ctrl.alarm_cnt>=10)
					{
						sys_ctrl.alarm_cnt=0;
						oneflag=1;
					}	
				}
			}
			else
			{
				if((sys_ctrl.time[0][1]+1)==sys_ctrl.min)
				{
					oneflag=0;
					sys_ctrl.feedflag[0]=0;
					LED1=1;//关闭投喂装置
				}
			}
		}
		//第2组投喂时间开启
		else if(sys_ctrl.timeflag[1]==1)
		{
			if(oneflag==0)
			{
				//投喂时间达到
				if(sys_ctrl.time[1][0]==sys_ctrl.hour && sys_ctrl.time[1][1]==sys_ctrl.min)
				{
					sys_ctrl.feedflag[1]=1;
					LED1=0;//打开投喂装置
					BEEP_Alarm(100,100);
					sys_ctrl.alarm_cnt++;
					if(sys_ctrl.alarm_cnt>=10)
					{
						sys_ctrl.alarm_cnt=0;
						oneflag=1;
					}	
				}
			}
			else
			{
				if((sys_ctrl.time[1][1]+1)==sys_ctrl.min)
				{
					oneflag=0;
					sys_ctrl.feedflag[1]=0;
					LED1=1;//关闭投喂装置
				}
			}
		}
		//第3组投喂时间开启
		else if(sys_ctrl.timeflag[2]==1)
		{
			if(oneflag==0)
			{
				//投喂时间达到
				if(sys_ctrl.time[2][0]==sys_ctrl.hour && sys_ctrl.time[2][1]==sys_ctrl.min)
				{
					sys_ctrl.feedflag[2]=1;
					LED1=0;//打开投喂装置
					BEEP_Alarm(100,100);
					sys_ctrl.alarm_cnt++;
					if(sys_ctrl.alarm_cnt>=10)
					{
						sys_ctrl.alarm_cnt=0;
						oneflag=1;
					}	
				}
			}
			else
			{
				if((sys_ctrl.time[2][1]+1)==sys_ctrl.min)
				{
					oneflag=0;
					sys_ctrl.feedflag[2]=0;
					LED1=1;//关闭投喂装置
				}
			}
		}
	}
}

//应用控制系统
void app_sys_ctrl_demo(void)
{
	LED_Init();
	USART1_Init(115200);
	OLED_Init();
	KEY_Matrix_Init();
	BEEP_Init();
	TIM3_Init(1000,36000-1);  //定时500ms
	sys_parm_init();//系统参数初始化
	
	sys_open_show();//系统开机界面显示
	
	while(1)
	{
		sys_data_get();//系统数据获取
		sys_data_show();//系统数据显示
		sys_data_set();//系统数据设置
		sys_fun_ctrl();//系统功能控制
	}
}



三、实验现象

B站演示视频:https://space.bilibili.com/444388619

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


联系作者

专注于51单片机、STM32、国产32、DSP、Proteus、ardunio、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1086638.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

核心概念:从晶体管到集成电路到摩尔定律

目录 晶体管 集成电路 摩尔定律 总结 这芯片和半导体是不是一回事儿呢&#xff1f;怎么我有时候听人说芯片行业&#xff0c;有时候又听人说半导体行业&#xff0c;好像他们说的都是一回事&#xff1f; 不知道你是不是也有这样的问题。其实啊&#xff0c;这问题很简单&…

arm实验

设置按键中断&#xff0c;按键1按下&#xff0c;LED亮&#xff0c;再次按下&#xff0c;灭 按键2按下&#xff0c;蜂鸣器叫&#xff0c;再次按下&#xff0c;停 按键3按下&#xff0c;风扇转&#xff0c;再次按下&#xff0c;停 头文件 #ifndef __CTRL_KEY_H__ #define __CT…

python 操作FT232H——(1)准备工作与IO输出方波信号

1.准备工作&#xff1a; python环境&#xff1a; 安装python 环境&#xff0c;我目前使用的是pycharm2023.2.1 community Edition 版本 需要注意设置python解释器的版本及关联本地库&#xff0c;这样就不需要在新的工程中安装库文件了&#xff0c;&#xff08;当然也有缺点&…

Activity页面不显示toolbar

页面显示如下&#xff0c;显示toolbar, 想实现不显示toolbar&#xff0c; 1、在manifest里设置 android:theme"style/AppThemeNoTitle"&#xff0c;可以隐藏&#xff0c;但是整个页面显示为透明的了&#xff0c;activity整体类型发生改变 2、或者设置这个&#xf…

如何逐步掌握STM32开发技巧?

第一步&#xff1a;建立开发环境 选择Keil MDK等开发环境&#xff0c;根据芯片型号安装相应库。 第二步&#xff1a;备齐开发板和资料 选择最小系统板&#xff0c;可自行搭建外围电路&#xff0c;更深入了解硬件。 第三步&#xff1a;了解STM32 观看视频教程&#xff0c;快速…

03 独立看门狗 hal库 stm32cubemx

1.设置配置参数 > 2.初始化 IWDG_HandleTypeDef hiwdg;/* IWDG init function */ void MX_IWDG_Init(void) //Tout((42^prer) rlr) /40 // IWDG_PRESCALER_8 (42^prer) 8/40 *5*2000 64/40 *4095 ---6s {/* USER CODE BEGIN IWDG_Init 0 *//* USER CODE END IWDG_…

python-arima模型statsmodels库实现-有数据集(续)-statsmodels-0.9.0版本

python-arima模型statsmodels库实现-有数据集&#xff08;续&#xff09; 这篇博客是上一篇python-arima模型statsmodels库实现的续集&#xff0c;上一篇采用的statsmodels版本应该要高一点&#xff0c;如果使用低版本的statsmodels代码会有bug&#xff0c;这一篇则是针对stat…

docker制作自定义版本的jdk镜像

1、下载jdk版本&#xff0c;这里以jdk1.8.0_381为例 Java Downloads | Oracle 2、创建Dockerfile文件 此操作在安装有docker环境的centos系统下操作&#xff0c;如果没有安装请参考此文章&#xff1a;http://t.csdnimg.cn/NCCRB vim Dockerfile From debian MAINTAINER "…

Arya小科普 | 硬件软件基础知识 Java语言的前世今生 James Gosling老爷子的小故事 Java下载 和 IDEA工具

前言 1.从硬件到软件的计算机基础知识&#xff1b; 2.Java之父的小故事&#xff1b; 3.Java语言的前世今生&#xff0c;及其特点&#xff1b; 4.Java下载 和 IDEA工具&#xff1b; 硬件和软件 键盘就是硬件&#xff0c; 操作系统就是软件。 硬件&#xff1a;设备和计算机打交…

核货宝:服装店收银系统必备的五大功能

收银系统对于服装店的经营至关重要&#xff0c;它不仅能简化收银流程&#xff0c;还能提供实时数据和综合报告&#xff0c;帮助店主更好地管理店铺。在选择服装店收银系统时&#xff0c;有五个必备功能需要考虑。本文将介绍这五大功能&#xff0c;并解释其在服装店中的重要性。…

我发现了计算机专业,能拉开很大差距的方式,计算机大一新生必看!

这个社会实在是太卷了&#xff0c;而程序员又是一个不断学习的行业。因此&#xff0c;如果你特别想和别人有一定差距&#xff0c;千万不能让自己信息闭塞。只要你多了解一些学习资源&#xff0c;学习更努力一些&#xff0c;就能离成功更近一步✨&#xff01; 下面&#xff0c;就…

Java开发-参数校验@NotEmpty、@NotBlank、@NotNull

大家好&#xff0c;我是小资。今天给大家说下参数校验。 标题中说的这三个注解所在的包路径为import javax.validation.constraints.*; 千万不要导错包哦&#xff0c;因为他们在好多包里都存在。开发只需引入Spring-web依赖就可以使用了。轻轻松松干掉多余的if-else。 下面我…

NiFi中缓存组件的运行机制及增删改缓存数据

要理解本文内容,需对NIFI有一定的了解,如果您是新手,想学习NIFI,或者想在数仓架构中引入NIFI,欢迎加我微信bigdata_work,我这有一整套使用NIFI的实时数仓落地方案。 在建设实时数仓的过程中,利用缓存机制来提升实时指标的实时性,是一种常用的方法。NIFI提供了专门的缓存…

Git相关知识(2)

目录 1.远程操作 1.基本认识 2.克隆远程仓库 3.向远端仓库推送 4.从远程仓库中拉取 5.忽略特殊文件 6.配置命令别名 2.标签管理 1.本地的标签 2.远端的标签 3.多人协作 1.远端同一个分支 2.远端不同的分支 4.企业级开发模型 1.交付软件流程 2.系统开发环境 1.…

振弦采集仪应用水坝安全监测的方案

振弦采集仪应用水坝安全监测的方案 随着工业化和城市化的快速发展&#xff0c;水资源的开发和利用越来越广泛。由于水坝在水利工程中起着至关重要的作用&#xff0c;因此对水坝进行安全监测变得越来越必要。为了实现对水坝的安全监测&#xff0c;振弦采集仪可以作为一种有效的…

Python+高光谱数据预处理-机器学习-深度学习-图像分类-参数回归

涵盖高光谱遥感数据处理的基础、python开发基础、机器学习和应用实践。重点解释高光谱数据处理所涉及的基本概念和理论&#xff0c;旨在帮助学员深入理解科学原理。结合Python编程工具&#xff0c;专注于解决高光谱数据读取、数据预处理、高光谱数据机器学习等技术难题&#xf…

SRC-记一处目录遍历

目录 安徽阳光心理测量平台目录遍历 FOFA指纹 漏洞复现 修复方案 hack渗透视频教程&#xff0c;扫码免费领 安徽阳光心理测量平台目录遍历 FOFA指纹 title"心理测量平台" 漏洞复现 路由后拼接/admin/UserFiles/ GET /admin/UserFiles/ HTTP/1.1 Host: {{Hostn…

关于pytorch不区分行向量与列向量的理解

听李沐老师讲深度学习时候解释pytorch不区分行向量和列向量&#xff0c;只相当于是一维数组&#xff0c;一维张量一定是行向量&#xff0c;相当于数组&#xff0c;而行列向量可以放到矩阵中看。 测试如下&#xff1a; rtorch.tensor([1,2,3],dtypetorch.float32) print(r,r.T…

Spring Boot中发送邮件时,如何让发件人显示别名

之前&#xff0c;我们通过一系列文章&#xff0c;介绍了如何在Spring Boot中发送邮件&#xff1a; 发送邮件添加附件引用静态资源邮件模版 已经包含了大部分的应用场景。但最近DD在做YouTube中文配音的时候&#xff0c;碰到一个问题&#xff1a; 如上图所示&#xff0c;收件人…

Android开发APT技术,与使用案例

annotationProcessor 是 javac 的一个工具&#xff0c;全称为 APT&#xff08;apt 工具&#xff0c;Annotation Processor Tool&#xff09;&#xff0c;它用来在编译时扫描和处理注解&#xff0c;获取注解和被注解对象的相关信息&#xff0c;然后根据注解自动生成 java 代码。…