找回密码
 立即注册

QQ登录

只需一步,快速开始

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

小型家用燃气锅炉单片机控制系统的设计(Proteus仿真+程序)

  [复制链接]
跳转到指定楼层
楼主
这个是我以前做的设计,主要的是内容是小型家用燃气锅炉单片机控制系统的设计。主要的实现就是可以显示当前的温度,可以设置当前的温度,并且当实际的温度超过此时的温度是就会报警。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


1. 设计任务
2. 整体方案设计
3. 系统硬件电路设计
3.1 时钟电路
3.2 复位电路
3.3 温度检测电路设计
3.4水位检测模块
3.5显示电路设计
3.6报警电路设计
3.7 按键电路设计
3.8加水模块与加热模块
4. 系统程序设计
4.1 主程序流程图
4.2 温度显示程序流程图
5. 系统调试
5.1 Proteus软件仿真调试
6. 程序清单
7.小结


小型家用燃气锅炉单片机控制系统的设计

锅炉是一种热能转换设备,由锅和炉两大主体和保证其安全经济连续运行的附件,仪表附属设备,自控和保护系统组成。近年来采用以天然气,液化石油气为燃料的中小型燃气锅炉具有 高效、环境污染小,发热量大甚至无污染等特点,受到普遍欢迎。随着科技的发展以及各种客观条件的具备,生活采暖用燃气锅 炉的应用也必将得到进一步的发展与推广。随着燃料不断补给,燃料充足,城市燃气 管网逐步完善,燃气使用率逐步会提高。小型家用燃气锅炉的使用作为集 中供暖的一个很好补充或替代它必将被越来越多的人关注和选用成为趋势。目前市场上家用燃气锅炉为进口,价格高,售后服务不够完善,不利于燃气锅炉的推广使用,研制燃气锅炉的公司亦相对较少。因此研制开发小型家用燃气锅炉就具有现实的意义与客观的市场价值。本设计将结合小型家用燃气锅炉实际的需要,利用 MCS-51 系列单片机为核心器件组成温度控制系统,采用温度采集技术,通过运行和分析研究,以期正确认识和全面理解利用单片机实现温度采集技术在过程控制中的应用。
1. 设计任务

结合实际情况,基于AT89C51单片机设计一个小型家用燃气锅炉单片机控制系统。

该系统应满足的功能要求为:

(1) 可以检测水位的高低;

(2) 可以检测当前温度;

(3) 可以自动报警;

(4) 可以自动控制加水;

主要硬件设备:AT89C51、温度传感器DS18B20、LCD1602液晶显示器、继电器、74LSO4 、74LS244等。

2. 整体方案设计

采用 AT89S51 单片机、温度传感器 DS18B20 和液晶显示器 LCD1602 等核心部件。该方案采用液晶显示器来显示水位的上下限值、当前水位、预先设定的温度报警值和当前采集的温度值。用不锈钢管制作成的装置放于水位上下限。锅炉采用电加热的方式,水源由水泵供给,水温可以通过按键预置,由温度传感器检测水的温度并送给单片机, 然后单片机将实际水温送至 LCD1602液晶显示,同时单片机将采集到的实际水温与预置温度相比较, 若实际温度在预置温度范围内,就关闭电热丝;若实际水温不在预置温度范围内,就接通电热丝给锅炉加热,若超过预置温度极限,控制系统就会报警。由 74LS04和 74LS244组成的水位检测电路的四个探针来检测水位并将采集到的信息送给单片机,当水位高于最高水位时,就关闭水泵;当水位低于下限水位时,就打开水泵;当水位低于或高于极限水位时,就会报警。



图2-1 基于单片机的小型家用燃气锅炉控制系统原理图

本系统硬件主要由燃烧器、继电器、温度检测器、显示系统等几部分组成。各模块的主要功能如下:

  • 继电器功能接通燃烧器电源
  • 显示屏的作用是可以显示当前时刻的温度以及用户设定的温度;
  • 温度检测器的作用是可以检测当前的温度;
