基于51单片机的宠物自动猫粮狗粮喂养机proteus仿真原理图PCB

功能介绍:
0.本系统采用STC89C52作为单片机
功能简介:
1.LCD1602实时显示当前时间/温湿度/食物重量
2.当时间到达设定喂食时间,启动步进电机进行投喂,投喂量达到预先设定好的重量后停止投喂
3.按键可更改当前时间/喂食时间/喂食量
4.按键可手动控制喂食(手动控制时,不判断实物重量)
5.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:
在这里插入图片描述

PCB :
在这里插入图片描述

主程序:

#include "main.h"

char dis[16];

enum _MODE_DF_ dispMode;
unsigned char setIndex = 0;

bit refreshFlag = 1;

unsigned long initialWeight = 0; //单位g
float objectWeight = 0; //单位g

unsigned char feedTime[3] = {18, 0, 0}; //投喂时间18:00:00
int feedWeight = 100; //100g
bit feedFlag1 = 0; //自动喂食启动标志1
bit feedFlag2 = 0; //手动喂食启动标志2

void main(void)
{

    BYJ48 = ((BYJ48 & 0xF0) | REV[0]); //取数据
    ULN_DQ3 = BIT3;
    ULN_DQ2 = BIT2;
    ULN_DQ1 = BIT1;
    ULN_DQ0 = BIT0;

    Timer0_Init();
    Timer1_Init();
    DS1302_Init();
    // DS1302_Write_Time();
    DelayMs(10);

    LCD_Init();
    LCD_DispStr(0, 0, "    Welcome!    ");
    DelayMs(200);
    initialWeight = HX711_GetInitialWeight();
    LCD_Clear();
    
    while (1)
    {
        if (refreshFlag == 1) //每400ms刷新一次屏幕
        {
            refreshFlag = 0;
            if (dispMode == NORMAL)
            {
                DispNormal();
            }
        }

        if (timeBufDec[4] == feedTime[0] && timeBufDec[5] == feedTime[1] && timeBufDec[6] == feedTime[2])
        {
            feedFlag1 = 1; //启动喂食
        }

        if (objectWeight >= feedWeight) //超过喂食重量
        {
            feedFlag1 = 0; //停止喂食
        }
        
        KeyProcess();
    }
}


void DispNormal()
{
    DS1302_Read_Time(); //读取实时时间
    ET1 = 0;
    objectWeight = HX711_Read();
    objectWeight = (objectWeight - initialWeight) / GAPVALUE; //读取实物重量
    objectWeight = (objectWeight<0)?0:objectWeight;
    DHT11_0_ReadData(); //读取温湿度
    ET1 = 1;
    sprintf(dis, "W:%6.3fkg %2d", objectWeight/1000, (int)U8T_data_H);
    LCD_DispStr(0, 0, dis);
    LCD_DispOneChar(13, 0, 0xdf);
    LCD_DispOneChar(14, 0, 'C');
    sprintf(dis, "%02d:%02d:%02d  Hm:%2d%%", (int)timeBufDec[4], (int)timeBufDec[5], (int)timeBufDec[6], (int)U8RH_data_H);
    LCD_DispStr(0, 1, dis);
}

/************************* 设置当前时间 *************************/
void DispSetTime(unsigned char setIndex)
{
    sprintf(dis, "%02d:%02d:%02d", (int)timeBufDec[4], (int)timeBufDec[5], (int)timeBufDec[6]);
    LCD_DispStr(0, 1, dis);

    switch (setIndex)
    {
        case 1: LCD_SetCursor(1, 1, 1); break;
        case 2: LCD_SetCursor(4, 1, 1); break;
        case 3: LCD_SetCursor(7, 1, 1); break;
        default:break;
    } 

}

/************************* 设置喂食时间 *************************/
void DispSetFeedTime(unsigned char setIndex)
{
    LCD_DispStr(0, 0, "    Feed Time   ");
    //LCD_DispStr(0, 0, "     TIME 2     ");
    sprintf(dis, "    %02d:%02d:%02d   ", (int)feedTime[0], (int)feedTime[1], (int)feedTime[2]);
    LCD_DispStr(0, 1, dis);
    
    switch (setIndex)
    {
        case 1: LCD_SetCursor(5, 1, 1); break;
        case 2: LCD_SetCursor(8, 1, 1); break;
        case 3: LCD_SetCursor(11, 1, 1); break;
        default:break;
    } 
}

/************************* 设置喂食量 *************************/
void DispSetFeedWeight(unsigned char setIndex)
{
    LCD_DispStr(0, 0, "   Food Weight  ");
    sprintf(dis, "    %6.3fkg ", (float)feedWeight/1000);
    LCD_DispStr(0, 1, dis);
    
    switch (setIndex)
    {
        case 1: LCD_SetCursor(8, 1, 1); break;
        default:break;
    } 
}

void Timer0_Init()
{
    TMOD &= 0xF0;
    TMOD |= 0x01; //T0 T1 均在工作方式1
    PT0 = 1;     //优先级设置
    TR0 = 0;
    ET0 = 1;     //T0开中断
    EA = 1;      //CPU开中断
}

void Timer1_Init()
{
    TMOD &= 0x0F;
    TMOD |= 0x10; //T0 T1 均在工作方式1
    TH1 = (65536 - 18432) / 256; //定时20ms
    TL1 = (65536 - 18432) % 256;
    TR1 = 1;
    ET1 = 1;     //T0开中断
    EA = 1;      //CPU开中断
}

void Timer1(void) interrupt 3 //T1中断程序
{
    static unsigned int cnt = 0;
    static unsigned int motorCnt = 0;

	TL1 = 0x66;		//设置定时初始值
	TH1 = 0xFC;		//设置定时初始值 1ms

    cnt++;

    if (cnt >= 400)
    {
        refreshFlag = 1;
        cnt = 0;
    }

    if (feedFlag1 == 1 || feedFlag2 == 1) //启动喂食,正转
    {
        if (motorCnt <= MAXCNT)
        {
            BYJ48 = ((BYJ48 & 0xF0) | REV[motorCnt % 8]); //取数据
            ULN_DQ3 = BIT3;
            ULN_DQ2 = BIT2;
            ULN_DQ1 = BIT1;
            ULN_DQ0 = BIT0;
            motorCnt++;
        }
    }
    else //停止喂食反转
    {
        if (motorCnt > 0)
        {
            BYJ48 = ((BYJ48 & 0xF0) | REV[motorCnt % 8]); //取数据
            ULN_DQ3 = BIT3;
            ULN_DQ2 = BIT2;
            ULN_DQ1 = BIT1;
            ULN_DQ0 = BIT0;
            motorCnt--;
        }
    }

}
//程序结束

仿真演示视频:
https://www.bilibili.com/video/BV1F24y197J3/

实物演示视频:
https://www.bilibili.com/video/BV1fN4y1P7Yu/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值