毕业设计(论文)基于单片机的粮食仓库实时温度监控报警系统_第1页
毕业设计(论文)基于单片机的粮食仓库实时温度监控报警系统_第2页
毕业设计(论文)基于单片机的粮食仓库实时温度监控报警系统_第3页
毕业设计(论文)基于单片机的粮食仓库实时温度监控报警系统_第4页
毕业设计(论文)基于单片机的粮食仓库实时温度监控报警系统_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、单片机毕业设计粮食仓库实时温度监控报警系统院 系: 班 级: 设 计 :学 号: 指 导 老 师: 设计日期:目 录第1章 引言3第2章 设计任务分析5第3章 仓库环境温度实时监控系统的总体设计5 一、总体设计框图.5 二、 硬件设计.6 三、软件设计.7 设计小结. .29 参考文献. 30第1章 引言本论文是基于单片机的仓库温湿度监控系统,该系统克服了传统装置的不足之处,由信号采集、信号分析和信号处理三个部分组成的,是一种造价低廉、使用方便简单,且测量准确的温湿度测量装置。论文介绍 本设计用于温度的智能控制,节能环保,低耗能,噪音低,设计合理,体现了优化设计低碳生活的理念。下面是本设计的具

2、体内容及功能说明。1.温度测量,测量范围0-125 c2.数字式温度范围可调,0-125 c。各种设定值在掉电后不会丢失,各种温度初始化设定值如下所述: 风机启动:90 c 风机停止:70 c 超温报警:120 c 报警: 100 c3.保存上次掉电时的瞬间温度,最高温度,最低温度。4.可以手动启停风机,超温报警,报警信号的显示。5.可以声光报警。6.带时钟显示,可以调整时间,7.可以查看掉电时,瞬间温度的时间,最高温度的时间,最低温度的时间8.闹钟设置功能9.闹钟初始值 是 8:00(1键是确定键,2键是加键,3是减键,4是退出键,5是设置温度键,6是时间设置键,7是查看掉电前时的瞬间温度及

3、出现的时间,最高温度及出现的时间,最低温度及出现的时间,当前最高时的温度及出现的时间。8键时设置闹钟时的时间。9键手动开关风机,超温跳闸,报警。)10. 可以与上位机进行通讯:上位机 (1)按下1键可以在上位机查看掉电前瞬间时的温度,及时间 (2)按下2键时在上位机可以看到此刻的温度,及时间 (3)按下3键可在上位机以看到设定超温的温度 也就是跳闸温度 (4)按下4键可以在上位机看到设定的报警温度 (5)按下5键在上位机上可以看到设定的开风机温度 (6)按下6键在上位机上可以看到设定的关风机温度 (7)按下7键可以实现开风机 (8)按下8键可以实现关风机11、设置时间:按下设置时间键后,接下来

4、设置月,设置日,设置时,设置分,设置时,按2,3键进行调整数值,设置时可以按退出键(4)退出。12.设置闹钟时,按下设置闹钟键后,接下来设置时,分,按2,3键进行调整数值,设置时可以按退出键(4)退出。13.设置温度:按下设置温度键后,会弹出提示语,ok按1键,ese按4键,设置完后,按ok键可以退出,在中间设置时,可以按退出键(4)退出。14查询温度:按下查询温度键后,按下2,3键可以切换查询的内容,在温度后面显示的数字:0代表掉电前瞬间时的温度,1代表掉电前出现的最高温度,2代表掉电前出现的最低温度,3代表此次出现的最高温度,4代表此次出现的最低温度。按退出键(4)退出查看。15.手动开关

5、风机,当按下9键后,超温跳闸,按2,3键后可以超温跳闸,报警,开风机,关风机之间切换,按退出键(4)键退出手动操作。第2章 设计任务分析一实时 :能够按照实际的日期时间显示和记录各项待检测物理量的参数值。二温度:能够检测各连续时间点所对应的的温度值。三监控:用户随时能够了解到仓库任意时间(包括历史时间)的温度状况以及做出相应的对策和处理措施,特别是不需要工作人员到仓库现场就可以知道仓库里的温度环境状况。四报警:当仓库的环境温度超过设定值时系统报警,风机启动,然后进行通风。五本系统通过液晶显示器将时间和温度显示给用户以及和上位机通讯。第3章 仓库环境温度实时监控系统的总体设计一、总体设计框图单

6、片 机仓库检测温度时钟输入i²c总线lcd 液晶显示功率接口(驱动器)继电器风机声音报警通讯二、 硬件设计(附图) 重要元器件介绍 此次设计用到的芯片有at89s52、at2404、lcm2402、uln2003、maxim487、dst302、ds18b20三 、软件设计设计程序如下:30 #include<reg52.h>#include<sring.h>#define uchar unsigned char#define uint unsigned int uchar count,count1;uchar clock_beep;char k_diaodi

7、an;uchar chaowenflag,baojinflag,kaifengjiflag;uchar key_ok=0; uchar key_ese=0;uchar key_add1=0; uchar key_add2=0; uchar key_settemp=0;uchar key_time=0;uchar key_searchtem=0; uchar key_clock=0;uchar key_qiting=0;uchar ser_flag=0;uchar ser_a=0;#define lcm2402_db0_db7 p0 /数据总线 sbit lcm2402_rs =p25; /定义

8、lcm2402的rs控制线sbit lcm2402_rw =p24; /定义lcm2402 的rw控制线sbit lcm2402_e =p23; /定义lcm2402的e控制线sbit lcm2402_busy =p07; /定义lcm2402的侧忙线 /lcm2402指令集#define cmd_clear 0x01 #define cmd_back 0x02#define cmd_dec1 0x04#define cmd_add1 0x06#define cmd_dis_gb1 0x0f#define cmd_dis_gb2 0x0e#define cmd_dis_gb3 0x0c#def

9、ine cmd_off_dis 0x08#define cmd_set82 0x38#define cmd_set81 0x30#define cmd_set42 0x28#define cmd_set41 0x20#define lin_1 0x80#define lin_2 0xc0/ 底层协议void delays(uint a) /延时 大概1ms uchar i; while (-a!=0) for(i=0;i<125;i+) ; void delays250(void) /延时 delays(250); / lcm2402测忙,若lcm2402处于忙状态,本函数将继续测忙,直

10、到lcm2402处于非忙状态 void lcm2402_testbusy(void ) lcm2402_db0_db7=0xff; /设备读状态 lcm2402_rs=0; lcm2402_rw=1; lcm2402_e=1; while (lcm2402_busy); lcm2402_e=0; void lcm2402_writecmd(uint lcm2402_command) lcm2402_testbusy(); lcm2402_db0_db7=lcm2402_command; lcm2402_rs=0; lcm2402_rw=0; lcm2402_e=1; lcm2402_e=0;

11、void lcm2402_writedata(uint lcm2402_data) lcm2402_testbusy(); lcm2402_db0_db7=lcm2402_data; lcm2402_rs=1; lcm2402_rw=0; lcm2402_e=1; lcm2402_e=0; void lcm2402_init(void) lcm2402_writecmd(cmd_set82); lcm2402_writecmd(cmd_clear); lcm2402_writecmd(cmd_back); lcm2402_writecmd(cmd_add1); lcm2402_writecmd

12、(cmd_dis_gb3); void print (uint *str) lcm2402_writecmd(a); while (*str!='0') lcm2402_writedata(*str+);*str=0; void print2(uint a,uint t) lcm2402_writecmd(a); lcm2402_writedata(t); /写数据lcm创建小汉字 unsigned int code xword= 0x18,0x18,0x07,0x08,0x08,0x08,0x07,0x00, /c 0x00,0x00,0x00,0x00,0xff,0x00,

