基于PCF8591转换器实现烟雾报警,LCD1602液晶屏和数码管实现检测烟雾浓度,超过预设值蜂鸣器响,灯亮。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
仿真图
单片机源程序:
- #include <reg51.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
- #include <intrins.h>
- #include "I2C.h"
- #define u8 unsigned char
- #define u16 unsigned int
- #define uchar unsigned char
- #define uint unsigned int
- #define nops() do{_nop_();_nop_();_nop_();_nop_();_nop_();} while(0) //定义空指令
- #define READADDR 0x91 //读地址
- #define WRITEADDR 0x90 //写地址
- sbit SCL = P1^7; //I2C 时钟
- sbit SDA = P1^6; //I2C 数据
- uchar yanwu; //用于读取ADC数据
- uchar yushe_yanwu=100; //烟雾预设值
- //运行模式
- uchar Mode=0; // =1是设置烟雾阀值 =0是正常监控模式
- //管脚声明
- sbit Led_Reg =P2^2; //红灯
- sbit Buzzer =P1^5; //蜂鸣器
- sbit Fan =P3^3; //
- /********************************************************************
- * 名称 : delay_1ms()
- * 功能 : 延时1ms函数
- * 输入 : q
- * 输出 : 无
- ***********************************************************************/
- void delay_ms(uint q)
- {
- uint i,j;
- for(i=0;i<q;i++)
- for(j=0;j<110;j++);
- }
- /***********************************************************************************************************
- LCD1602相关函数
- 特殊接口说明
- RS:寄存器选择输入端
- RS = 1:指向数据寄存器 数据
- RS = 0:指向指令寄存器 命令
- RW:读写控制输入端
- RW = 0:写操作 RW = 1:读操作
- E:使能信号输入端
- 读操作时,高电平有效;
- 写操作时,下降沿有效;
- ***********************************************************************************************************/
- //LCD管脚声明 (RW引脚实物直接接地,因为本设计只用到液晶的写操作,RW引脚一直是低电平)
- sbit LCDRS = P2^6; //寄存器选择输入端,RS = 1 指向数据(读或写数据) RS = 0指向指令(读或写命令)
- sbit LCDEN = P2^7;
- sbit D0 = P0^0;
- sbit D1 = P0^1;
- sbit D2 = P0^2;
- sbit D3 = P0^3;
- sbit D4 = P0^4;
- sbit D5 = P0^5;
- sbit D6 = P0^6;
- sbit D7 = P0^7;
- //LCD延时
- void LCDdelay(uint z) //该延时大约100us(不精确,液晶操作的延时不要求很精确)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=10;y>0;y--);
- }
- 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;
- }
- //写命令
- void write_com(uchar com)
- {
- LCDRS=0; //RS = 0 ,指向数据寄存器,
- LCD_WriteData(com);
- // DAT=com;
- LCDdelay(5);
- LCDEN=1;
- LCDdelay(5);
- LCDEN=0;
- }
- //写数据
- void write_data(uchar date)
- {
- LCDRS=1;
- LCD_WriteData(date);
- // DAT=date;
- LCDdelay(5);
- LCDEN=1;
- LCDdelay(5);
- LCDEN=0;
- }
- /*------------------------------------------------
- 选择写入位置
- x = 0 表示写入第一行, y是列
- x = 1 表示写入第二行, y是列
- ------------------------------------------------*/
- void SelectPosition(unsigned char x,unsigned char y)
- {
- if (x == 0)
- {
- write_com(0x80 + y); //表示第一行
- }
- else
- {
- write_com(0xC0 + y); //表示第二行
- }
- }
- /*------------------------------------------------
- 写入字符串函数
- x是行,y是列,*s是写入的数据
- ------------------------------------------------*/
- void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
- {
- SelectPosition(x,y) ;
- while (*s)
- {
- write_data( *s);
- s++;
- }
- }
- //========================================================================
- // 函数: void LCD_Write_Char(u8 x,u8 y,u16 s,u8 l)
- // 应用: LCD_Write_Char(0,1,366,4) ;
- // 描述: 在第0行第一个字节位置显示366的后4位,显示结果为 0366
- // 参数: x:行,y:列,s:要显示的字,l:显示的位数
- // 返回: none.
- // 版本: VER1.0
- // 备注: 最大显示65535
- //========================================================================
- void LCD_Write_Char(u8 x,u8 y,u16 s,u8 l)
- {
- SelectPosition(x,y) ;
- if(l>=5)
- write_data(0x30+s/10000%10); //万位
- if(l>=4)
- write_data(0x30+s/1000%10); //千位
- if(l>=3)
- write_data(0x30+s/100%10); //百位
- if(l>=2)
- write_data(0x30+s/10%10); //十位
- if(l>=1)
- write_data(0x30+s%10); //个位
- }
复制代码
全部资料51hei下载地址:
烟雾报警器.zip
(142.14 KB, 下载次数: 184)
|