【单片机仿真】基于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的分享