13、0x00,0x00, /一 0x00,0x00,0x00,0x0e,0x00,0xff,0x00,0x00, /二 0x00,0x00,0xff,0x00,0x0e,0x00,0xff,0x00, /三 0x00,0x00,0xff,0xf5,0xfb,0xf1,0xff,0x00, /四 0x00,0xfe,0x08,0xfe,0x0a,0x0a,0xff,0x00, /五 0x00,0x0r,0x00,0xff,0x00,0x0a,0x11,0x00, /六 0x00,0x1f,0x11,0x1f,0x11,0x11,0x1f,0x00, /日; void cgramwrite(void)

14、 /装入cgram unsigned int i,k; k=at24c02_read(0x33); /读取标志位,多次开机,只执行一次这程序 if(k=1) lcm2402_writecmd(0x06); / cgram地址自动加一 lcm2402_writecmd( 0x40); /cgram 地址设为00处 for(i=0;i<64;i+) lcm2402_writedata(xwordi); at24c02_writecmd(0x33,0); / 写入0标志位 /at24c02芯片 的处理sbit scl=p21;sbit sda=p22;sbit mos_bitsbit low_

15、bitdata com_data / 定义一个能位寻址的变量mos_bit= com_data7;low_bit= com_data0;void start() sda=1; _nop_(); _nop_(); _nop_(); _nop_(); scl=1; _nop_(); _nop_(); _nop_(); _nop_(); sda=0; _nop_(); _nop_(); _nop_(); _nop_(); scl=0; _nop_(); _nop_(); _nop_(); _nop_(); void stop() sda=0; _nop_(); _nop_(); _nop_(); _

16、nop_(); scl=1; _nop_(); _nop_(); _nop_(); _nop_(); sda=1; _nop_(); _nop_(); _nop_(); _nop_(); void ack() scl=1; _nop_(); _nop_(); _nop_(); _nop_(); scl=0; _nop_(); _nop_(); _nop_(); _nop_();void shift8(char a) data uchar i; com_data=a; for(i=0;i<8;i+) sda=mos_bit; scl=1; _nop_(); _nop_(); _nop_()

17、; _nop_(); scl=0; _nop_(); _nop_(); _nop_(); _nop_(); com_data=com_data*2; unsigned char at24c02_read(char a) /读数据 data unsigned char i,command; sda=1; _nop_(); _nop_(); _nop_(); _nop_(); scl=0; _nop_(); _nop_(); _nop_(); _nop_(); start(); command=160; shift(command); ack(); shift8(a); ack(); start(

18、); command=161; shift8(command); ack(); sda=1; _nop_(); _nop_(); _nop_(); _nop_(); for(i=0;i<8;i+) com_data=com_data*2; scl=1; _nop_(); _nop_(); _nop_(); _nop_(); low_bit=sda; scl=0; _nop_(); _nop_(); _nop_(); _nop_(); stop(); return com_data; void at24c02_write(char a,char b) /写数据,a是地址,b要写的数据 da

19、ta unsigned char command; nop_(); _nop_(); _nop_(); _nop_(); sda=1; _nop_(); _nop_(); _nop_(); _nop_(); scl=0; _nop_(); _nop_(); _nop_(); _nop_(); start(); command=160; shift8(command); ack(); shift8(a); ack(); shift(b); ack(); stop(); nop_(); _nop_(); _nop_(); _nop_(); /ds1302时钟 芯片的初始化sbit clock_cl

20、k=p35; /时钟线sbit clock_dat=p36; /数据线sbit clock_rst=p37; / 复位线sbit a0 = acc0;sbit a1 = acc1;sbit a2 = acc2;sbit a3 = acc3;sbit a4 = acc4; sbit a5 = acc5;sbit a6 = acc6;sbit a7 = acc7;unsigned char yy;mo,dd,xq,hh,mm,ss; /全局变量bit w=0; /调时标志位void clock_ out (unsigned char dd) / 发送8 位数据到1302 acc=dd; clock

