找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4456|回复: 5
打印 上一主题 下一主题
收起左侧

基于51单片机水温控制系统综合实训资料文档

[复制链接]
跳转到指定楼层
楼主
实验实现温度的智能控制,温度超过设置温度上下线会蜂鸣器会响及LED小灯发出亮光产生报警,实现实时温控为目的。
实训要求
(1)测量和控制温度
(2)控制精度在正负1
(3)控制输出通道为继电器或双向晶闸管
设计实施
1.系统概述
本实验采用51单片机和温度传感器18B20来设计的,温度测量范围宽,严密性高等特点,温度设计采用逢0.5进一的四舍五入的方法来消除其他客观或非客观因素带来的不利影响,实现温度的实时温度测量及显示,本实验还可自行设置超温报警和底纹报警控制,超出温度范围相应的继电器工作,继电器可以驱动相应的加热或制冷负载,上下限温度可通过按键设定功能。
2.主要单元电路(或功能程序)设计与分析
下面从软件电路方面分析电路各部分功能及其作用:
一 、首先介绍电路最核心的版块
单片机最小系统
AT89C51是一种4k字节闪烁可编程可擦除只读存储器的低电压 、高性能CMOS8位为微处理器存储器,俗称单片机。是一种高性能微处理器且为很多嵌入式控制系统提供了一种灵活性高且廉价的方案。  

2、晶振模块

晶振能把电能和机械能相互转换的晶体在共振的状体下工作,以提供稳定精确的单频震荡。为系统提供基本的时钟信号,使系统各部分保持同步,通常与锁相环电路配套使用。

  • 复位模块

复位模块在单片机上电启动的时候复位一次,当按键按下的时候系统再次复位,如果释放后再按下,系统还会复位。单片机rst引脚接收到2us以上的电平信号,只要保证电容的充放电时间大于2us,就可以实现复位,所以电容值是可以改变的。本电路中按下复位键以后液晶显示屏上会显示最初的设置。

二、其它重要模块

1、按键模块

按键1设置功能

设置功能的作用是可以调节上下限温度的限定值,比如温度下限为10摄氏度,按下设置键可以选中液晶显示屏中的下限温度,按下加减键可以做温度调整。

按键2加温

按下按键2可以增加上下限设定温度值。

按键3减温

按下按键3可以减小上下限设定温度值。


  • 蜂鸣器模块

当温度达到设定值上下限的时候,蜂鸣器模块电路接通,蜂鸣器模块开始工作发出刺耳的报警声响。

3、18B20模块

18b20模块是一个温度采集模块,能够实时采集并传输温度。具有体积小,硬件开销低,抗干扰能力强,精度高的特点。采用单总线的接口方式 与微处理器连接时仅需要一条口线即可实现微处理器与 DS18B20 的双向通讯。单总线具有经济性好,抗干扰能力强,适合于恶劣环境的现场温度测量,使用方便等优点。测量温度范围宽,测量精度高 DS18B20 的测量范围为 -55 ℃ ~+ 125 ℃ ; 在 -10~+ 85°C范围内,精度为 ± 0.5°C 。负压特性电源极性接反时,温度计不会因发热而烧毁,但不能正常工作。 DS18B20管脚排列:
  1. GND为电源地;
  2. DQ为数字信号输入/输出端;
  3. VDD为外接供电电源输入端(在寄生电源接线方式时接地)
  

三、上下限水温报警显示控制模块

1、蜂鸣器、小灯报警模块

Led灯报警模块中接入了两个继电器控制当温度超过所设置温度的上下限以后继电器工作电路接通,led灯变亮发出报警信息。

2、显示模块

采用Lm016L液晶显示屏,蓝屏带背光白字体。用于显示控制温度

  • 排阻

相同性质的电阻排列在一起,在电路中共同作用。

3.硬件组装与测试

硬件组装与调试,先看仿真结果:

1 正常初始化温度及运行状况

2上限温度报警

3下限温度报警

4 上下限温度调节

设计过程中遇到的问题:

在设计电路的过程中遇到了显示温度,而小灯和蜂鸣器在温度超过上下限之后小灯不亮,蜂鸣器不报警的情况,经查为电路接入电阻过高,导致元器件不能正常工作。

设计思路总流程图


四.实训小结

通过本次实训让自己认识到了那些方面不足,那些方面需要改进。使自己的动手能力和查阅资料独立思考的能力更加强大,再一个感谢指导老师的细心指导,让自己懂得了更多的知识。

