基于STM32的自动宠物喂食器的Proteus仿真


一、宠物喂食器

1.题目要求

基于STM32F103C8单片机做一个自动宠物喂食器,主要特点可以在自动喂食模式下通过按键设置喂食时间,待喂食时间达到,驱动步进电机转动模拟喂食;其中自动模式下,还有个液位传感器能够检测水位,低于一定水位需要开启水泵加水,而压力传感器则检测食物重量,达到一定重量,要关闭电机。而手动喂食模式电机不转动。

额外功能:DS1302时钟模块显示实时时间,OLED显示。

2.思路

2.1 OLED显示汉字

OLED要显示中文,这需要用到取模软件,如下所示:
在这里插入图片描述
参数设置为:
在这里插入图片描述

2.2 DS1302模块

这里晶振可以不画,仿真里面不影响
在这里插入图片描述

2.3 液位传感器

仿真里面没有液位传感器,这里用滑动变阻器代码,通过改变滑阻的阻值,输出不同的电压值来检测。而水泵的驱动则是NPN驱动继电器的电路,当PUMP为低电平时,继电器不闭合,水泵不工作,当PUMP为高电平时,继电器闭合,水泵工作。

在这里插入图片描述

2.4 压力传感器和步进电机驱动

这里的压力传感器用的是mpx4115,步进电机用ULN2003芯片驱动。
在这里插入图片描述

3.仿真图

3.1 未仿真时

在这里插入图片描述

3.2 开始仿真,OLED初始界面显示实时时间

在这里插入图片描述

3.3 通过设置按键进入模式选择和喂食时间设置

在这里插入图片描述

3.4 进入喂食时间设置

在这里插入图片描述

3.5 设置好喂食时间,这里的时间指的是仿真内的时间,而非显现实时间

在这里插入图片描述

3.6 到达喂食时间,电机转动,模拟喂食

在这里插入图片描述

3.7 通过压力传感器模拟食物超过78g,大于设置阈值75g关闭电机

在这里插入图片描述

3.8 通过返回按键返回上一次的操作界面

在这里插入图片描述

3.9 通过液位模拟器模拟水位28%,低于30%阈值,开启水泵进行加水

在这里插入图片描述

3.10 通过液位模拟器模拟水位34%,高于30%阈值,关闭水泵

在这里插入图片描述

3.11 通过往上按键进入模式选择

在这里插入图片描述

3.12 模式选择界面

在这里插入图片描述

3.13 选择手动喂食模式,手动喂食模式下设置喂食时间,电机不转动(这里不演示)

在这里插入图片描述

4.仿真程序

4.1 程序说明

主控芯片:STM32F103C8
HICK:64MHZ
Systick: 1ms
测试Led:PC13

模拟wifi模块(Uart1):9600(PA9:tx1,PA10:rx1)

OLED显示屏:SCL(PB10),SDA(PB11)

液位传感器:FLUID(PA0)

压力传感器:STRESS(PA1)

水泵:PUMP(PB0)

时钟DS1302:
RST(PB7)
SCLK(PB5)
IO(PB6)

KEY按键:
KEY1(PA2)
KEY2(PA3)
KEY3(PA4)
KEY4(PA5)
KEY5(PA6)
KEY6(PA7)
KEY7(PA8)

MOTOR电机:
IN1(PB12)
IN2(PB13)
IN3(PB14)
IN4(PB15)

4.2 主函数

/* Includes ------------------------------------------------------------------*/
#include "Drv_UserSystem.h"

/**
  * @brief  main function.
  * @param  none
  * @retval none
  */
int main(void)
{
	UserSystemInit();//用户配置初始化		
	while (1)
	{					
		if (stSysTime.flg._10ms + TEN_MILLISECOND < Time_millis()) //10ms
		{
			stSysTime.flg._10ms = Time_millis();
            Key_Scan();//按键扫描						
		}
		if (stSysTime.flg._50ms + FIFTY_MILLISECOND < Time_millis()) //50ms
		{
			stSysTime.flg._50ms = Time_millis();			
			OLED_Handel();//OLED显示						
		}
		if (stSysTime.flg._100ms + BEST_MILLISECOND < Time_millis()) //100ms
		{
			stSysTime.flg._100ms = Time_millis();	
			Receive_data_Handel();//数据接收判断
			Led_Flicker();//灯光闪烁 		
            ADC_Scan();	//液体/压力检测						
			IWDG_ReloadCounter();//清开门狗 
		}
		if (stSysTime.flg._1s + THOUSAND_MILLISECOND < Time_millis()) //1s
		{
			stSysTime.flg._1s = Time_millis();
      Pet_feeding_countdown();		
      Read_RTC();//DS1302读取当前时间				
	  }
  }
}

