目錄
一、主要功能
二、使用步驟
三、硬件資源
四、軟件設計
五、實驗現象
一、主要功能
1、LCD1602液晶顯示時間、溫度、食物重量
2、按鍵手動投喂食物?
3、稱重模塊檢測當前食物重量
4、食物重量小于閾值會聲光警報并自動投喂
二、使用步驟
基于51單片機的寵物投食系統通常包含以下功能顯示模塊使用LCD1602液晶屏,實時展示時間、溫度及食物重量數據,投喂執行機構采用步進電機(ULN2003驅動)或舵機,實現正反轉控制投食口開關。
三、硬件資源
1、51單片機核心模塊
2、按鍵模塊
3、溫度傳感器、稱重傳感器模塊、步進電機模塊
4、蜂鳴器模塊、繼電器模塊
5、時鐘模塊、數模轉換模塊
6、LCD1602顯示模塊
四、軟件設計
#include "reg52.h"?? ??? ?
#include "ds1302.h"?? ?
#include "lcd.h"
#include "temp.h"
#include "intrins.h"
typedef unsigned int u16;?? ? ?
typedef unsigned char u8;
#define ulong unsigned long
#define GPIO_MOTOR P1
sbit KEY1 = P3^0;
sbit BEEP = P2^7;
sbit LED1 ?= P3^3;
sbit DOUT=P3^4;?? ?//定義2543數據讀取口
sbit DIN =P3^5;?? ?//定義2543數據寫入口
sbit CS ?=P3^6;?? ?//定義2543片選信號口
sbit CLK =P3^7;?? ?//定義時鐘信號口
bit adjust;//調節標志位 ?0-1
u8 num;//鬧鐘調節位
u8 hour_shi, hour_ge, minute_shi, minute_ge;//鬧鐘調節
ulong Volt;//測量的電壓值
ulong AD_Volt;//測量的電壓值
ulong quality;//檢測重量
ulong quality_set=2000;//設置的重量閾值200克
unsigned char code FFW_X[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09}; //X反轉順序
unsigned char code FFZ_X[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1}; //X正轉順序
unsigned char Direction,stop=0;
void delay30ms(void) ? //誤差 0us
{
? ? unsigned char a,b;
? ? for(b=101;b>0;b--)
? ? ? ? for(a=147;a>0;a--);
}
void Delay(unsigned int t)
{
?unsigned int k;
?while(t--)
?{
?for(k=0; k<80; k++)
?{ }
?}
}
void Motor()
{
?? ?unsigned char a=30;
?unsigned char i;
?for(i=0;i<8;i++)
?{
? if(Direction==1&&stop==0)?? ??? ? //正轉電機&電機沒按下停止
?GPIO_MOTOR = FFW_X[i]&0x0F;//取數據
?if(Direction==2&&stop==0)?? ??? ? //反轉&X電機&電機沒按下停止
?GPIO_MOTOR = FFZ_X[i]&0x0F;
?
? Delay(a);
? }
}
void Read2543(uchar addr)
{
?? ?uint ad=0;
?? ?uchar i;
?? ?CLK=0;
?? ?CS=0;//片選段,啟動2543
?? ?addr<<=4;//對地址位預處理
?? ?for(i=0;i<12;i++) //12個時鐘走完,完成一次讀取測量
?? ?{
?? ??? ?if(DOUT==1)
?? ??? ??? ?ad=ad|0x01;//單片機讀取ad數據
?? ??? ?DIN=addr&0x80;//2543讀取測量地址位
?? ??? ?CLK=1;
?? ??? ?;;;//很短的延時
?? ??? ?CLK=0;//產生下降沿,產生時鐘信號
?? ??? ?;;;
?? ??? ?addr<<=1;
?? ??? ?ad<<=1;//將數據移位準備下一位的讀寫
?? ?}
?? ?CS=1;//關2543
?? ?ad>>=1;
?? ?Volt=ad;//取走轉換結果
?? ?//Volt=Volt*1221;//例子的滿量程為5V,轉換分辯率為12位(2的12次方=4096) 。即最大值是255,5/4096=1221mV,即例子中的1V代表實際1221mV
??
?? ?Volt=Volt*5000/4095;
?? ?quality=(Volt/5.12+40)*10/4;//計算壓力
?? ?//Pressure=(Volt/5.41+40)*10/4;
?? ??? ?
}
void KEY_Control()//按鍵調節
{
?? ?if(KEY1==0)
?? ?{
?? ??? ?delay30ms();
?? ??? ?if(KEY1==0)
?? ??? ?{
?? ??? ? ?stop=0;
?? ??? ? ?? ?Direction=1;?? ?
?? ??? ?}
?? ?}
?? ?
}
void show_quality(void)//顯示重量
{
?? ?quality=quality-30;
?? ??? ?DisplayOneChar(11,0,(char)(quality/1000+'0'));
? ?? ?DisplayOneChar(12,0,(char)(quality%1000/100+'0'));
?? ? ?DisplayOneChar(13,0,(char)((quality%100)/10+'0'));
?? ?
?? ?if( quality <= quality_set )
?? ?{
?? ??? ?stop=0;
?? ??? ?Direction=1;
?? ??? ?BEEP=0;
?? ??? ?LED1=0;
?? ??? ?Delay(200);
?? ??? ?BEEP=1;
?? ??? ?LED1=1;
?? ??? ?Delay(300);
?? ?}
?? ?
?? ?if( quality > quality_set )
?? ?{
?? ??? ?stop=1;
?? ??? ?
?? ??? ?BEEP=1;
?? ??? ?LED1=1;
?? ??? ?
?? ?}
}
void main()//主函數
{?? ?
?? ?
?? ?LcdInit();
?? ?DisplayOneChar(0,0,'2'); DisplayOneChar(1,0,'0'); DisplayOneChar(4,0,'-'); DisplayOneChar(7,0,'-');//2022-05-05 ?6
?? ?DisplayOneChar(2,1,':'); DisplayOneChar(5,1,':'); DisplayOneChar(2,1,':');//13:39:40?? ?
?? ?DisplayListChar(9,1,"T:"); DisplayOneChar(13,1,'.'); DisplayOneChar(15,1,'C');//T:23.5C
?? ?DisplayOneChar(15,0,'g');
?? ?while(1)
?? ?{
?? ??? ?
?? ??? ?KEY_Control();//按鍵控制
?? ??? ?Motor();//步進電機控制
?? ??? ??? ?
?? ??? ?Read2543(0);//檢測重量
?? ??? ?show_quality();//顯示重量
?? ??? ?
?? ??? ?ReadTemperature();//讀取溫度?? ?
?? ??? ?DisplayTemp();//顯示溫度? ??
?? ??? ?Ds1302ReadTime();//讀取時間
?? ??? ?DisplayTime();//顯示時間
?? ?}
}
五、實驗現象
演示視頻: