//{
//PWM2=0;
//}
//elsePWM2=1;
if(count>=CYCLE)
{
count=0;
PWM1=0;
//PWM2=0;
}
}
4.3温度显示及检测的实现
温度检测原理:
低温度系数晶振的振荡频率受温度的影响很小,用于产生固定频率的脉冲信号送给减法计数器1,高温度系数晶振随温度变化其震荡频率明显改变,所产生的信号作为减法计数器2的脉冲输入,当计数门打开时,DS18B20就对低温度系数振荡器产生的时钟脉冲进行计数,进而完成温度测量。
计数门的开启时间由高温度系数振荡器来决定,每次测量前,首先将-55℃所对应的基数分别置入减法计数器1和温度寄存器中,减法计数器1和温度寄存器被预置在-55℃所对应的一个基数值。
减法计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当减法计数器1的预置值减到0时温度寄存器的值将加1,减法计数器1的预置将重新被装入,减法计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到减法计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。
温度显示及检测子程序:
voidLcdDisplay(inttemp)//显示
{
//定义数组
floattp;
if(temp<0)//当温度值为负数
{
LcdWriteCom(0x80);//写地址80表示初始地址
SBUF='-';//将接收到的数据放入到发送寄存器
while(!
TI);//等待发送数据完成
TI=0;//清除发送完成标志位
LcdWriteData('-');//显示负
//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
temp=temp-1;
temp=~temp;
tp=temp;
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算由0.5,还是在小数点后面。
}
else
{
LcdWriteCom(0x80);//写地址80表示初始地址
LcdWriteData('+');//显示正
SBUF='+';//将接收到的数据放入到发送寄存器
while(!
TI);//等待发送数据完成
TI=0;//清除发送完成标志位
tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
}
datas[0]=temp/10000;
datas[1]=temp%10000/1000;
datas[2]=temp%1000/100;
datas[3]=temp%100/10;
datas[4]=temp%10;
}
4.4数码管显示模块的实现
数码管显示利用38译码器进行段选和位选,并通过数码管输出信号。
由于只要求显示四位,故只驱动四个数码管。
数码管显示子程序:
voidDigDisplayr()interrupt1
{
//定时器在工作方式二会自动重装初,所以不用在赋值。
//TH0=0X9c;//给定时器赋初值,定时1ms
//TL0=0X00;
DIG=0;//消隐
switch(Num)//位选,选择点亮的数码管,
{
case(7):
LSA=0;LSB=0;LSC=0;break;
case(6):
LSA=1;LSB=0;LSC=0;break;
case(5):
LSA=0;LSB=1;LSC=0;break;
case(4):
LSA=1;LSB=1;LSC=0;break;
//case(3):
//LSA=0;LSB=0;LSC=1;break;
//case
(2):
//LSA=1;LSB=0;LSC=1;break;
//case
(1):
//LSA=0;LSB=1;LSC=1;break;
//case(0):
//LSA=1;LSB=1;LSC=1;break;
}
DIG=disp[Num];//段选,选择显示的数字。
Num++;
if(Num>7)
Num=0;
}
4.5光电传感模块的实现
通过光电开关接收外部的控制信号,当外部无信号时,光电开关输出高电平,当光电开关检测到卷帘机运动到极限位置时,由于遮挡,输出低电平,卷帘机停止运动。
温度传感器达到设定温度时,光电开关传感器恢复动作。
光电开关传感器子程序:
voidmain()
if(((temp%1000/100>0))&&((temp%1000/100<2)))
{
fanzhuan();
if(key1==0)//停止传感器
{
ting();
}
}
else
{
ting();
}
if(((temp%1000/100>2))&&((temp%1000/100<4)))
{
zhengzhuan();
if(key1==0)//停止传感器
{
ting();
}
}//高温
4.6系统分析
智能大棚系统基本上可以满足前期的设计要求,能够完成温湿度自动检测,自动灌溉等功能。
但同时也存在着一些设计之前未曾预料到的问题,主要问题如下:
1.直流电机的调速不完美。
理论上,直流电机通过L298N调速之后可以输出各种电压,但实际调速中,由于受到电机参数等影响,最终输出电压只能稳定在3V左右。
同时,输出的电压由于实时检测,所以很不稳定,导致电机有堵转的情况发生,电机在启动过程中,启动惯性较大,但提供的启动电流较小。
2.单片机的输出端口接负载时,对外输出产生影响。
单片机的某些端口,由于外加负载,对外输出电压发生变化。
L298N驱动板在调试过程中碰到了P1端口输出电压较小的问题,直接影响了桥式电路的运行,在花费了半天的时间之后才发现毛病。
3.温度传感器对电机运行的影响。
由于温度传感器对信号进行实时转化,这样,温度便在实时的变化,电机依照设定的温度进行运行,由于温度的跳跃性,以及温度传感器的检测精度等问题,导致,电机的运行不精确。
第六节课程设计总结
通过各种方案的讨论和尝试,再经过多次的整体软硬件的结合调试,不断的对系统进行优化,智能大棚系统可以完成各项功能。
大棚模型总长25mm,宽20mm,高15mm。
在系统的设计过程中,我们力求硬件线路简单,充分发挥软件编程灵活方便的特点,来满足系统设计的要求。
从最终综合测试的结果来看,本系统能够很好地完成设计要求,并具有发展空间。
在本次设计活动中,我们学到了很多东西,从机械到软件,掌握了各种元件的基本原理,并学会了使用方法,注意事项等,极大地丰富了我们的课外知识,拓宽了我们的知识面。
在整个设计、制造的过程中,还遇到了很多突发的事件和各种困难。
直流电机调速过程中,单个电机运行可以满足各种调速要求,但是,当直流电机和温度模块整合测试时,由于温度测量模块18b20使用数码管输出温度,在显示过程中,需要不断地进行“刷屏”,因此需要用定时中断程序;而PWM电机调速中,输出的PWM波形,同样也是依靠定时中断程序来完成的,这两个中断发生冲突。
温度显示模块的定时程序对时间的要求较低,(定时时间不需要太短,只要刷屏的速度超过人的肉眼的辨别力即可)而PWM的定时,由其原理决定,定时时间要求极短,这样才能满足波形精确的要求。
通过不断的进行调试、整合、修改,最终将输出电压稳定在3V左右。
同样,在程序的最终整合阶段,由于使用了温度、湿度、光电传感器,这样就需要不断的进行AD转化,多路信号的传输,对单片机的运行提出了很高的要求,多次遇到多路信号相互影响的情况,但通过仔细的分析、讨论和我们自己的调整,最后这些问题都解决了,提高了我们分析问题,解决问题的能力,也进一步提高了我们的动手能力。
在硬件模型制作的过程中更是对我们的动手能力提出了较高的要求,大棚的拱形模型的制作耗费了大量的时间,卷帘机的制作也让我们吃尽了苦头。
不过,值得欣慰的是,模型最终制成了,也基本满足了我们的要求。
无可否认,在调试的艰难阶段,也想过放弃,不过,最终还是坚持下来了。
在这里对给予我们帮助的王常顺、饶中洋老师,以及韩峰波、段成杰、董勇圣、王智、吴明明、冯延猛等同学一并表示感谢。
这次活动让我学到了很多课堂之内远远学不到的东西,譬如毅力、耐力,这些都将使我终生获益,而我们也认为,精神上的收获与充实,高于最终比赛的成绩。
附录
附录1:
实物模型
附录2:
主程序:
#include
#include"temp.h"
#include"i2c.h"
//--定义使用的IO--//
#defineGPIO_DIGP0
sbitLSA=P2^2;
sbitLSB=P2^3;
sbitLSC=P2^4;
sbitwet=P2^7;
//--定义PCF8591的读写地址--//
#defineWRITEADDR0x90//写地址
#defineREADADDR0x91//读地址
//--定义全局变量--//
unsignedcharcodeDIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsignedcharDisplayData[8];
//用来存放要显示的8位数的值
//unsignedcharcodeFFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9};//反转顺序
//unsignedcharcodeFFZ[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1};//正转顺序
//unsignedcharDirection,Speed;
//
//--声明全局函数--//
voidDigDisplay();//动态显示函数
voidPcf8591SendByte(unsignedcharchannel);
unsignedcharPcf8591ReadByte();
voidPcf8591DaConversion(unsignedcharvalue);
voidDigDisplay();
//数码管IO
#defineDIGP0
/*sbitLSA=P2^2;
sbitLSB=P2^3;
sbitLSC=P2^4;
inttemp;
unsignedcharcodeDIG_CODE[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};*/
unsignedcharNum=0;
unsignedintdisp[8]={0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f};
unsignedcharPWM1,PWM2;
sbitIN1=P2^0;//没用
sbitIN2=P2^1;//没用
sbitIN3=P2^5;
sbitIN4=P2^6;
sbitPWM_zuo=P0^4;//没用
sbitPWM_you=P1^6;
sbitkey1=P3^1;//停止按键
CYCLE=8;
count=0;
PWM_ON1=7;
PWM_ON2=7;
voidLcdDisplay(int);
voidTimer0Configuration();
voidchushihua()
{
TMOD=0x10;
TH1=0x9c;
TL1=0x9c;
IE=0x88;
TR1=1;
}
voiddianji()
{
PWM_zuo=PWM_you=PWM1;
//PWM_you=PWM2;
}
voidzhengzhuan()//RIGHT
{
IN