一、宠物喂食器

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仿真。

感谢你的观看!

在这里插入图片描述

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