4.3 OLED显示函数

/*******************************************************************************
 * 函数名:OLED_Handel
 * 描述  :OLED显示
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :50ms
*******************************************************************************/
void OLED_Handel(void)
{  	
	  if(Display_interface == 0)
		{
			if(Back_clear_flag)
			{
				Back_clear_flag = 0;
				OLED_Clear();
			}
			
            OLED_ShowNum(1,1,Year,2);
			OLED_Show_Character(1,2,23,16);//年	
            OLED_ShowNum(1,5,Month,2);
			OLED_Show_Character(1,4,24,16);//月	
            OLED_ShowNum(1,9,Day,2);
			OLED_Show_Character(1,6,25,16);//日			

            OLED_ShowNum(2,1,Hour,2);
			OLED_Show_Character(2,2,26,16);//时	
            OLED_ShowNum(2,5,Minute,2);
			OLED_Show_Character(2,4,27,16);//分	
			
            OLED_ShowNum(2,9,Second,2);
			OLED_Show_Character(2,6,28,16);//秒			

			OLED_Show_Character(3,1,29,16);//星		
			OLED_Show_Character(3,2,30,16);//期			
           OLED_ShowNum(3,5,Week,1);			
    }
    else if(Display_interface == 1)
		{
			if(Back_clear_flag)
			{
				Back_clear_flag = 0;
				OLED_Clear();
			}			
			
			OLED_Show_Character(1,1,5,16);//模
			OLED_Show_Character(1,2,6,16);//式	
			OLED_Show_Character(1,3,7,16);//选	
			OLED_Show_Character(1,4,8,16);//择		

			OLED_Show_Character(2,1,11,16);//喂	
			OLED_Show_Character(2,2,12,16);//食		
			OLED_Show_Character(2,3,13,16);//时	
			OLED_Show_Character(2,4,14,16);//间	

      if(key_Line == 1)
	  {
		if(clear_flag)
		{
			clear_flag = 0;
			OLED_Part_Clear(2,13,16);
		}				
	    OLED_Show_Character(1,8,21,16);//←								
	  }
      else if(key_Line == 0)
	  {
		 if(clear_flag)
		 {
			clear_flag = 0;
			OLED_Part_Clear(1,13,16);
		 }
		 OLED_Show_Character(2,8,21,16);//←								
	  }				
	}		
    else if(Display_interface == 2)//模式选择
	{
			if(Back_clear_flag)
			{
				Back_clear_flag = 0;
				OLED_Clear();
			}			

			OLED_Show_Character(1,1,19,16);//自
			OLED_Show_Character(1,2,20,16);//动		
			OLED_Show_Character(1,3,17,16);//喂	
			OLED_Show_Character(1,4,18,16);//食	
			
			OLED_Show_Character(2,1,15,16);//手
			OLED_Show_Character(2,2,16,16);//动	
			OLED_Show_Character(2,3,17,16);//喂	
			OLED_Show_Character(2,4,18,16);//食		

      if(key_Line == 1)
	  {
		if(clear_flag)
		{
			clear_flag = 0;
			OLED_Part_Clear(2,13,16);
		}				
		OLED_Show_Character(1,8,21,16);//←					
	  }
      else if(key_Line == 0)
	  {
		if(clear_flag)
		{
			clear_flag = 0;
			OLED_Part_Clear(1,13,16);
		}
		OLED_Show_Character(2,8,21,16);//←								
	  }			
	}		
    else if(Display_interface == 3)//喂食时间设置
	{
		if(Back_clear_flag)
		{
		  Back_clear_flag = 0;
		  OLED_Clear();
	    }
			
      OLED_ShowNum(2,3,Minute_tens,1);			
      OLED_ShowNum(2,4,Minute_ones,1);			
	  OLED_ShowString(2,5,":");//:			
      OLED_ShowNum(2,6,Second_tens,1);			
      OLED_ShowNum(2,7,Second_ones,1);	
			
      if(key_Column == 0)
	  {
				  if(clear_flag)
					{
						clear_flag = 0;
						OLED_Part_Clear(3,1,16);
					}
			    OLED_ShowString(3,7,"^");//^								
	  }							
      else if(key_Column == 1)
	  {
		if(clear_flag)
		{
			clear_flag = 0;
			OLED_Part_Clear(3,1,16);
		}				
		OLED_ShowString(3,6,"^");//^								
	  }
      else if(key_Column == 2)
	  {
		 if(clear_flag)
		 {
			clear_flag = 0;
			OLED_Part_Clear(3,1,16);
	 	 }
	     OLED_ShowString(3,4,"^");//^								
	  }	
      else if(key_Column == 3)
	  {
		if(clear_flag)
		{
				clear_flag = 0;
				OLED_Part_Clear(3,1,16);
		}
			 OLED_ShowString(3,3,"^");//^								
	 }				
 }			
}

