基于单片机智能鱼缸控制设计(自动喂鱼的鱼缸自动控制系统设计与制作)
各位小伙伴大家好,考研的事总算告一段落了,最近有点难受去医院一查,呀,好像有点神经衰弱,干什么都有点力不从心,热心的护士小姐姐给我测量了体温查看健康码一气呵成,然后顺利进入了医院。回到家喂了一下鱼感觉有点麻烦,于是就有了自动喂鱼器这个想法。在网上找了很久,就看到一个用15F104W单片机 只用定时器功能定时震动下鱼食的,不太喜欢,今天给大家分享一个我自己设计制作,还算比较满意的小作品。
单片机电路原理图如下:可能有点丑啊
手绘电路图:
控制端口分配:
引脚分配 lcd lcddata: P0
lcd_e: P2^7
lcd_rs: P2^6
lcd_rw: P2^5
设置按键 limit_choise: P //温度上下限选择按键
increase_temperature P //增加温度限值按键
reduce_temperature P //减少温度限值按键
蜂鸣器报警 warning P
温度传感器 temperature_sensor P
制热 heatting P
制冷 refrigerating P
LED显示 normal P //正常温度指示灯
high_temperature P //高温指示灯
low_temperature P //低温指示灯
C语言参考源代码 如下:
#include <main.h>
void DelayUs(unsigned char tu)
{
while(--tu);
}
void DelayMs(unsigned char tm)
{
while(tm--)
{
DelayUs(248);
DelayUs(248);
}
}
void dianji() //喂鱼
{
unsigned int i;
speed=10;
i=3000;
while(i--)
{
A_ON
DelayMs(speed);
AB_ON
DelayMs(speed);
B_ON
DelayMs(speed);
BC_ON
DelayMs(speed);
C_ON
DelayMs(speed);
CD_ON
DelayMs(speed);
D_ON
DelayMs(speed);
DA_ON
DelayMs(speed);
}
ABCD_OFF
}
void dianji_shoudong() //手动喂鱼
{
unsigned int i;
speed=10;
i=500;
while(i--)
{
A_ON
DelayMs(speed);
AB_ON
DelayMs(speed);
B_ON
DelayMs(speed);
BC_ON
DelayMs(speed);
C_ON
DelayMs(speed);
CD_ON
DelayMs(speed);
D_ON
DelayMs(speed);
DA_ON
DelayMs(speed);
}
ABCD_OFF
}
void Timer0Init()
{
TMOD|=0X01;
TH0=0xB8; //11.0592M晶振 定时20ms
TL0=0x00;
ET0=1;
EA=1;
TR0=1;
}
void main()//主函数
{
init();//初始化函数
K1=1;
XIAODU=1;
YANGQI=1;
BENG=1;
Timer0Init();
while(1)
{
temp_control();//控制按键函数
unnormal_proccessing(get_temp(Ds18b20ReadTemp()),up_limit_temp,down_limit_temp);//恒温控制函数
if((h==0)&(m==0)&(s==5))BENG=0; if((h==3)&(m==0)&(s==0))BENG=1;
if((h==4)&(m==0)&(s==0))BENG=0; if((h==7)&(m==0)&(s==0))BENG=1;
if((h==8)&(m==0)&(s==0))BENG=0; if((h==11)&(m==0)&(s==0))BENG=1;
if(BENG==1)
{
YANGQI=0;
XIAODU=1;
}
else
{
YANGQI=1;
XIAODU=0;
}
if((h==6)&(m==0)&(s==0))
{
dianji();
}
if(K1==0)
{
DelayMs(20);
if(K1==0)
{
dianji_shoudong();
}
}
}
}
void init()//初始化函数
{
uint i,j;
//函数初始化
LcdInit();//LCD初始化函数
Ds18b20Init();
//I/O口初始化
heatting=1;//不制热
refrigerating=1;//不制冷
normal=1;//正常温度指示灯不显示
unnormal=1;//不正常温度指示灯不显示
warning=1;//蜂鸣器不报警
//LCD初始化显示
LcdWriteCom(0x80);//第一行显示
j=strlen(num1);
for(i=0; i<j; i )
{
LcdWriteData(num1[i]);
delay_ms(1);
}
LcdWriteCom(0x80 0x40);//第二行显示
j=strlen(num2);
for(i=0; i<j; i )
{
LcdWriteData(num2[i]);
delay_ms(1);
}
LcdWriteCom(0x04); //关闭写一个指针加1
}
uint get_temp(uint temp)//计算温度函数
{
float tp;
tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
temp=tp*0.0625*100 0.5;
//留两个小数点就*100, 0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而 0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
return temp;
}
void display_real_tenp(uint temp)//实时温度显示函数
{
uchar datas[] = {0, 0, 0, 0}; //定义数组
datas[0] = temp % 10000 / 1000;
datas[1] = temp % 1000 / 100;
datas[2] = temp % 100 / 10;
datas[3] = temp % 10;
LcdWriteCom(0x80 0x0a); //写地址 80表示初始地址
LcdWriteData('0' datas[0]); //十位
LcdWriteCom(0x80 0x0b); //写地址 80表示初始地址
LcdWriteData('0' datas[1]); //个位
LcdWriteCom(0x80 0x0d); //写地址 80表示初始地址
LcdWriteData('0' datas[2]); //显示小数点
LcdWriteCom(0x80 0x0e); //写地址 80表示初始地址
LcdWriteData('0' datas[3]); //显示小数点
}
void temp_control()//控制温度上下限函数
{
if(limit_choise==0)//选择按键
{
delay_ms(5);
if(limit_choise==0)
{
while(!limit_choise);
limit_choise_num ;
if(limit_choise_num>=3)
{
limit_choise_num=0;
}
}
}
if(limit_choise_num==0)//正常显示
{
LcdWriteCom(0x0c);//关闭光标
display_real_tenp(get_temp(Ds18b20ReadTemp()));//显示函数
}
if(limit_choise_num==1)//调节上限温度
{
LcdWriteCom(0x80 0X40 2);
LcdWriteCom(0x0f);//开启光标
if(increase_temperature==0)//增加温度
{
delay_ms(5);
if(increase_temperature==0)
{
while(!increase_temperature);
up_limit_temp ;
if(up_limit_temp>=100)
{
up_limit_temp=0;
}
//写入新数据
LcdWriteCom(0x80 0X40 0x03);
LcdWriteData('0' up_limit_temp/10);
LcdWriteCom(0x80 0X40 0x04);
LcdWriteData('0' up_limit_temp);
LcdWriteCom(0x80 0X40 2);//光标回写
}
}
if(reduce_temperature==0)//减少温度
{
delay_ms(5);
if(reduce_temperature==0)
{
while(!reduce_temperature);
up_limit_temp--;
if(up_limit_temp<0)
{
up_limit_temp=99;
}
//写入新数据
LcdWriteCom(0x80 0X40 0x03);
LcdWriteData('0' up_limit_temp/10);
LcdWriteCom(0x80 0X40 0x04);
LcdWriteData('0' up_limit_temp);
LcdWriteCom(0x80 0X40 2);//光标回写
}
}
}
if(limit_choise_num==2)//调节下限温度
{
LcdWriteCom(0x80 0X40 12);
LcdWriteCom(0x0f);//开启光标
if(increase_temperature==0)//增加温度
{
delay_ms(5);
if(increase_temperature==0)
{
while(!increase_temperature);
down_limit_temp ;
if(down_limit_temp>=100)
{
down_limit_temp=0;
}
//写入新数据
LcdWriteCom(0x80 0X40 0x0d);
LcdWriteData('0' down_limit_temp/10);
LcdWriteCom(0x80 0X40 0x0e);
LcdWriteData('0' down_limit_temp);
LcdWriteCom(0x80 0X40 12);//光标回写
}
}
if(reduce_temperature==0)//减少温度
{
delay_ms(5);
if(reduce_temperature==0)
{
while(!reduce_temperature);
down_limit_temp--;
if(down_limit_temp<0)
{
down_limit_temp=99;
}
//写入新数据
LcdWriteCom(0x80 0X40 0x0d);
LcdWriteData('0' down_limit_temp/10);
LcdWriteCom(0x80 0X40 0x0e);
LcdWriteData('0' down_limit_temp);
LcdWriteCom(0x80 0X40 12);//光标回写
}
}
}
}
void unnormal_proccessing(uint temp,uint up_temp,uint down_temp)//恒温控制函数
{
uchar datas[] = {0, 0, 0, 0}; //定义数组
uint temp1=0;
datas[0] = temp % 10000 / 1000;
datas[1] = temp % 1000 / 100;
datas[2] = temp % 100 / 10;
datas[3] = temp % 10;
temp1=datas[0]*1000 datas[1]*100 datas[2]*10 datas[3];//实际的温度乘以100
if(temp1 < down_temp*100)//升温函数
{
heatting=0;//制热
refrigerating=1;//不制冷
unnormal=0;//不正常温度指示灯显示
normal=1;//正常温度指示灯不显示
//蜂鸣器报警
//warning=0;
//delay_ms(10);
//warning=1;
}
else if(temp1 > up_temp*100)//降温函数
{
heatting=1;//不制热
refrigerating=0;//制冷
unnormal=0;//不正常温度指示灯显示
normal=1;//正常温度指示灯不显示
//蜂鸣器报警
// warning=0;
// delay_ms(10);
// warning=1;
}
else//正常
{
heatting=1;//不制热
refrigerating=1;//不制冷
unnormal=1;//不正常温度指示灯不显示
normal=0;//正常温度指示灯显示
//蜂鸣器不报警
// warning=1;
}
}
void Time0() interrupt 1
{
static u8 i;
TH0=0xB8; //11.0592M晶振 定时20ms
TL0=0x00;
i ;
if(i>=50) //1秒时间到
{
i=0;
鉴于篇幅限制,只能写部分代码
最后,如果有什么意见或者建议欢迎您留言给我,让我们共同学习一起进步,
如果需要 完整代码或设计文件,请在下方留言或者私信我,看到后会第一时间回复。
谢谢!
感谢你的阅读,希望您有所收获,喜欢请点赞评论加关注!
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com