自学内容网 自学内容网

【Proteus仿真】基于51单片机的宠物喂食系统设计

目录

一、主要功能

二、硬件资源

三、程序编程

四、实现现象


一、主要功能

基于51单片机,两个按键调整重量阈值的大小,如果mpx4117压力传感器测重没超过阈值,
则电机转动,表示投喂,蜂鸣器发出滴滴声,如果超过阈值,则全部停止;
同时,再加三个按键,一个按键按下切换到闹钟设置模式,一个按键按下切换时和分的调整,
一个按键按下则增加时或者分,当系统时间到达所设置的时间后,显示屏显示50,
表示要投喂的重量,此时电机转动,蜂鸣器发出滴滴声

二、硬件资源

基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。

三、程序编程

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#include "LCD1602.h"
#include "DS1302.h"

//IO设置
//****************************************************
sbit CS   =  P2^3;        //ADC0832引脚定义
sbit CLK  =  P2^4;
sbit DIO  =  P2^5;
sbit key1 =  P1^3;
sbit key2 =  P1^4;
sbit key3 =  P1^5;
sbit key4 =  P1^6;
sbit key5 =  P1^7;
sbit beep =  P2^6;
sbit out1 =  P3^0;
sbit out2 =  P3^1;

unsigned char KEY_NUM = 0;
bit Flag\_KEY\_Set = 0;
unsigned char KEY2_Count = 0;
static uchar u,U,YL;
static int numbermax=100,flag=0,time_num,flag1=0,hournum=8,minutenum=0,miaonum=0,flag2 = 0;

void ajpd(void);
void twpd(void);
void sjqh(void);
void nzpd(void);
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}


uchar get\_AD\_Res()          //ADC0832启动读取函数
{
uchar i, data1=0, data2=0;
CS=0;

CLK=0;DIO=1;\_nop\_();
CLK=1;\_nop\_();

CLK=0;DIO=1;\_nop\_(); 
CLK=1;\_nop\_();

CLK=0;DIO=0;\_nop\_();
CLK=1;\_nop\_();

CLK=0;DIO=1;\_nop\_(); 

for(i=0; i<8; i++)
{
CLK=1;\_nop\_();
CLK=0;\_nop\_();
data1=(data1<<1)|(uchar)DIO; 
}

for(i=0; i<8; i++)
{
data2=data2|(uchar)DIO<<i;
CLK=1;\_nop\_();
CLK=0;\_nop\_();
}
CS=1;

return(data1 == data2)?data1:0;
}

//显示实时时钟
//****************************************************
void Display_RTCC()
{
unsigned char *weeklist\[7\]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
LCD1602\_write\_com(0x80);//指针设置到第一行第1列

LCD1602_prints("20");
LCD1602_printc(DS1302Buffer.Year/10 + 0x30); //显示Year高位
LCD1602_printc(DS1302Buffer.Year%10 + 0x30); //显示Year低位
LCD1602_printc('-');
LCD1602_printc(DS1302Buffer.Month/10 + 0x30); //显示Month高位
LCD1602_printc(DS1302Buffer.Month%10 + 0x30); //显示Month低位
LCD1602_printc('-');
LCD1602_printc(DS1302Buffer.Day/10 + 0x30); //显示Day高位
LCD1602_printc(DS1302Buffer.Day%10 + 0x30); //显示Day低位

LCD1602\_write\_com(0x80+13); //指针设置到第一行第14列
LCD1602_prints(weeklist\[DS1302Buffer.Week -1\]);

LCD1602\_write\_com(0xc0); //指针设置到第二行第1列
LCD1602_printc(DS1302Buffer.Hour/10 + 0x30); //显示Hour高位
LCD1602_printc(DS1302Buffer.Hour%10 + 0x30); //显示Hour低位
LCD1602_printc(':');
LCD1602_printc(DS1302Buffer.Minute/10 + 0x30); //显示Minute高位
LCD1602_printc(DS1302Buffer.Minute%10 + 0x30); //显示Minute低位
LCD1602_printc(':');
LCD1602_printc(DS1302Buffer.Second/10 + 0x30); //显示Second高位
LCD1602_printc(DS1302Buffer.Second%10 + 0x30); //显示Second低位
}


void main()
{
    LCD1602_Init();//初始化LCD1602
    LCD1602\_delay\_ms(1);
    LCD1602\_set\_position(0,0);//指针设置到第一行第1列
    LCD1602_prints("Hello World!");
    LCD1602\_set\_position(0,13);//指针设置到第一行第13列
    LCD1602_prints("STC");
  LCD1602\_delay\_ms(500);
  LCD1602\_write\_com(0x01);//清屏指令
  DS1302_Init();//初始化DS1302
  beep = 0;
    while(1)
    {
if(flag==0)
{
  DS1302_GetTime(&DS1302Buffer);//获取当前RTCC值
  if(Flag\_Time\_Refresh==1&& Flag\_KEY\_Set == 0)//数据更新时才刷新LCD
{
Flag\_Time\_Refresh = 0;
Display_RTCC();//显示实时时钟
}

u=get\_AD\_Res();   //压力传感器
  U=(250*u)/128;    
  YL=200*U/250;
    LCD_ShowNum(2,14,YL,3);
LCD_ShowNum(2,10,numbermax,3);
  }
ajpd(); //按键判断
twpd();  //投喂判断
nzpd(); //闹钟判断
sjqh(); // 时间切换
time_num++;    //计时变量+1
if(time_num == 5000)
{
time_num = 0;
}

    }
}

