找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5121|回复: 6
收起左侧

基于PCF8591转换器实现烟雾报警器仿真和单片机程序

  [复制链接]
ID:410399 发表于 2018-10-30 08:10 | 显示全部楼层 |阅读模式
基于PCF8591转换器实现烟雾报警,LCD1602液晶屏和数码管实现检测烟雾浓度,超过预设值蜂鸣器响,灯亮。

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

仿真图

仿真图


单片机源程序:
  1. #include <reg51.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
  2. #include <intrins.h>
  3. #include "I2C.h"

  4. #define     u8                  unsigned char
  5. #define     u16                   unsigned int
  6. #define     uchar                  unsigned char
  7. #define     uint                   unsigned int

  8. #define nops()  do{_nop_();_nop_();_nop_();_nop_();_nop_();} while(0) //定义空指令


  9. #define  READADDR  0x91    //读地址
  10. #define  WRITEADDR  0x90    //写地址


  11. sbit SCL = P1^7;       //I2C  时钟
  12. sbit SDA = P1^6;       //I2C  数据

  13. uchar yanwu;                                                 //用于读取ADC数据
  14. uchar yushe_yanwu=100;                                //烟雾预设值

  15. //运行模式  
  16. uchar Mode=0;                                                 //  =1是设置烟雾阀值        =0是正常监控模式

  17. //管脚声明
  18. sbit Led_Reg                =P2^2;                                 //红灯
  19. sbit Buzzer                     =P1^5;                                 //蜂鸣器
  20. sbit Fan                     =P3^3;                                 //



  21. /********************************************************************
  22. * 名称 : delay_1ms()
  23. * 功能 : 延时1ms函数
  24. * 输入 : q
  25. * 输出 : 无
  26. ***********************************************************************/
  27. void delay_ms(uint q)
  28. {
  29.         uint i,j;
  30.         for(i=0;i<q;i++)
  31.                 for(j=0;j<110;j++);
  32. }
  33. /***********************************************************************************************************
  34. LCD1602相关函数
  35.         特殊接口说明
  36.                 RS:寄存器选择输入端
  37.                         RS = 1:指向数据寄存器                 数据
  38.                         RS = 0:指向指令寄存器                        命令

  39.                 RW:读写控制输入端
  40.                         RW = 0:写操作                 RW = 1:读操作

  41.                 E:使能信号输入端
  42.                         读操作时,高电平有效;
  43.                         写操作时,下降沿有效;
  44. ***********************************************************************************************************/

  45. //LCD管脚声明 (RW引脚实物直接接地,因为本设计只用到液晶的写操作,RW引脚一直是低电平)
  46. sbit LCDRS = P2^6;                                //寄存器选择输入端,RS = 1 指向数据(读或写数据)        RS = 0指向指令(读或写命令)
  47. sbit LCDEN = P2^7;
  48. sbit D0                 = P0^0;
  49. sbit D1                 = P0^1;
  50. sbit D2                 = P0^2;
  51. sbit D3                 = P0^3;
  52. sbit D4                 = P0^4;
  53. sbit D5                 = P0^5;
  54. sbit D6                 = P0^6;
  55. sbit D7                 = P0^7;



  56. //LCD延时
  57. void LCDdelay(uint z)                  //该延时大约100us(不精确,液晶操作的延时不要求很精确)
  58. {
  59.         uint x,y;
  60.         for(x=z;x>0;x--)
  61.                 for(y=10;y>0;y--);
  62. }

  63. void LCD_WriteData(u8 dat)         
  64. {
  65.         if(dat&0x01)D0=1;else D0=0;
  66.         if(dat&0x02)D1=1;else D1=0;
  67.         if(dat&0x04)D2=1;else D2=0;
  68.         if(dat&0x08)D3=1;else D3=0;
  69.         if(dat&0x10)D4=1;else D4=0;
  70.         if(dat&0x20)D5=1;else D5=0;
  71.         if(dat&0x40)D6=1;else D6=0;
  72.         if(dat&0x80)D7=1;else D7=0;
  73. }
  74. //写命令
  75. void write_com(uchar com)
  76. {
  77.         LCDRS=0;                                //RS = 0 ,指向数据寄存器,                          
  78.         LCD_WriteData(com);
  79. //  DAT=com;
  80.         LCDdelay(5);
  81.         LCDEN=1;
  82.         LCDdelay(5);
  83.         LCDEN=0;
  84. }
  85. //写数据
  86. void write_data(uchar date)
  87. {
  88.         LCDRS=1;
  89.         LCD_WriteData(date);
  90. //  DAT=date;
  91.         LCDdelay(5);
  92.         LCDEN=1;
  93.         LCDdelay(5);
  94.         LCDEN=0;
  95. }

  96. /*------------------------------------------------
  97.               选择写入位置
  98.         x = 0        表示写入第一行, y是列
  99.         x = 1          表示写入第二行, y是列
  100. ------------------------------------------------*/
  101. void SelectPosition(unsigned char x,unsigned char y)                 
  102. {     
  103.         if (x == 0)
  104.         {     
  105.                 write_com(0x80 + y);     //表示第一行
  106.         }
  107.         else
  108.         {      
  109.                 write_com(0xC0 + y);      //表示第二行
  110.         }        
  111. }
  112. /*------------------------------------------------
  113.               写入字符串函数
  114.                 x是行,y是列,*s是写入的数据
  115. ------------------------------------------------*/
  116. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  117. {     
  118.         SelectPosition(x,y) ;
  119.         while (*s)
  120.         {     
  121.                 write_data( *s);     
  122.                 s++;     
  123.         }
  124. }
  125. //========================================================================
  126. // 函数: void LCD_Write_Char(u8 x,u8 y,u16 s,u8 l)
  127. // 应用: LCD_Write_Char(0,1,366,4) ;
  128. // 描述: 在第0行第一个字节位置显示366的后4位,显示结果为 0366
  129. // 参数: x:行,y:列,s:要显示的字,l:显示的位数
  130. // 返回: none.
  131. // 版本: VER1.0
  132. // 备注: 最大显示65535
  133. //========================================================================
  134. void LCD_Write_Char(u8 x,u8 y,u16 s,u8 l)
  135. {     
  136.         SelectPosition(x,y) ;

  137.         if(l>=5)
  138.                 write_data(0x30+s/10000%10);        //万位
  139.         if(l>=4)
  140.                 write_data(0x30+s/1000%10);                //千位
  141.         if(l>=3)
  142.                 write_data(0x30+s/100%10);                //百位
  143.         if(l>=2)
  144.                 write_data(0x30+s/10%10);                        //十位
  145.         if(l>=1)
  146.                 write_data(0x30+s%10);                //个位

  147. }