21、_dat= a0; clock_clk=1; clock_clk=0; clock_dat= a1; clock_clk=1; clock_clk=0; clock_dat= a2; clock_clk=1; clock_clk=0; clock_dat= a3; clock_clk=1; clock_clk=0; clock_dat= a4; clock_clk=1; clock_clk=0; clock_dat= a5; clock_clk=1; clock_clk=0; clock_dat= a6; clock_clk=1; clock_clk=0; clock_dat= a7; clo

22、ck_clk=1; clock_clk=0;unsigned char clock_in(void) /从1302中接收8位数据 clock_dat=1; a0=clock_dat; clock_clk=1; clock_clk=0; a1=clock_dat; clock_clk=1; clock_clk=0; a2=clock_dat; clock_clk=1; clock_clk=0; a3=clock_dat; clock_clk=1; clock_clk=0; a4=clock_dat; clock_clk=1; clock_clk=0; a5=clock_dat; clock_cl

23、k=1; clock_clk=0; a6=clock_dat; clock_clk=1; clock_clk=0; a7=clock_dat; return (acc); void write_clock(unsigned char ord,unsigned char dd) /写入一个数 clock_clk=0; clock_rst=0; clock_rst=1; clock_out(ord); clock_out(dd); clock_rst=0; clock_clk=1; unsigned char read_clock(unsigned char ord) /读取一个数 unsigne

24、d char dd=0; clock_clk=0; clock_rst=0; clock_rst=1; clock_out(ord); dd=clock_in(); clock_rst=0; clock_clk=1; return(dd);void init_1302(void) /1302初始化 uchar k; k=at24c02_read(0x34); /标志位为一时, if(k=1) write_clock(0x8e,0x00); /允许写操作 write_clock(0x8c,0x10); /年 write_clock(0x8a,0x02); /星期 write_clock(0x88

25、,0x04); /月 write_clock(0x86,0x10); /日 write_clock(0x84,0x11); /小时 write_clock(0x82,0x00); /分钟 write_clock(0x80,0x00); / 秒 write_clock(0x90,0xa5); /充电 write_clock(0x34,0); /写入标志位为0; write_clock(0x8e,0x80); /禁止写操作 / 18b02温度初始化,及相关处理sbit dq =p20;void delay(int num) /延时函数 while(num-);void init_ds18b20(v

26、oid) /初始化ds18b20 uchar x=0; dq=1; delay(8); dq=0; /单片机将dq拉低 delay(80); /精确延时 大于480us dq=1; delay(14); x= dq; delay(20); uchar readonechar(void)/读一个字节 uchar i=0; uchar dat=0; for(i=8;i>0;i-) dq=0; dat>>=1; dq=1; if(dq) dat|=0x80; delay(4); return(dat); void writeonechar(uchar dat) / 写一字节 uch

27、ar i=0; for(i=8;i>0;i-) dq=0; dq=dat&01; delay(5); dq=1; dat>>=1; uint readtemperature(void)/读取温度 uchar a=0; uchar b=0; uint t=0; float tt=0; init_ds18b20(); writeonechar(0xcc); / 跳过序列号的操作 writeonechar(0x44);/启动温度转换 init_ds18b20(); writeonechar(0xcc); / 跳过序列号的操作 writeonechar(0xbe)/读取温度寄

28、存器 a=readonechar(); b=readonechar(); t=b; t<<=8; t=t|a; tt=t*0.0625; t=tt*10+0.5; return(t); void printtemperature(void) 显示温度 uint i=0; uchar a=0,b=0,c=0,d=0; i=readtemperature(); a=i/1000; if(a>0) print2(0xc2,a+0x30); b=i/100-a*10; print2(0xc3,b+0x30); c=i/10%10; print2(0xc4,c+0x30); print

29、2(0xc5,"."); d=t%10; print2(0xc6,d+0x30);print2(0xc7,0x00); / 实时时间显示void realtime_display(void) print (0x80,"20"); print2 (0x82, (read_clock(0x8d)/16)+0x30); print2 (0x83, (read_clock(0x8d)%16)+0x30); print(0x84,"/"); /显示年 print2(0x85,(read_clock(0x89)/16)+0x30); print2

