找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2005|回复: 1
收起左侧

基于STC89C52单片机的火灾报警器设计资料(Proteus仿真+源码)

[复制链接]
ID:318489 发表于 2022-9-23 15:52 | 显示全部楼层 |阅读模式
这是以前做小玩意的成品资料,包含了原理图,单片机程序,仿真图。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.gif

制作出来的实物图如下:
照片 416.jpg

电路原理图如下:
51hei.png

单片机源程序如下:
  1. //程序头函数
  2. #include <reg52.h>
  3. //显示函数
  4. #include <display.h>

  5. //宏定义
  6. #define uint unsigned int
  7. #define uchar unsigned char
  8. #include <intrins.h>
  9. #include "eeprom52.h"
  10. #define Data_ADC0809 P1

  11. //管脚声明
  12. sbit LED_wendu= P2^2;
  13. sbit LED_yanwu= P2^1;
  14. sbit baojing= P2^5;
  15. sbit DQ = P2^0;
  16. sbit fs=P3^4;
  17. //ADC0809
  18. sbit ST=P3^3;
  19. sbit EOC=P3^6;
  20. sbit OE=P3^2;
  21. //按键
  22. sbit Key1=P2^6;
  23. sbit Key2=P2^7;
  24. sbit Key3=P3^7;

  25. signed char w;                                     //温度值全局变量
  26. uint c;                                         //温度值全局变量
  27. bit bdata flag=0;
  28. //酒精含量变量
  29. uchar temp;
  30. uchar yushe_wendu;
  31. uchar yushe_yanwu;
  32. //按钮模式|  
  33. uchar Mode=0;

  34. //函数声明
  35. extern uchar ADC0809();
  36. extern void Key();

  37. /******************把数据保存到单片机内部eeprom中******************/
  38. void write_eeprom()
  39. {
  40.         SectorErase(0x2000);
  41.         byte_write(0x2000, yushe_wendu);
  42.         byte_write(0x2001, yushe_yanwu);
  43.         byte_write(0x2060, a_a);       
  44. }

  45. /******************把数据从单片机内部eeprom中读出来*****************/
  46. void read_eeprom()
  47. {
  48.         yushe_wendu   = byte_read(0x2000);
  49.         yushe_yanwu   = byte_read(0x2001);
  50.         a_a      = byte_read(0x2060);
  51. }

  52. /**************开机自检eeprom初始化*****************/
  53. void init_eeprom()
  54. {
  55.         read_eeprom();                //先读
  56.         if(a_a != 1)                //新的单片机初始单片机内问eeprom
  57.         {
  58.                 yushe_wendu=50;
  59.                 yushe_yanwu=45;
  60.                 a_a = 1;
  61.                 write_eeprom();           //保存数据
  62.         }       
  63. }

  64. void delay(uint z)
  65. {
  66.         uint i,j;
  67.         for(i=0;i<z;i++)
  68.         for(j=0;j<121;j++);
  69. }
  70. /*****延时子程序*****/
  71. void Delay_DS18B20(int num)
  72. {
  73.   while(num--) ;
  74. }
  75. /*****初始化DS18B20*****/
  76. void Init_DS18B20(void)
  77. {
  78.   unsigned char x=0;
  79.   DQ = 1;         //DQ复位
  80.   Delay_DS18B20(8);    //稍做延时
  81.   DQ = 0;         //单片机将DQ拉低
  82.   Delay_DS18B20(80);   //精确延时,大于480us
  83.   DQ = 1;         //拉高总线
  84.   Delay_DS18B20(14);
  85.   x = DQ;           //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
  86.   Delay_DS18B20(20);
  87. }
  88. /*****读一个字节*****/
  89. unsigned char ReadOneChar(void)
  90. {
  91.   unsigned char i=0;
  92.   unsigned char dat = 0;
  93.   for (i=8;i>0;i--)
  94.   {
  95.     DQ = 0;     // 给脉冲信号
  96.     dat>>=1;
  97.     DQ = 1;     // 给脉冲信号
  98.     if(DQ)
  99.     dat|=0x80;
  100.     Delay_DS18B20(4);
  101.   }
  102.   return(dat);
  103. }
  104. /*****写一个字节*****/
  105. void WriteOneChar(unsigned char dat)
  106. {
  107.   unsigned char i=0;
  108.   for (i=8; i>0; i--)
  109.   {
  110.     DQ = 0;
  111.     DQ = dat&0x01;
  112.     Delay_DS18B20(5);
  113.     DQ = 1;
  114.     dat>>=1;
  115.   }
  116. }
  117. /*****读取温度*****/
  118. unsigned int ReadTemperature(void)
  119. {
  120.   unsigned char a=0;
  121.   unsigned char b=0;
  122.   unsigned int t=0;
  123.   float tt=0;
  124.   Init_DS18B20();
  125.   WriteOneChar(0xCC);  //跳过读序号列号的操作
  126.   WriteOneChar(0x44);  //启动温度转换
  127.   Init_DS18B20();
  128.   WriteOneChar(0xCC);  //跳过读序号列号的操作
  129.   WriteOneChar(0xBE);  //读取温度寄存器
  130.   a=ReadOneChar();     //读低8位
  131.   b=ReadOneChar();    //读高8位
  132.   t=b;
  133.   t<<=8;
  134.   t=t|a;
  135.   tt=t*0.0625;
  136.   t= tt*10+0.5;     //放大10倍输出并四舍五入
  137.   return(t);
  138. }
  139. //=====================================================================================
  140. //=====================================================================================
  141. //=====================================================================================


  142. /*****读取温度*****/
  143. void check_wendu(void)
  144. {
  145.         c=ReadTemperature()-5;                          //获取温度值并减去DS18B20的温漂误差
  146.         if(c<0) c=0;
  147.         if(c>=999) c=999;
  148. }

  149. //ADC0809读取信息
  150. uchar ADC0809()
  151. {
  152.         uchar temp_=0x00;
  153.         //初始化高阻太

  154.         OE=0;
  155.         //转化初始化
  156.         ST=0;
  157.         //开始转换
  158.         ST=1;
  159.         ST=0;
  160.         //外部中断等待AD转换结束
  161.         while(EOC==0)
  162.         //读取转换的AD值
  163.         OE=1;
  164.         temp_=Data_ADC0809;
  165.         OE=0;
  166.         return temp_;
  167. }

  168. void Key()
  169. {
  170.         //模式选择
  171.         if(Key1==0)
  172.         {
  173.                 while(Key1==0);
  174.                 if(Mode>=3) Mode=0;
  175.                 else
  176.                 {
  177.                            write_com(0x38);//屏幕初始化
  178.                            write_com(0x0d);//打开显示 无光标 光标闪烁
  179.                            write_com(0x06);//当读或写一个字符是指针后一一位
  180.                         Mode++;
  181.                         switch(Mode)
  182.                         {
  183.                                 case 1:
  184.                                 {
  185.                                         write_com(0x80+7);//位置
  186.                                         break;
  187.                                 }
  188.                                 case 2:
  189.                                 {
  190.                                         write_com(0x80+15);//位置
  191.                                         break;
  192.                                 }
  193.                                 case 3:
  194.                                 {
  195.                                         write_com(0x38);//屏幕初始化
  196.                                         write_com(0x0c);//打开显示 无光标 无光标闪烁
  197.                                         Mode=0;
  198.                                         write_eeprom();                           //保存数据
  199.                                         break;
  200.                                 }
  201.                         }
  202.                 }
  203.         }
  204.         if(Key2==0&&Mode!=0)
  205.         {
  206.                 while(Key2==0);
  207.                 switch(Mode)
  208.                 {
  209.                         case 1:
  210.                         {
  211.                                 yushe_wendu++;
  212.                                 if(yushe_wendu>=99)
  213.                                 yushe_wendu=99;
  214.                                 write_com(0x80+6);
  215.                                 write_data(0x30+yushe_wendu/10);
  216.                                 write_data(0x30+yushe_wendu%10);
  217.                                 break;
  218.                         }
  219.                         case 2:
  220.                         {
  221.                                 yushe_yanwu++;
  222.                                 if(yushe_yanwu>=255)
  223.                                 yushe_yanwu=255;
  224.                                 write_com(0x80+13);
  225.                                 write_data(0x30+yushe_yanwu/100);
  226.                                 write_data(0x30+yushe_yanwu%100/10);
  227.                                 write_data(0x30+yushe_yanwu%10);
  228.                                 break;                               
  229.                         }
  230.                 }
  231.         }
  232.         if(Key3==0&&Mode!=0)
  233.         {
  234.                 while(Key3==0);
  235.                 switch(Mode)
  236.                 {
  237.                         case 1:
  238.                         {
  239.                                 yushe_wendu--;
  240.                                 if(yushe_wendu<=0)
  241.                                 yushe_wendu=0;
  242.                                 write_com(0x80+6);
  243.                                 write_data(0x30+yushe_wendu/10);
  244.                                 write_data(0x30+yushe_wendu%10);
  245.                                 break;
  246.                         }
  247.                         case 2:
  248.                         {
  249.                                 yushe_yanwu--;
  250.                                 if(yushe_yanwu<=0)
  251.                                 yushe_yanwu=0;
  252.                                 write_com(0x80+13);
  253.                                 write_data(0x30+yushe_yanwu/100);
  254.                                 write_data(0x30+yushe_yanwu%100/10);
  255.                                 write_data(0x30+yushe_yanwu%10);
  256.                                 break;                               
  257.                         }
  258.                 }
  259.         }
  260.         delay(200);
  261.         write_com(0x38);//屏幕初始化
  262.         write_com(0x0c);//打开显示 无光标 无光标闪烁
  263. }

  264. void main()
  265. {
  266.         check_wendu();
  267.         check_wendu();
  268.         Init1602();
  269.         init_eeprom();  //开始初始化保存的数据
  270.         while(1)
  271.         {
  272.                 temp=ADC0809();
  273.                 check_wendu();
  274.                 Key();

  275.                 if(Mode==0)
  276.                 {
  277.                         Display_1602(yushe_wendu,yushe_yanwu,c,temp);
  278.                         if(temp>=yushe_yanwu)
  279.                         {
  280.                                 LED_yanwu=0;
  281.                                 baojing=0;
  282.                                 fs=0;
  283.                         }
  284.                         else
  285.                         {
  286.                                 LED_yanwu=1;
  287.                         }
  288.                         if(c>=(yushe_wendu*10))
  289.                         {
  290.                                 baojing=0;
  291.                                 LED_wendu=0;
  292.                         }
  293.                         else
  294.                         {
  295.                                 LED_wendu=1;
  296.                         }
  297.                         if((temp<yushe_yanwu)&&(c<(yushe_wendu*10)))
  298.                         {
  299.                                 baojing=1;
  300.                                 fs=1;
  301.                         }
  302.                 }
  303.         }
  304. }       
复制代码

Keil代码与Proteus仿真下载: 仿真程序.7z (312.34 KB, 下载次数: 104)

评分

参与人数 1黑币 +50 收起 理由
admin + 50

查看全部评分

回复

使用道具 举报

ID:441043 发表于 2022-10-31 17:10 | 显示全部楼层
题主,protues用得是那个版本
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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