复制代码

全部资料51hei下载地址:
烟雾报警器.zip (142.14 KB, 下载次数: 181)

评分

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

查看全部评分

回复

使用道具 举报

ID:269211 发表于 2018-10-31 09:28 | 显示全部楼层
请问您这个烟雾报警模块的型号是哪一个?
回复

使用道具 举报

ID:410399 发表于 2018-11-2 15:24 来自手机 | 显示全部楼层
chaoself 发表于 2018-10-31 09:28
请问您这个烟雾报警模块的型号是哪一个?

MQ-2烟雾传感器
回复

使用道具 举报

ID:509148 发表于 2019-4-11 13:45 | 显示全部楼层
void LCD_WriteData(u8 dat)          
{
        if(dat&0x01)D0=1;else D0=0;
        if(dat&0x02)D1=1;else D1=0;
        if(dat&0x04)D2=1;else D2=0;
        if(dat&0x08)D3=1;else D3=0;
        if(dat&0x10)D4=1;else D4=0;
        if(dat&0x20)D5=1;else D5=0;
        if(dat&0x40)D6=1;else D6=0;
        if(dat&0x80)D7=1;else D7=0;
}这段代码是什么意思?什么作用?
回复

使用道具 举报

ID:503551 发表于 2019-6-1 10:55 | 显示全部楼层
你好,请问你的程序是完全可以运行的吗,为什么我实际烧录的时候没有反应
回复

使用道具 举报

ID:768338 发表于 2020-6-14 17:00 | 显示全部楼层
你好,请问烟雾报警器压缩包里有代码吗?
回复

使用道具 举报

ID:786582 发表于 2021-3-14 22:31 | 显示全部楼层
chaoself 发表于 2018-10-31 09:28
请问您这个烟雾报警模块的型号是哪一个?

应该是MQ2烟雾传感器吧
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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