五.附录

  1.主要电路图和主程序流程图。


4.程序设计与调试

  1. #include <reg51.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char               
  4. #define LCD1602 P0
  5. sbit SET=P3^1;                            //定义调整键
  6. sbit DEC=P3^2;                            //定义减少键
  7. sbit ADD=P3^3;                            //定义增加键
  8. sbit BUZZ=P3^6;                            //定义蜂鸣器
  9. sbit ALAM=P1^2;                                //定义灯光报警
  10. sbit ALAM1=P1^4;
  11. sbit DQ=P3^7;                             //定义DS18B20总线I/O      
  12. sbit RS = P2^7;
  13. sbit EN = P2^6;
  14. bit shanshuo_st;                            //闪烁间隔标志
  15. bit beep_st;                                     //蜂鸣器间隔标志
  16. uchar x=0;                                      //计数器

  17. uchar code tab1[]={"Now Tem:   .  C "};
  18. uchar code tab2[]={"TH:   C  TL:   C"};
  19. uint c;
  20. uchar Mode=0;                             //状态标志
  21. signed char TH=40;                  //上限报警温度,默认值为40
  22. signed char TL=10;                   //下限报警温度,默认值为10
  23. void Delay_DS18B20(int num)
  24. {
  25.   while(num--) ;
  26. }
  27. void delay(uint xms)
  28. {
  29.         uint x,y;
  30.         for(x=xms;x>0;x--)
  31.          for(y=110;y>0;y--);
  32. }
  33. void Init_DS18B20(void)
  34. {
  35.   unsigned char x=0;
  36.   DQ = 1;         //DQ复位
  37.   Delay_DS18B20(8);    //稍做延时
  38.   DQ = 0;         //单片机将DQ拉低
  39.   Delay_DS18B20(80);   //精确延时,大于480us
  40.   DQ = 1;         //拉高总线
  41.   Delay_DS18B20(14);
  42.   x = DQ;           //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
  43.   Delay_DS18B20(20);
  44. }
  45. unsigned char ReadOneChar(void)
  46. {
  47.   unsigned char i=0;
  48.   unsigned char dat = 0;
  49.   for (i=8;i>0;i--)
  50.   {
  51.     DQ = 0;   
  52.     dat>>=1;
  53.     DQ = 1;   
  54.     if(DQ)
  55.     dat|=0x80;
  56.     Delay_DS18B20(4);
  57.   }
  58.   return(dat);
  59. }
  60. void WriteOneChar(unsigned char dat)
  61. {
  62.   unsigned char i=0;
  63.   for (i=8; i>0; i--)
  64.   {
  65.     DQ = 0;
  66.     DQ = dat&0x01;
  67.     Delay_DS18B20(5);
  68.     DQ = 1;
  69.     dat>>=1;
  70.   }
  71. }
  72. unsigned int ReadTemperature(void)
  73. {
  74.   unsigned char a=0;
  75.   unsigned char b=0;
  76.   unsigned int t=0;
  77.   float tt=0;
  78.   Init_DS18B20();
  79.   WriteOneChar(0xCC);  //跳过读序号列号的操作
  80.   WriteOneChar(0x44);  //启动温度转换
  81.   Init_DS18B20();
  82.   WriteOneChar(0xCC);  //跳过读序号列号的操作
  83.   WriteOneChar(0xBE);  //读取温度寄存器
  84.   a=ReadOneChar();     //读低8位
  85.   b=ReadOneChar();    //读高8位
  86.   t=b;
  87.   t<<=8;
  88.   t=t|a;
  89.   tt=t*0.0625;
  90. t= tt*10+0.5;     //放大10倍输出并四舍五入
  91.   t= tt*10+0.5;
  92.   return(t);
  93. }
  94. void check_wendu(void)
  95. {
  96.         c=ReadTemperature()-5; //获取温度值并减去DS18B20的温漂误差
  97.         if(c>1200)
  98.         c=1200;
  99. }
  100. void write_1602com(uchar com)
  101. {
  102.         RS=0;//数据/指令选择置为指令
  103. //        rw=0; //读写选择置为写
  104.         LCD1602=com;//送入数据
  105.         delay(1);
  106.         EN=1;//拉高使能端,为制造有效的下降沿做准备
  107.         delay(1);
  108.         EN=0;//en由高变低,产生下降沿,液晶执行命令
  109. }
  110. void write_1602dat(uchar dat)
  111. {
  112.         RS=1;//数据/指令选择置为数据
  113.        // rw=0; //读写选择置为写
  114.         LCD1602=dat;//送入数据
  115.         delay(1);
  116.         EN=1; //en置高电平,为制造下降沿做准备
  117.         delay(1);
  118.         EN=0; //en由高变低,产生下降沿,液晶执行命令
  119. }


  120. void lcd_init()
  121. {
  122.         uchar a;
  123.         write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据
  124.         write_1602com(0x0c);//开显示不显示光标
  125.         write_1602com(0x06);//整屏不移动,光标自动右移
  126.         write_1602com(0x01);//清显示
  127.         write_1602com(0x80);//日历显示固定符号从第一行第1个位置之后开始显示
  128.         for(a=0;a<16;a++)
  129.         {
  130.                 write_1602dat(tab1[a]);//向液晶屏写日历显示的固定符号部分
  131.                 delay(3);
  132.         }
  133.         write_1602com(0x80+0x40);//时间显示固定符号写入位置,从第2个位置后开始显示
  134.         for(a=0;a<16;a++)
  135.         {
  136.                 write_1602dat(tab2[a]);//写显示时间固定符号,两个冒号
  137.                 delay(3);
  138.         }
  139. }
  140. void display()
  141. {
  142.         if(Mode==0)
  143.         {
  144.                 write_1602com(0x80+8);
  145.                 write_1602dat(c/1000+0x30);
  146.                 write_1602dat((c%1000)/100+0x30);
  147.                 write_1602dat(((c%1000)%100)/10+0x30);
  148.                 write_1602com(0x80+12);
  149.                 write_1602dat(((c%1000)%100)%10+0x30);
  150.                 write_1602com(0x80+13);
  151.                 write_1602dat(0xdf);
  152.                 write_1602com(0x80+0x40+3);
  153.                 write_1602dat(TH/10+0x30);
  154.                 write_1602dat(TH%10+0x30);
  155.                 write_1602dat(0xdf);
  156.                 write_1602com(0x80+0x40+12);
  157.                 write_1602dat(TL/10+0x30);
  158.                 write_1602dat(TL%10+0x30);
  159.                 write_1602dat(0xdf);                       
  160.         }                                                                 
  161. }
  162. void InitTimer(void)
  163. {
  164.         TMOD=0x1;
  165.         TH0=0x3c;
  166.         TL0=0xb0;     //50ms(晶振12M)
  167.         EA=1;      //全局中断开关
  168.         TR0=1;
  169.         ET0=1;      //开启定时器0
  170. }
  171. void KEY()
  172. {
  173.                         //功能键
  174.         if(SET==0)
  175.         {
  176.                 BUZZ=0;
  177.                 delay(10);
  178.                 if(SET==0)
  179.                 {
  180.                         Mode++;
  181.                         if(Mode==3)
  182.                         Mode=0;
  183.                         BUZZ=1;
  184.                 }
  185.                 while(SET==0)
  186.                 {
  187.                         if(Mode==0)
  188.                                 {
  189.                                       write_1602com(0x80+0x40+6);
  190.                                        write_1602com(0x0c);
  191.                                 }      
  192.                         else if(Mode==1)
  193.                                 {
  194.                                         write_1602com(0x80+0x40+4);
  195.                                         write_1602com(0x0f);
  196.                                 }      
  197.                         else
  198.                                 {
  199.                                         write_1602com(0x80+0x40+13);
  200.                                         write_1602com(0x0f);
  201.                                 }                                                      
  202.                 }
  203.         }
  204.         if(ADD==0&&Mode==1)
  205.         {
  206.                 BUZZ=0;
  207.                 delay(10);
  208.                 if(ADD==0)      
  209.                 {
  210.                         TH++;
  211.                         if(TH>=99)      
  212.                         TH=99;
  213.                         write_1602com(0x80+0x40+3);
  214.                         write_1602dat(TH/10+0x30);
  215.                         write_1602dat(TH%10+0x30);
  216.                         write_1602com(0x80+0x40+4);      
  217.                         BUZZ=1;
  218.                 }
  219.                 while(ADD==0);
  220.         }
  221.         if(DEC==0&&Mode==1)
  222.         {
  223.                 BUZZ=0;
  224.                 delay(10);
  225.                 if(DEC==0)
  226.                 {
  227.                         TH--;
  228.                         if(TH==TL)      
  229.                         TH=TL+1;
  230.                         write_1602com(0x80+0x40+3);
  231.                         write_1602dat(TH/10+0x30);
  232.                         write_1602dat(TH%10+0x30);
  233.                         write_1602com(0x80+0x40+4);      
  234.                         BUZZ=1;
  235.                 }
  236.                 while(DEC==0);
  237.         }
  238.         if(ADD==0&&Mode==2)
  239.         {
  240.                 BUZZ=0;
  241.                 delay(10);
  242.                 if(ADD==0)      
  243.                 {
  244.                         TL++;
  245.                         if(TL==TH)      
  246.                         TL=TH-1;
  247.                         write_1602com(0x80+0x40+12);
  248.                         write_1602dat(TL/10+0x30);
  249.                         write_1602dat(TL%10+0x30);
  250.                         write_1602com(0x80+0x40+13);      
  251.                         BUZZ=1;
  252.                 }
  253.                 while(ADD==0);
  254.          }
  255.         //减少
  256.         if(DEC==0&&Mode==2)
  257.         {
  258.                 BUZZ=0;
  259.                 delay(10);
  260.                 if(DEC==0)
  261.                 {
  262.                         TL--;
  263.                         if(TL<=0)      
  264.                         TL=0;
  265.                         write_1602com(0x80+0x40+12);
  266.                         write_1602dat(TL/10+0x30);
  267.                         write_1602dat(TL%10+0x30);
  268.                         write_1602com(0x80+0x40+13);      
  269.                         BUZZ=1;
  270.                 }
  271.                 while(DEC==0);               
  272.         }
  273. }
  274. void Alarm()
  275. {
  276.         if(x>=10){beep_st=~beep_st;x=0;}
  277.         if(Mode==0)
  278.         {
  279.                 if((c/10)>=TH)
  280.                 {
  281.                         ALAM=0;
  282.                         ALAM1=1;
  283.                         if(beep_st==1)
  284.                         BUZZ=0;
  285.                         else
  286.                         BUZZ=1;
  287.                 }
  288.                 else if((c/10)<TL)
  289.                 {
  290.                         ALAM1=0;
  291.                         ALAM=1;
  292.                         if(beep_st==1)
  293.                         BUZZ=0;
  294.                         else
  295.                         BUZZ=1;
  296.                 }
  297.                 else
  298.                 {
  299.                         BUZZ=1;
  300.                         ALAM=1;
  301.                         ALAM1=1;               
  302.                 }
  303.         }
  304.         else
  305.         {
  306.                 BUZZ=1;
  307.                 ALAM=1;
  308.                 ALAM1=1;
  309.         }
  310. }
  311. void main(void)
  312. {
  313.         uint z;
  314.         delay(1);
  315.         lcd_init();
  316.         delay(1);
  317.         InitTimer();   
  318.         for(z=0;z<100;z++)
  319.         {
  320.                 check_wendu();
  321.                 delay(1);      
  322.         }
  323.         while(1)
  324.         {
  325.                 display();
  326.                 KEY();
  327.                 Alarm();
  328.                 check_wendu();
  329.         }
  330. }
  331. void timer0(void) interrupt 1
  332. {
  333. TH0=0x3c;
  334. TL0=0xb0;
  335. x++;
  336. }