void nzpd() //闹钟判断
{
if(flag==0)
{
if(DS1302Buffer.Hour == hournum && DS1302Buffer.Minute == minutenum && DS1302Buffer.Second > miaonum)
{
flag2 = 1;
numbermax = 50;
LCD_ShowNum(2,10,numbermax,3);
out1 = 1;
out2 = 0;
beep=1;
Delay(300);
beep=0;
Delay(300);
}
else
{
flag2 = 0;
}
}
}
void sjqh() //时间切换
{
if(flag == 2)
{
if(flag1 == 1)
{
if(time_num % 100 == 0 )
{
LCD1602\_set\_position(0,0);//指针设置到第一行第1列
    LCD1602_prints("nao zhong");
LCD1602\_set\_position(1,0);//指针设置到第二行第1列
  LCD1602_printc(hournum/10 + 0x30); //显示Hour高位
  LCD1602_printc(hournum%10 + 0x30); //显示Hour低位
  LCD1602_printc(':');
  LCD1602_printc(minutenum/10  + 0x30); //显示Minute高位
  LCD1602_printc(minutenum/10  + 0x30); //显示Minute低位
  LCD1602_printc(':');
  LCD1602_printc(miaonum/10  + 0x30); //显示Second高位
  LCD1602_printc(miaonum/10  + 0x30); //显示Second低位
}

if(time_num % 200 == 0 )
{
LCD1602\_set\_position(1,1);
LCD1602_printc("      ");
}
}

if(flag1 == 2)
{
if(time_num % 100 == 0 )
{
LCD1602\_set\_position(0,0);//指针设置到第一行第1列
    LCD1602_prints("nao zhong");
LCD1602\_set\_position(1,0);//指针设置到第二行第1列
  LCD1602_printc(hournum/10 + 0x30); //显示Hour高位
  LCD1602_printc(hournum%10 + 0x30); //显示Hour低位
  LCD1602_printc(':');
  LCD1602_printc(minutenum/10  + 0x30); //显示Minute高位
  LCD1602_printc(minutenum%10  + 0x30); //显示Minute低位
  LCD1602_printc(':');
  LCD1602_printc(miaonum/10  + 0x30); //显示Second高位
  LCD1602_printc(miaonum/10  + 0x30); //显示Second低位
}

if(time_num % 200 == 0 )
{
LCD1602\_set\_position(1,4);
LCD1602_printc("      ");
}
}

if(flag1 == 3)
{
if(time_num % 100 == 0 )
{
LCD1602\_set\_position(0,0);//指针设置到第一行第1列
    LCD1602_prints("nao zhong");
LCD1602\_set\_position(1,0);//指针设置到第二行第1列
  LCD1602_printc(hournum/10 + 0x30); //显示Hour高位
  LCD1602_printc(hournum%10 + 0x30); //显示Hour低位
  LCD1602_printc(':');
  LCD1602_printc(minutenum/10  + 0x30); //显示Minute高位
  LCD1602_printc(minutenum%10  + 0x30); //显示Minute低位
  LCD1602_printc(':');
  LCD1602_printc(miaonum/10  + 0x30); //显示Second高位
  LCD1602_printc(miaonum/10  + 0x30); //显示Second低位
}

if(time_num % 200 == 0 )
{
LCD1602\_set\_position(1,7);
LCD1602_printc("      ");
}
}
 }
}

void ajpd()  //按键判断
{
if(!key4)
{
numbermax++;
while(!key4);
}
 if(!key5)
{
numbermax--;
while(!key5);
}

if(!key1) //切换模式
{
flag++;
if(flag>2)
{
flag=0;
}
if(flag==1)
{
LCD1602\_write\_com(0x01);//清屏指令
LCD1602\_set\_position(0,0);//指针设置到第一行第1列
    LCD1602_prints("nao zhong");
LCD1602\_set\_position(1,0);//指针设置到第二行第1列
  LCD1602_printc(0 + 0x30); //显示Hour高位
  LCD1602_printc(8 + 0x30); //显示Hour低位
  LCD1602_printc(':');
  LCD1602_printc(0 + 0x30); //显示Minute高位
  LCD1602_printc(0 + 0x30); //显示Minute低位
  LCD1602_printc(':');
  LCD1602_printc(0 + 0x30); //显示Second高位
  LCD1602_printc(0 + 0x30); //显示Second低位
}
while(!key1);
}

if(!key2) //切换时间
{
flag1++;
if(flag1>3)
{
flag1=1;
}
while(!key2);
}

if(!key3)
{
if(flag1==1)
{
hournum++;
if(hournum>24)
{
hournum=0;
}
}

if(flag1==2)
{
minutenum++;
if(minutenum>60)
{
minutenum=0;
}
}

while(!key3);
}
}

void twpd() //投喂判断
{
if(flag2 == 0)
{
if(YL>numbermax)
{
out1=0;
out2=0;
beep=0;
}
else
{
out1=1;
out2=0;
beep=1;
Delay(300);
beep=0;
Delay(300);
}
 }

}

四、实现现象

具体动态效果看B站演示视频:

基于51单片机的宠物喂食系统设计_哔哩哔哩_bilibili

全部资料(源程序、仿真文件、安装包、演示视频):

通过百度网盘分享的文件:基于51单片机的宠物喂食系统设计.zip
链接:https://pan.baidu.com/s/1hxCikh5QDz6SodvzQIOn4w 
提取码:hszh 
–来自百度网盘超级会员V4的分享


原文地址:https://blog.csdn.net/szq0419/article/details/142327486

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!