4.4 DS1302获取实时时间函数

/*******************************************************************************
 * 函数名:Read_RTC
 * 描述  :读RTC
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
*******************************************************************************/
void Read_RTC(void)
{
	 static uint8_t time_count = 0;
    // 获取时间数据
	Second = Read_Clock(0X81);
    Minute = Read_Clock(0X83);
    Hour = Read_Clock(0X85);
    Day = Read_Clock(0X87);
    Month = Read_Clock(0X89);
    Week = Read_Clock(0X8B);
	Week = Week - 1;
    Year = Read_Clock(0X8D);
    
	if(++time_count > 2)
	{			
		time_count = 0; 
		// 输出时间数据
		printf("时间:%d年%d月%d日 %d时%d分%d秒 星期%d \r\n", Year, Month,    Day, Hour, Minute, Second, Week);
	}			
}

二、总结

今天主要讲了基于STM32的自动宠物喂食器的Proteus仿真。

感谢你的观看!

在这里插入图片描述

### STM32F103 宠物自动喂食开发教程 #### 项目概述 宠物自动喂食的设计旨在实现定时定量给宠物提供食物的功能。该设备采用STM32F103作为核心控制,具备无线传输、重量检测以及语音播报等功能[^1]。 #### 硬件组成 - **主控单元**:选用STM32F103系列微控制,具有高性能ARM Cortex-M3内核。 - **传感模块**:用于监测容内的剩余粮食量并反馈至MCU处理。 - **驱动电路**:负责控制电机运转完成出料动作;同时配备步进马达确保精准度。 - **通讯接口**:集成HC-05蓝牙模块以便远程操控设置参数或查询状态信息[^3]。 #### 软件架构 软件部分主要分为以下几个方面: ##### 初始化配置 初始化阶段需对各个外设进行必要的设定操作,包括但不限于GPIO端口方向定义、UART波特率调整等基础工作。 ##### 主循环逻辑 进入正常运行模式后,系统会按照预置的时间间隔定期触发喂养流程,并实时监控当前库存情况以防止缺粮报警发生。 ##### 数据交互协议 为了能够顺利地与其他智能终端建立连接,必须制定一套完整的命令集来描述不同场景下的行为规范。例如,“请求当前时间戳”,“修改下次投喂时刻表”。 ```c // UART中断服务函数模板 void USART_IRQHandler(void){ if(USART_GetITStatus(UARTx, USART_IT_RXNE) != RESET){ // 接收到新字符 char ch = USART_ReceiveData(UARTx); ProcessReceivedChar(ch); // 处理接收到的数据 } } ``` ##### 用户界面支持 考虑到用户体验感的重要性,在此基础上还加入了TTS(Text To Speech)功能,允许主人通过手机应用程序下达指令的同时听到清晰的提示音效。 #### 实现细节说明 针对上述提到的各项特性具体实施方式如下所示: - 编写专门的服务例程监听来自外部设备的消息输入事件; - 配套PC端图形化编辑工具简化初次安装调试过程中的复杂程度。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xiaobuding_QAQ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值