复制代码


word文档51hei下载地址(如有错误 请大家指出 一起学习):
电子综合设计实训报告.docx (254.24 KB, 下载次数: 91)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:448073 发表于 2019-9-3 09:47 | 只看该作者
程序 有错误啊 rw 没有 定义怎么搞
回复

使用道具 举报

板凳
ID:619509 发表于 2019-10-23 20:45 | 只看该作者
我想请问一下为什么我进行仿真的时候,超出水温上下限,灯没亮,蜂鸣器也没响。我修改了输入阻值,还是不行
回复

使用道具 举报

地板
ID:546381 发表于 2019-11-25 17:01 | 只看该作者
程序有问题,仿真也不行
回复

使用道具 举报

5#
ID:934838 发表于 2021-6-10 10:03 | 只看该作者
网页上的程序可以用 但是word里面的编译错误
回复

使用道具 举报

6#
ID:1035250 发表于 2022-6-17 22:27 来自手机 | 只看该作者
怎么都不报警,是哪里出错了
回复

使用道具 举报

7#
ID:191844 发表于 2023-1-11 21:58 | 只看该作者
本帖最后由 chengeiis 于 2023-1-12 19:54 编辑
ztlshr 发表于 2019-9-3 09:47
程序 有错误啊 rw 没有 定义怎么搞

sbit RS = P1^0;
sbit EN = P1^2;
sbit rw = P1^1;

加上就行了。试了可以正常运行!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表