3. 系统硬件电路设计
3.1 时钟电路
AT89S51 的时钟可由内部产生也可以由外部产生。
在这个设计中只是用了内部产生。利用芯片内部振荡电路,在 XTAL1,XTAL2的引脚上外接定时元件,内部振荡器便能产生自激振荡,定时元件可以采用石英晶体和电容组成的并联谐振电路,它与单片机的接法的如图所示。晶体可以在 1.2MHz~12MHz 之间所选,电容可以在 20~60pF 之间所选,通常选择 30pF 左右,电容 C6,C7 的大小对振荡频率有微小的影响,可起频率微调作用。
图3-1 时钟电路结构图

3.2 复位电路
系统的复位电路是由 RC 电路组成,外加一个手动复位按钮。刚上电时或者触动 按钮后 C5 两端的电压为 0,这时 RST 为高电平,而其高电平保持时间是由 R 和 C 的时间常数决定,由公式τ=R*C可知,C 充电的时间常数 τ 等于 0.22ms,远远大于 2μs,即使 RST 高电平的时间保持 2μs 以上,确保了单片机正常复位。
图3-1 复位电路结构图
图3-3 时钟电路复位电路与单片机的连接图

3.3 温度检测电路设计

温度采集电路只有一个DS18B20温度传感器,它与单片机的接口比较简单,所示。只要给传感器5V的供电并把它的单总线接到单片机的P口就可以了。

图3-4 温度检测模块结构图

3.4水位检测模块
水位检测模块由芯片 74LS04和芯片74LS244及其附加电路组成。具体电路
如图所示。四个探针分别接在锅炉连通器从下到上的四个位置,当水位为 0
时,四个探针全被悬空,74LS04的四个输入端全被上拉电阻拉成高电平,经过
非门之后变为低电平,再经过缓冲芯片 74LS244输送给单片机并在液晶显示屏上显示。当水位上升到探针 1 处时,由于水的导电性,使 74LS04的 A1输入端为低电平,经过非门之后变为高电平, 再经过缓冲芯片 74LS244输送给单片机。此时,单片机认为水位为百分之二十五,并在液晶显示屏上显示。以此类推,单片机会依次检测到的水位是百分之五十,百分之七十五,百分之百。完成对水位的检测。
图3-5 温度检测模块结构图

3.5显示电路设计
本系统采用LCD1602作为显示模块,其主要功能是 显示水位的上下限值、当前水位、预先设定的温度报警值和当前采集的温度值。其中 VDD 接 5V 电源用于显示 LCD 液晶显示芯片的工作 ,VL 串接阻值 10K 欧姆的滑动变阻器是为了调节 LCD液晶显示芯片字符的亮度,当阻值越大时,LCD液晶显示越模糊。用滑动变阻器 能更好的调节LCD液晶字符显示的亮度,合适于锅炉的水位于水温的观察。 要想使显示器正常的工作需在连接P0口之前接一上拉电阻。
图3-6 显示模块结构图

3.6报警电路设计
本系统采用喇叭进行报警,该部分电路与单片机的接口如图所示。 电路由限流电阻R8、三极管Q1和喇叭组成。这个电路并不是一般的放大电路,三极管不是工作在放大状态,而是工作在饱和状态和截止状态。当基极为低电平时,晶体管处于饱和状态,饱和电压为UCES=0.3V,此时,喇叭鸣叫。当基极为高电平时,晶体管截止,相当于开路,输出为高电平,喇叭停止鸣叫。
图3-7 报警电路结构图

3.7 按键电路设计
本系统为符合实际要求,进入系统之前首先对温度报警值的设置。本系统有三个 按键分别为 K1,K2,K3.
如图所示。
  • K1 设置锅炉温度报警值的温度值增加按键。K1 每按下一次,温度报警值显 示加比上一次值增加一度。
  • K2 设置锅炉温度报警值的温度值减少按键。K1 每按下一次,温度报警值显 示比上一次值减少一度。
  • K3 温度报警值确定值。