30、(0x86,(read_clock(0x89)%16)+0x30); print(0x87,"/"); /显示月 print2(0x88,(read_clock(0x87)/16)+0x30); print2(0x89,(read_clock(0x87)%16)+0x30); print(0x8b,""); /显示 print2(0x8c,read_clock(0x8b)%16); /显示星期 print(0x8d,""); / 显示 print2(0x8f,(read_clock(0x85)/16)+0x30); /显示小时 pri

31、nt2(0x90,(read_clock(0x85)%16)+0x30); print(0x91,":"); /显示cgram 第一个字模 print2(0x92,(read_clock(0x83)/16)+0x30); / 显示分 print2(0x93,(read_clock(0x83)%16)+0x30); print(0x94,"."); /显示cgram 第一个字模 print2(0x95,(read_clock(0x81)/16)+0x30); /显示秒 print2(0x96,(read_clock(0x81)%16)+0x30); pri

32、nt(0x8a," "); / 在主显示区空白处写入空格 防止乱码 print(0x8e," "); print(0xc0," "); / 按键扫描 void key_scan(void)unsigned char n;/扫描第一行p1=0xfe;n=p1;n&=0xf0;if(n!=0xf0) delay(); p1=0xfe; n=p1; n&=0xf0; if(n!=0xf0) switch(n) case(0xe0):key_ese=1;break; case(0xd0):key_add1=1;break; c

33、ase(0xb0):key_add2=1;break; case(0x70):key_ok=1;break; /扫描第二行p1=0xfd;n=p1;n&=0xf0;if(n!=0xf0) delay(); p1=0xfd; n=p1; n&=0xf0; if(n!=0xf0) switch(n)case(0xe0):key_settemp=1;break; case(0xd0):key_time=1; break; case(0xb0):key_searchtem;break; case(0x70):key_clock=1;break; /扫描第三行 / 后面8个键暂无定义,以

34、备后用p1=0xfb;n=p1;n&=0xf0;if(n!=0xf0) delay(); p1=0xfb; n=p1; n&=0xf0; if(n!=0xf0) switch(n) case(0xe0):qiting=1;break; case(0xd0):;break; case(0xb0):;break; case(0x70):;break; /扫描第四行p1=0xf7;n=p1;n&=0xf0;if(n!=0xf0) delay(); p1=0xf7; n=p1; n&=0xf0; if(n!=0xf0) switch(n) case(0xe0):;bre

35、ak; case(0xd0):;break; case(0xb0):;break; case(0x70):;break; / 按键初始化void key_init() key_ok=0; key_ese=0; key_add1=0; key_add2=0; key_settemp=0; key_time=0; key_searchtem=0; key_clock=0; /产生闹钟 sbit bell_out =p23;void beep( uchar a,uchar b,uchar c,uchar d) for(;a>0;a-) bell_out=bell_out; /产生音频 dela

36、y(b); /音调延时 for(;c>0;c-) bell_out=bell_out; delay(d); bell_out=1; void beep_k(void) / 扬声器按键音 beep(10,60,5,250); void beep_c(void) /超温报警声音 beep(400,26,350,40); void beep_a(void) /报警声音 beep(300,16,250,40); void beep_al(void) /报警声音 beep(100,16,150,40); void beep_z(void) / 整点报时 beep(60,100,100,80); v

37、oid beep_n(void) /闹钟响 beep(200,20,150,15); void kaifengji(); char k; k=at24c02_read(0x32); /判断是否第一次开机,第一次时k=255;第一次时,进行初始化下,不是,则退出 if(k!=1) at24c02_write(0x20,1); /初始化超温,报警,开关风机 at24c02_write(0x21,2); at24c02_write(0x22,0); at24c02_write(0x24,1); at24c02_write(0x25,0); at24c02_write(0x26,0); at24c02

38、_write(0x28,0); at24c02_write(0x29,9); at24c02_write(0x2a,0); at24c02_write(0x2c,0); at24c02_write(0x2d,7); at24c02_write(0x2e,0); at24c02_write(0x30,8); /初始化闹钟 小时 at24c02_write(0x31,0); /分钟 at24c02_write(0x32,1); /初始化第一开机 at24c02_write(0x33,1); /cgram 初始化标志位 at24c02_write(0x34,1); /1302 时间初始化标志位 fo

39、r(i=0;i<48;i+) /初始化掉电前时的温度 at24c02_write(0x40+i,0); void init_time()/两个定时器初始化 一个定时温度,报警,定时1定时闹钟 tmod=0x11; /工作方式1 th0=(65536-50000)/256; /初始值50ms tl0=(65536-50000)%256; th1=(65536-40000)/256; /初始值40ms tl1=(65563-40000)%256; tro=1; tr1=1; ea=1; /开总中断 et0=1; /开定时器0中断 et1=1; /开定时器1中断 void insteadoft

40、emp() /把记入掉电时的温度放在显示区域的空间 char a,b,c; char month,day,hour,minutes; char i; for(i=0;i<3;i+) /掉电时的三个温度,瞬时,最高,最低 month=at24c02_read(0x58+i*8); /存储月 at24c02_write(0x40+i*8,month); day=at24c02_read(0x59+i*8); /存储日 at24c02_write(0x41+i*8,day); hour=at24c02_read(0x5a+i*8); /存储时 at24c02_write(0x42+i*8,ho

41、ur); minutes=at24c02_read(0x5b+i*8); /存储分 at24c02_write(0x43+i*8,minutes); a=at24c02_read(0x5c+i*8); /存储温度的百位 at24c02_write(0x45+i*8,a); b=at24c02_read(0x5d+i*8); /存储温度的十位 at24c02_write(0x45+i*8,a); c=at24c02_read(0x5e+i*8); /存储温度的个位 at24c02_write(0x46+i*8,c); void time1() interrupt 3 /闹钟定时查询 char c

42、_hour,c_minutes; th1=(65536-40000)/256; /每隔40ms定时一次 tl1=(65536-40000)%256; tr1=0; /暂停下定时器,以避免一定时器正处理程序时,另一定时器发生中断 tr0=0; count1+; /0.4s与定时时间相比,时间到了,闹钟响 if(count1=10) count1=0; c_hour=read_clock(0x85); /读取实时时间 小时 c_minutes=read_clock(0x83); / 读取实时时间 分钟 c_hour=c_hour/16*10+c_hour%16; /转换成十进制 c_minutes

43、=c_minutes/16*10+c_minutes%16; /转换成十进制 if(c_hour=at24c02_read(0x30)&&c_minutes=at24c02_read(0x31) /时间到了,闹钟响 clock_beep=1; /全局变量 tr1=1; /开时钟 tr0=1; void time0() interrupt 1 int t; char a,b,c; char month,day,hour,minutes; char highflag=0; /提高效率,判断完最高温度后就不再寻找最低温度 th0=(65536-50000)/256; /初始化定时器,

44、50ms, tl0=(65536-50000)%256; tr0=0; tr1=0; count+; /全局变量,时间计数 if(count=10) /当等于0.5s时读取温度,并把温度值及时间存储下来 t=readtemperature(); /读取温度,温度共四位,百位,十位,个位,还有小数位,小数位存储。a=t/1000; /百位b=t/100-a*10; /十位c=t/10%10; /个位 at24c02_write(5c,a); / 存储百位at24c02_write(5d,b); / 存储十位 at24c02_write(5e,c); /存储个位 month=read_clock(0x89); /读取月,显示月at24c02_write(0x58,month);day=read_clock(0x87); /读取日,显示日at24c02_write(0x59,day); hour=read_clock(0x85); /读取时,显示时at24c02_write(0x5a,hour); minutes=read_clock(0x83); /读取分,显示分at24c02_write(0x5b

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论