图3-8 按键模块结构图
3.8加水模块与加热模块
小型开水锅炉控制系统执行机构通过继电器来控制加热电热丝和水泵来实
现水位和水温的自动控制,具体加水控制电路如图所示。
加热控制类似加水控制,不再赘述
图3-9 执行模块结构图
4. 系统程序设计
4.1 主程序流程图

本系统进入执行时先对锅炉水位进行与设定的水位上下限进行判断,然后按条件不同处理结果。当锅炉水位满足条件的时候再对锅炉的水温采样监控,并进行相应的处理


4.2 温度显示程序流程图
温度部分程序的主要功能是负责温度的实时显示、 读出并处理 DS18B20的测
量温度值,温度测量每 1S进行一次。

5. 系统调试
5.1 Proteus软件仿真调试
利用 protues软件进行仿真,能够实现预期目标,如图 ,系统能够正常
显示当前锅炉状态,在第一行显示当前温度,第二行显示当前水位。当按下图中
按键时, LCD1602进入温度设置界面,如图 ,按下按钮一次可实现设
置温度加一摄氏度。按下按钮一次可实现设置温度减一摄氏度。当再次按下
按键时,系统重新恢复如图界面。经调试,各项功能均能够很好的实现,包括温度的控制和水位的自动调节。


7.小结

在本次的实际过程中,我明白了一个完整的控制系统的设计过程。从明白我们的设计的目的开始,以目的为主要的标准来进行模块以及电路元器件的选择。根据自己所需要的东西以及想要达到的目标进行设计编程。用keil软件导出hex文件之后导入进单片机,没有错误的话就可以仿真了。我是采用protues进行仿真的,在仿真之前需要把程序导入到单片机当中,我是第一次完成这样的任务,中间也经历了很多的挫折,最主要的问题还是显示屏lcd1602的使用。但是在于同学的交流当中都一一解决,让我明白了自己与他人的差距,也更加深刻的体会到了合作的重要性。对今后的学习和生活有重要的意义。


6. 程序清单
  1. #include<reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit DQ=P3^3;//ds18b20 与单片机连接口
  5. sbit alarm=P3^6;// 蜂鸣器与单片机连接口
  6. sbit jidian1=P3^7;// 水位控制继电器与单片机连接口
  7. sbit jidianqi2 = P1^0;
  8. sbit RS=P2^0;
  9. sbit RW=P2^1;
  10. sbit EN=P2^2;
  11. sbit control = P1^6;
  12. sbit add_key = P1^7;
  13. sbit sub_key = P3^4;
  14. uchar control_flag = 0;
  15. uint wendu = 350;
  16. unsigned char code str1[]={"T:"};
  17. unsigned char str2[]={"C:"};
  18. unsigned char code str3[]={"W: "};
  19. uchar data disdata[5]={1,0,1,0,0};
  20. uint tvalue;// 温度值
  21. uchar tflag;// 温度正负标志
  22. unsigned char k=0;
  23. /*************************lcd1602 程序**************************/
  24. void delay1ms(unsigned int ms)//延时 1 毫秒(不够精确的)
  25. {unsigned int i,j;
  26. for(i=0;i<ms;i++)
  27. for(j=0;j<100;j++)
  28. ;
  29. }
  30. void wr_com(unsigned char com)//写指令
  31. {
  32. delay1ms(1);
  33. RS=0;
  34. RW=0;
  35. EN=0;
  36. P0=com;
  37. delay1ms(1);
  38. EN=1;
  39. delay1ms(1);
  40. EN=0;
  41. }
  42. void wr_dat(unsigned char dat)// 写数据
  43. {
  44. delay1ms(1);;
  45. RS=1;
  46. RW=0;
  47. EN=0;
  48. P0=dat;
  49. delay1ms(1);
  50. EN=1;
  51. delay1ms(1);
  52. EN=0;
  53. }
  54. /********** 延时函数 ,毫秒级 ***************/
  55. void delayms(unsigned int t)// 延时函数
  56. {
  57. unsigned int i, j;
  58. for( i = t; i > 0; i-- )
  59. {
  60. for( j = 110; j > 0; j-- );
  61. }
  62. }
  63. void lcd_init()// 初始化设置
  64. {delay1ms(15);
  65. wr_com(0x38);delay1ms(5);
  66. wr_com(0x08);delay1ms(5);
  67. wr_com(0x01);delay1ms(5);
  68. wr_com(0x06);delay1ms(5);
  69. wr_com(0x0c);delay1ms(5);
  70. }
  71. /******************* 读水位 ************************/
  72. void readlevel()
  73. {
  74. P2|=0xf0;
  75. if((P2&0XF0)==0X00)
  76. k= 0;
  77. else if((P2&0XF0)==0X10)
  78. k=25;
  79. else if((P2&0XF0)==0X30)
  80. k=50;
  81. else if((P2&0XF0)==0X70)
  82. k=75;
  83. else if((P2&0XF0)==0XF0)
  84. k=100;
  85. }
  86. /********************* 温度和水位报警 ***********************/
  87. void alarming() // 报警模块
  88. {
  89. uchar i;
  90. if(k==0||tvalue<0)// 温度低于零度或者水位为 0 时短报警
  91. {
  92. for(i=6;i>0;i--)
  93. {
  94. alarm=0;
  95. delay1ms(100);
  96. alarm=1;
  97. delay1ms(100);
  98. }
  99. }
  100. if(k==100||tvalue>95)// 温度高于 95 度或者水位为 100%时长报警
  101. {
  102. alarm=0;
  103. delay1ms(1000);
  104. alarm=1;
  105. }
  106. if(k==25)//水位过低报警
  107. {
  108. uchar j;
  109. for(j=3;j>0;j--)
  110. {
  111. alarm=0;
  112. delay1ms(300);
  113. alarm=1;
  114. delay1ms(300);
  115. }
  116. }
  117. if(k==75||k==50)// 不报警,延时 1 秒用于水位显示
  118. {
  119. delay1ms(1000);
  120. }
  121. }
  122. /*************** 继电器控制上水 ****************************/
  123. void jiashui() // 继电器控制上水
  124. {
  125. if(k<50)
  126. jidian1=0;
  127. if(k==100)
  128. jidian1=1;
  129. }
  130. /*************** 继电器控制加热 ****************************/
  131. void jiare() // 继电器控制加热
  132. {
  133. if ( wendu >= tvalue )
  134. {
  135. jidianqi2 = 0;
  136. }
  137. else
  138. {
  139. jidianqi2 = 1;
  140. }
  141. }
  142. /******************** 水位显示 *************************/
  143. void leveldisp() // 水位显示函数
  144. {
  145. disdata[0]=k/100+0x30;//百位数
  146. disdata[1]=k%100/10+0x30;//十位数
  147. disdata[2]=k%10+0x30;//个位数
  148. if(disdata[0]==0x30)
  149. {
  150. disdata[0]=0x20;// 如果百位为 0,不显示
  151. if(disdata[1]==0x30)
  152. {
  153. disdata[1]=0x20;// 如果百位为 0,十位为 0 也不显示
  154. }
  155. }
  156. wr_com(0xc4);
  157. wr_dat(disdata[0]);// 显示百位
  158. wr_com(0xc5);
  159. wr_dat(disdata[1]);// 显示十位
  160. wr_com(0xc6);
  161. wr_dat(disdata[2]);// 显示个位
  162. wr_com(0xc7);
  163. wr_dat(0x25);// 显示百分号
  164. }
  165. /*******************ds1820 程序*********************/
  166. void delay_18B20(unsigned int i)//延时 1 微秒
  167. {
  168. while(i--);
  169. }
  170. void ds1820rst()//ds1820 复位
  171. {
  172. unsigned char x=0;
  173. DQ = 1; //DQ 复位
  174. delay_18B20(4); //延时
  175. DQ = 0; //DQ 拉低
  176. delay_18B20(100); //精确延时大于 480us
  177. DQ = 1; // 拉高
  178. delay_18B20(40);
  179. }
  180. uchar ds1820rd()/*读数据*/
  181. {
  182. unsigned char i=0;
  183. unsigned char dat = 0;
  184. for (i=8;i>0;i--)
  185. {
  186. DQ = 0; //给脉冲信号
  187. dat>>=1;
  188. DQ = 1; //给脉冲信号
  189. if(DQ)
  190. dat|=0x80;
  191. delay_18B20(10);
  192. }
  193. return(dat);
  194. }
  195. void ds1820wr(uchar wdata)//写数据
  196. {unsigned char i=0;
  197. for (i=8; i>0; i--)
  198. {
  199. DQ = 0;
  200. DQ = wdata&0x01;
  201. delay_18B20(10);
  202. DQ = 1;
  203. wdata>>=1;
  204. }
  205. }
  206. read_temp()// 读取温度值并转换
  207. {
  208. uchar a,b;
  209. ds1820rst();
  210. ds1820wr(0xcc);//跳过读序列号
  211. ds1820wr(0x44);//启动温度转换
  212. ds1820rst();
  213. ds1820wr(0xcc);//跳过读序列号
  214. ds1820wr(0xbe);//读取温度
  215. a=ds1820rd();
  216. b=ds1820rd();
  217. tvalue=b;
  218. tvalue<<=8;
  219. tvalue=tvalue|a;
  220. if(tvalue<0x0fff)
  221. tflag=0;
  222. else
  223. {
  224. tvalue=~tvalue+1;
  225. tflag=1;
  226. }
  227. tvalue=tvalue*(0.625);// 温度值扩大 10 倍,精确到 1 位小数
  228. return(tvalue);
  229. }

  230. /************** 温度显示 ****************************/
  231. void ds1820disp() // 温度显示
  232. {
  233. uchar flagdat;
  234. disdata[0]=tvalue/1000+0x30;//百位数
  235. disdata[1]=tvalue%1000/100+0x30;//十位数
  236. disdata[2]=tvalue%100/10+0x30;//个位数
  237. disdata[3]=tvalue%10+0x30;//小数位
  238. if(tflag==0)
  239. flagdat=0x20;// 正温度不显示符号
  240. else
  241. flagdat=0x2d;// 负温度显示负号
  242. if(disdata[0]==0x30)
  243. {
  244. disdata[0]=0x20;// 如果百位为 0,不显示
  245. if(disdata[1]==0x30)
  246. {
  247. disdata[1]=0x20;// 如果百位为 0,十位为 0 也不显示
  248. }
  249. }
  250. wr_com(0x82);
  251. wr_dat(flagdat);// 显示符号位
  252. wr_com(0x83);
  253. wr_dat(disdata[0]);// 显示百位
  254. wr_com(0x84);
  255. wr_dat(disdata[1]);// 显示十位
  256. wr_com(0x85);
  257. wr_dat(disdata[2]);// 显示个位
  258. wr_com(0x86);
  259. wr_dat(0x2e);// 显示小数点
  260. wr_com(0x87);
  261. wr_dat(disdata[3]);// 显示小数位
  262. }
  263. void display(unsigned char *p)
  264. {
  265. while(*p!='\0')
  266. {
  267. wr_dat(*p);
  268. p++;
  269. delay1ms(1);
  270. }
  271. }
  272. void init_play()// 初始化显示
  273. {
  274. //              wr_com(0x01);
  275.               wr_com(0x80);
  276.               display(str1);
  277.               read_temp();// 读取温度
  278.               ds1820disp();//显示温度
  279.               wr_com(0xc0);
  280.               display(str3);
  281.               readlevel();// 读取水位
  282.               leveldisp();// 显示水位
  283. }
  284. void control_play( void )// 设定温度显示
  285. {
  286.               uchar flagdat;
  287.               //wr_com(0x01);
  288.               wr_com(0x89); //输入设定温度
  289.               display(str2);// 显示设定温度
  290.               disdata[0]=wendu/1000+0x30;//百位数
  291.               disdata[1]=wendu %1000/100+0x30;//十位数
  292.               disdata[2]=wendu%100/10+0x30;//个位数
  293.               disdata[3]=wendu%10+0x30;//小数位
  294.               if(tflag==0)
  295.               flagdat=0x20;// 正温度不显示符号
  296.               else
  297.               flagdat=0x2d;// 负温度显示负号
  298.               if(disdata[0]==0x30)
  299.               {
  300.               disdata[0]=0x20;// 如果百位为 0,不显示
  301.               if(disdata[1]==0x30)
  302.               {
  303.               disdata[1]=0x20;// 如果百位为 0,十位为 0 也不显示
  304.               }
  305.               }
  306.               wr_com(0x8B);
  307.               wr_dat(disdata[0]);// 显示百位
  308.               wr_com(0x8C);
  309.               wr_dat(disdata[1]);// 显示十位
  310.               wr_com(0x8D);
  311.               wr_dat(disdata[2]);// 显示个位
  312.               wr_com(0x8E);
  313.               wr_dat(0x2e);// 显示小数点
  314.               wr_com(0x8F);
  315.               wr_dat(disdata[3]);// 显示小数位

  316. }
  317. /************** 按键控制模块 *************/
  318. void key_scan( void ) // 按键控制模块
  319. {
  320.               static uchar i = 0;
  321.               if ( 0 == control )
  322.               {
  323.               delayms( 10 );
  324.               while ( 0 == control );
  325.               wr_com(0x01);
  326.               control_flag = 1;
  327.               i++;
  328.               if ( i >= 2 )
  329.               {
  330.               i = 0;
  331. ……………………

  332. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

全部资料51hei下载地址:
附件.zip (456.31 KB, 下载次数: 138)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:538291 发表于 2019-5-14 20:23 | 只看该作者
感谢感谢
回复

使用道具 举报

板凳
ID:748803 发表于 2020-5-11 09:09 | 只看该作者
感谢
回复

使用道具 举报

地板
ID:748868 发表于 2020-5-12 13:59 | 只看该作者
感谢楼主!
回复

使用道具 举报

5#
ID:748868 发表于 2020-5-14 11:28 | 只看该作者
老哥,你的报警程序没有调用,编译有警告。请问老哥proteus仿真整体图是不是不全啊?我联机调试有问题
回复

使用道具 举报

6#
ID:815578 发表于 2020-8-23 15:49 | 只看该作者
您好:我是做锅炉生产,我们有开发自控的需求,如有兴趣,请联系我
回复

使用道具 举报

7#
ID:863329 发表于 2020-12-21 12:54 | 只看该作者
LCD 不显示啊
回复

使用道具 举报

8#
ID:866311 发表于 2020-12-24 08:55 来自手机 | 只看该作者
DaDaoWanYan 发表于 2020-5-14 11:28
老哥,你的报警程序没有调用,编译有警告。请问老哥proteus仿真整体图是不是不全啊?我联机调试有问题

小哥,你的调试出来了吗?我这边有点弄不出来,可以看一下你的完整版的呗?
回复

使用道具 举报

9#
ID:866311 发表于 2020-12-25 10:25 来自手机 | 只看该作者
少加点糖 发表于 2020-5-11 09:09
感谢

能不能看一下您的调试成功的完整版
回复

使用道具 举报

10#
ID:1051028 发表于 2022-11-8 16:04 | 只看该作者
ygj1926 发表于 2020-12-25 10:25
能不能看一下您的调试成功的完整版

请问xd调整好了吗
回复

使用道具 举报

11#
ID:824664 发表于 2023-3-15 08:11 | 只看该作者
内容丰富实用,一定好好学学学习。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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