目录
实物以及proteus仿真展示
51单片机环境监测系统
系统设计方案
1.1设计任务与要求
1.设计任务
设计一个基于STC89C52的环境监测系统,能够实时监测温湿度、PM2.5浓度、天然气浓度、二氧化碳和甲醛等挥发性有机物浓度、光照强度等,并能够通过OLED屏幕显示监测数据。同时,当PM2.5浓度、天然气浓度、二氧化碳、甲醛等挥发性有机物的浓度超过所设定的阈值时,蜂鸣器便自动报警。
2.设计要求
- 温湿度监测:使用DHT11传感器进行温湿度监测,通过单片机读取芯片输出的数字信号,并进行转换和处理,将温湿度监测数据显示在OLED显示屏上。
- 天然气浓度监测:使用MQ-5传感器监测天然气浓度,并使用ADS1115模数转换将该传感器输出的模拟信号转换为数字信号,经过单片机的读取和处理,将PM2.5监测数据显示在OLED显示屏上。
- PM2.5浓度监测:使用GP2Y1014AU0F传感器监测PM2.5浓度,并使用ADS1115数模转换向单片机传递信号。最后将PM2.5监测数据显示在OLED显示屏上。
- 甲醛和二氧化碳浓度监测:使用SGP30传感器进行甲醛和二氧化碳浓度监测,通过单片机读取传感器输出的信号并进行转换和处理,最终将甲醛和二氧化碳浓度数据显示在OLED显示屏上。
- 光强监测:使用光敏传感器监测环境中的光照强度,输出模拟信号,经ADS1115的转换为数字信号交由单片机处理,最终将数据显示在OLED显示屏上。
- 报警功能:当天然气浓度,PM2.5、甲醛和二氧化碳浓度超过预设阈值时,蜂鸣器发出报警。
系统设计整体方案
1.2.1 设计思路:
设计思路如下:
- 硬件设计:
- 使用STC89C52单片机作为主控芯片。
- 连接温湿度传感器、PM2.5传感器、天然气传感器、甲醛传感器、二氧化碳传感器和光照传感器,通过相应的引脚与单片机进行通信。
- 连接OLED屏幕和蜂鸣器,通过相应的引脚与单片机进行控制。
- 软件设计:
- 初始化各个传感器和显示屏,设置阈值。
- 循环读取各个传感器的数据,并将数据实时显示在OLED屏幕上。
- 判断PM2.5浓度、天然气浓度、甲醛和二氧化碳浓度是否超过阈值,若超过则触发蜂鸣器报警。
- 系统调试和优化:
- 在实际环境中进行系统调试,确保各个传感器的数据准确可靠。
- 根据实际需求和使用情况,对系统进行优化,如增加数据存储、远程控制等功能。
1.2.2 系统框图:
图1-1系统整体设计框图
系统硬件电路设计
2.1 主控模块
单片机最小系统是保证单片机能够正常运行的最小硬件电路,其由时钟电路、复位电路和电源电路三个部分组成。其最小系统如图2-1所示。
2.1.1 时钟电路设计
时钟电路就是一个振荡器,给单片机提供一个节拍,就像人的心脏一样,只有提供了时钟信号,单片机内部的每一个部件才能协调工作。单片机内部有一个用于构成振荡器的高效益放大器,引脚XTAL1和XTAL2分别是放大器的输入端和输出端,只要外接一个晶振和两个电容即可构成自激振荡器,为单片机系统提供稳定的时钟。时钟电路如图2-2所示:
图2-2 时钟电路
2.1.2 复位电路设计
复位电路就是确定单片机的工作起始状态,完成单片机的启动过程。单片机接通电源时产生复位信号,完成单片机启动确定单片机起始工作状态。当单片机系统在运行中,受到外界环境干扰出现程序跑飞的时候,按下复位按钮内部的程序自动从头开始执行。一般有上电自动复位和外部按键手动复位,单片机在时钟电路工作以后,在RST端持续给出2个机器周期的高电平时就可以完成复位操作。本设计采用的是外部手动按键复位电路,需要接上上拉电阻来提高输出高电平的值。复位电路如图2-3所示:
图2-3 复位电路
2.2 显示模块设计
OLED,即有机发光二极管。OLED 由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。LCD都需要背光,而OLED不需要,因为它是自发光的。这样同样的显示OLED 效果要来得好一些。以目前的技术,OLED 的尺寸还难以大型化,但是分辨率确可以做到很高。OLED显示电路连接如图2-4所示:
2.3 温湿度模块设计
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该传感器具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。温湿度连接电路如图2-5所示:
2.4 天然气模块设计
当气体传感器所处环境中存在可燃气体时,可燃气体传感器的电导率随空气中可燃气体浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出信号。选用MQ-5传感器实现对气体的检测,具有灵敏度高、响应快、抗干扰能力强等优点,而且价格低廉,使用寿命长。传感器采集到数据,经过A/D转换后,再由单片机处理。A/D转换采用ADS1115转换器,ADS1115是一种高精度、超小型、低功耗的16位模数转换器,内部集成了一个可编程增益放大器,能将模拟信号转换为数字信号。该芯片可广泛应用于测量温度、压力,、湿度和流量等工业应用领域。天然气监测电路图如图2-6所示:
2.5 PM2.5粉尘模块设计
GP2Y1014AUOF是一种光学粉尘传感器这意味着它通过使用光学传感系统(例如光源)来感应灰尘,可以用于检测空气中的灰尘颗粒。此外,它还可用于测量空气质量。
GP2Y1014AU0F内部电路由一个简单的红外发光二极管和一个光电晶体管组成。这两个光学操作电子元件都放置在彼此对角的位置。这种灰尘传感器利用空气中灰尘的反射光来检测灰尘。与此同时,GP2Y1014AU0F还可以识别室内灰尘中的烟雾,例如香烟烟雾,并根据空气中的灰尘量产生一系列输出电压脉冲。经过A/D转换后,再由单片机处理。GP2Y1014AUOF与ADS1115电路连接如图2-7所示:
2.6 SGP30模块设计
SGP30传感器是一种用于检测室内空气质量的传感器。它基于独特的电化学技术,可以测量二氧化碳(CO2)和可挥发性有机化合物(VOC)的浓度。SGP30传感器的工作原理是利用化学反应来测量气体浓度。传感器内部有一个电化学电池,其中包含一层气敏材料。当空气中的气体进入传感器并与气敏材料接触时,气体分子会在材料表面发生化学反应。这些反应会引起电化学电池中的电流变化,从而使传感器能够测量气体浓度。SGP30传感器通过电化学反应来测量室内空气中CO2和VOC的浓度,具有高精度、快速响应、低功耗、小巧便携和低成本等优势。电路图如图2-8所示:
2.7光强监测模块设计
光敏传感器是一种能够感知光线强度并将其转化为电信号的器件。它基于光电效应原理工作,其中光线照射到传感器的光敏元件上,激发出电子,并产生电流。这个电流信号经过放大和处理后,可以用来测量光线的强度或者控制其他设备的操作。它具有高灵敏度、宽波长范围、快速响应时间、小尺寸和低功耗等优势,应用比较广泛。传感器采集到数据,经过A/D转换后,再由单片机处理,将数据显示在OLED屏上。光强监测连接电路如图2-9所示:
2.8报警模块设计
本设计使用有源蜂鸣器声音报警,当单片机的P2.4口输出低电平时,蜂鸣器便发出声音报警,当单片机的P2.4口输出高电平时,声音报警停止工作。其具有报警功能的数据模块分别为天然气浓度监测模块、PM2.5粉尘浓度监测模块和甲醛二氧化碳浓度监测模块,报警阈值由程序设置控制。报警模块电路图如图2-10所示:
2.9灯带模块
灯带在室内的作用是为室内环境提供照明和装饰效果。它可以增加室内的亮度,使空间更加明亮和舒适。此外,灯带还可以用作装饰,为房间增添美感和个性化。本项目中灯带的主控芯片为STM32,两个触摸按键分别控制亮度的调节和花样模式的切换。
灯带有多种模式,包括流水灯、呼吸灯、花样灯和亮度调节。流水灯模式是指灯带上的灯珠按照一定的顺序或频率依次亮起和熄灭,形成像流水一样的效果。呼吸灯模式是指灯带的亮度逐渐增加和减弱,仿佛在呼吸一样。花样灯模式是指灯带可以显示不同的颜色和图案,使房间更加丰富多彩。亮度调节模式是可以根据需要调节灯带的亮度,使其适应不同的环境和场景。实物图如图2-11所示:
3系统软件设计
3.1软件总体设计思路及其分析
室内环境监测系统的工作过程:在给系统上电后,单片机需要先初始化外部的OLED模块、ADS1115模块、蜂鸣器报警模块和各传感器模块。待初始化完成后,开始读取当前各传感器所测的数据,读取失败后会重新读取,否则会显示当前数据,当PM2.5粉尘模块、天然气模块和SGP30模块所测数据超过所设阈值时,蜂鸣器自动报警,各模块数据显示在OLED显示屏上。其流程图如图3-1所示:
3.2 OLED显示控制程序设计
OLED显示电路程序开始后,先初始化OLED的发送指令、设置模式、参数等内容,接着分别读取当前各传感器的值,将读取到的值显示到OLE屏上,OLED实时更新。
3.3 温湿度显示程序设计
初始化51单片机和DHT11传感器后,传感器采集到空气的温湿度,51单片机从DHT11接收数据并根据相应公式计算温度和湿度,最后将数据显示在OLED屏上,数据实时更新。
流程图如图3-3所示:
3.4粉尘、天然气、光敏传感器显示程序设计
ADS1115是具有16位的分辨率,可以实现高精度的模数转换器,内部集成了一个可编程增益放大器,能够准确地测量参数的变化。我们首先配置了51单片机的IIC总线,并将其连接到ADS1115芯片,然后初始化ADS1115,设置增益和采样率等参数。通过IIC总线依次发送读取粉尘传感器、光敏传感器和MQ-5传感器数据的命令给ADS1115芯片。ADS1115通过IIC总线依次读取每个传感器的数据,并将其存储在寄存器中。接着将各个传感器的数据从寄存器读出,并进行处理和存储,最后将数据显示在OLED屏上。
流程图如图3-4所示:
3.5 二氧化碳和TVOC浓度显示设计
我们采用SGP30芯片来监测空气中的CO2与甲醛等挥发性有机化合物的浓度,我们首先初始化51单片机和SGP30传感器,然后发送IIC起始信号同时发送SGP30的地址到单片机,单片机接收SGP30传感器数据并返回CO2和TVOC的浓度在OLED显示屏上显示。程序控制流程图如图3-5所示:
3.6 蜂鸣器报警程序设计
本设计中当PM2.5粉尘浓度、天然气浓度,二氧化碳和甲醛等挥发性有机物的浓度超过程序所设定的正常阈值时,蜂鸣器便会自动报警。首先初始化各传感器,51单片机与各传感器取得联系并设置阈值,判断传感器监测到的数据是否超过阈值,如果超过,则触发蜂鸣器报警,并将数据显示在OLED屏上,反之,将数据显示在OLED屏上。
程序控制流程图如图3-5所示:
4 调试与分析
4.1 软件调试
采用Keil C51软件对所编写的C51源程序进行调试分析。需要将代码在keil中进行一次编译。在对程序进行编译之后,系统提示有0个错误和0个警告,编译成功。编译结果如图4-1所示。
图4-1 程序的调试
4.2 电路原理与仿真
本设计的主要构成部分是51单片机、OLED显示屏、有源蜂鸣器、GP2Y1014AU0F传感器、MQ-5传感器、SGP30传感器、ADS1115模数转换器、光敏传感器、DHT11传感器等。电路搭建过程中参考各芯片数据手册及所画原理图正确连接各引脚。程序编写过程中,参考网络资料编写修改。原理图如图4-2所示。
仿真过程中,由于Proteus元件库中没有PM2.5传感器,MQ-5传感器和光敏传感器,故我们使用三个滑动变阻器分别代替它们。因Proteus没有SGP30传感器也无法使用滑动变阻器代替,所有我们只仿真了温湿度,PM2.5浓度,天然气浓度以及光照强度。通过改变DHT11的值和各滑动变阻器的值可以看到OLED屏显示不同的数据。
系统仿真图如图4-3所示:
4.3整机联调
- 硬件搭建:
- 连接STC89C52微控制器、OLED屏幕、DHT11传感器、PM2.5传感器、天然气传感器、SGP30传感器、光敏传感器和蜂鸣器。
- 根据传感器的接口要求,将它们与微控制器的引脚连接。
- 连接OLED屏幕的I2C接口到相应的引脚。
- 编写代码:
- 使用C语言编写代码,利用STC89C52的开发工具进行编程。
- 初始化各个传感器,并对需要报警的传感器模块设置相应的阈值。
- 通过串口通信或I2C总线读取传感器数据。
- 根据读取的数据,判断是否超过阈值,并控制蜂鸣器报警。
- 将监测数据通过串口或I2C总线发送到OLED屏幕上进行显示。
- 调试和测试:
- 烧录代码到STC89C52微控制器中。
- 运行程序,监测传感器数据并显示在OLED屏幕上。
- 通过调整阈值,测试蜂鸣器是否能够正确地报警。
- 检查传感器数据的准确性和稳定性,确保系统正常工作。
- 整机联调:
- 将所有模块连接在一起,确保它们能够正常协同工作。
- 测试各个传感器的数据是否能够准确地传输到微控制器,并在OLED屏幕上显示。
- 测试蜂鸣器是否能够根据阈值正确地报警。
- 检查整个系统的稳定性和可靠性。
实物图如图4-4所示:
4.3报警测试
-
PM2.5粉尘模块报警测试:
该传感器利用空气中灰尘的反射光来检测灰尘,这里我们用螺丝刀模拟灰尘进行PM2.5粉尘报警测试,当空气中灰尘浓度较小时,蜂鸣器不报警,当监测到空气中灰尘浓度较高时,蜂鸣器自动报警,OLED显示屏显示当前浓度。
如图4-5所示:
-
天然气模块报警测试:
当气体传感器所处环境中存在可燃气体时,可燃气体传感器的电导率随空气中可燃气体浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出信号。这里我们用酒精代替天然气进行报警测试。当监测到空气中的酒精浓度正常时,蜂鸣器不报警,当酒精浓度超过程序所设定的正常阈值时,蜂鸣器报警,浓度显示在OLED屏上。
天然气浓度报警检测如图4-6所示:
-
二氧化碳和TVOC模块报警测试:
SGP30传感器的工作原理是利用化学反应来测量气体浓度。传感器内部有一个电化学电池,其中包含一层气敏材料。当空气中的气体进入传感器并与气敏材料接触时,气体分子会在材料表面发生化学反应。这些反应会引起电化学电池中的电流变化,从而使传感器能够测量气体浓度。由于条件的限制,我们只检测二氧化碳浓度报警。我们通过向传感器哈气检测报警,当不哈气时,空气中的二氧化碳浓度处在正常值,蜂鸣器不报警;当向传感器哈气时,二氧化碳浓度较高,传感器监测到高浓度的二氧化碳浓度,超过系统所设置的阈值,蜂鸣器报警,所测数据显示在OLED屏上。
二氧化碳浓度报警检测如图4-7所示:
5 总结与展望
在这个项目中,我使用了多个传感器来检测不同的参数,包括温湿度、CO2浓度和TVOC浓度、PM2.5浓度、天然气浓度以及光照强度等。通过收集和分析这些数据,可以更好地了解室内环境的情况,并及时采取相应的措施来保障人们的健康和安全。
在这个项目中,我使用了ADC转换芯片ADS1115来处理传感器产生的模拟信号。在使用ADC的过程中,我遇到了很多问题,例如时序问题、转换通道选择、PGA增益选择、转换速率等。这些问题可能会令我感到困惑和沮丧,但是通过耐心地研究和实践,我成功地克服了这些难题,并最终完成了这个项目。
除此之外,在整个项目的设计和实现过程中,我锻炼了自己的团队协作能力和沟通能力。我需要与其他团队成员一起制定项目计划、分配任务、协调进度,以及及时向他们汇报自己的工作进展和遇到的问题,以便及时解决。这些能力可以让我更好地适应未来的学习和职业发展。
通过这个项目,我不仅学习了很多有用的技术知识,还提高了整体项目管理和执行能力。这是非常有价值的经验,可以让我在今后的学习和工作中更好地发挥自己的才华,为社会做出更大的贡献。
此外,这个项目还让我了解了如何将多个传感器的数据进行处理和融合,以实现对室内环境的全面监测。这需要我具备一定的软件编程技能,例如使用C语言进行程序设计和调试,掌握数据结构和算法等方面的知识。
在这个项目中,我还需要具备一定的电路设计和焊接技能,例如使用proteus进行仿真,以及掌握基本的焊接技巧和质量检测方法等。这些技能可以帮助我更好地完成硬件设计和制造,保证项目的稳定性和可靠性。
总之,通过这个项目,我不仅学习到了技术知识,还提高了整体项目管理和执行能力。这是非常有价值的经验,可以让我更好地适应未来的学习和职业发展。在今后的学习和工作中,我会更加自信和有能力面对各种挑战,并取得更加优异的成绩。
希望我在今后的学习和工作中,能够继续努力,不断提高自己的技术水平和综合素质,为社会做出更大的贡献。
元器件清单:
元器件种类 | 个数 |
51单片机最小系统板 | x1 |
STC89C52单片机 | x1 |
STM32F103单片机 | x1 |
SGP30传感器 | x1 |
ADS1115 小型16位 4通道ADC转换芯片 | x1 |
有源蜂鸣器 | x1 |
GP2Y1014AUVF传感器 | x1 |
MQ-5传感器 | x1 |
0.96寸OLED屏幕 | x2 |
WS2812幻彩LED灯带 | x1 |
DHT11传感器 | x1 |
光敏电阻传感器 | x1 |
触摸按键 | x3 |
150ohm的电阻 | x1 |
220uF的电容 | x1 |
杜邦线 | n |
源代码:(51单片机ROM已爆代码)
附录2:
//ADS1115.h
#ifndef ADS1115_H
#define ADS1115_H
/*******************************************************************************
ADDR--GND
SLAVE ADDRESS 0X90
*******************************************************************************/
/*****************Pointer Register*************/
#define REG_Conversion 0x00
#define REG_config 0x01
#define REG_L_thresh 0x02
#define REG_H_thresh 0x03
/*****************Conversion Register**********/
//???16???
/*****************Config Register**********/
#define OS 1 //Operational status or single-shot conversion start
#define MUX 0x04 //[2:0]Input multiplexer configuration
#define MUX2 0x06 //[2:0]Input multiplexer configuration
#define MUX1 0x05 //[2:0]Input multiplexer configuration
#define PGA 0x02 //Programmable gain amplifier configuration
#define PGA1 0x02 //Programmable gain amplifier configuration
#define PGA2 0x00 //Programmable gain amplifier configuration
#define MODE 0x00 //Device operating mode
#define DR 0x04//Data rate
#define COMP_MODE 0 // Comparator mode
#define COMP_POL 0 //Comparator polarity
#define COMP_LAT 0 //Latching comparator
#define COMP_QUE 0x3 //Comparator queue and disable
#define config_MSB (OS << 7)|(MUX << 4)|(PGA << 1)|(MODE)//0xC2
#define config_MSB1 (OS << 7)|(MUX1 << 4)|(PGA1 << 1)|(MODE)
#define config_MSB2 (OS << 7)|(MUX2 << 4)|(PGA2 << 1)|(MODE)
#define config_LSB (DR << 5)|(COMP_MODE << 4)|(COMP_POL << 3)|(COMP_LAT << 2)|(COMP_QUE)//0x83
/*****************Lo_thresh Register**********/
#define Lo_thresh 0x8000 // Low threshold value
#define Hi_thresh 0x7FFF // High threshold value
void ADS1115_Write(unsigned char Reg , unsigned char reg_MSB , unsigned char reg_LSB);
unsigned int ADS1115_ReadAD(void);
void ADS115_config(void);
void ADS115_config1(void);
void ADS115_config2(void);
#endif
//ADS1115.c
#include <REGX52.H>
#include "ADC1115.h"
#include "Delay.h"
#include "I2C.h"
void ADS1115_Write(unsigned char Reg , unsigned char reg_MSB , unsigned char reg_LSB)
{
I2C_Start();
I2C_SendByte(0x90+0);//0x90鍦板潃+0鍐欎綅
I2C_ReceiveAck();
I2C_SendByte(Reg);
I2C_ReceiveAck();
I2C_SendByte(reg_MSB);
I2C_ReceiveAck();
I2C_SendByte(reg_LSB);
I2C_ReceiveAck();
I2C_Stop();
}
unsigned int ADS1115_ReadAD()
{
unsigned int Data;
I2C_Start();
I2C_SendByte(0x90+0);//0x90鍦板潃+0鍐欎綅
I2C_ReceiveAck();
I2C_SendByte(REG_Conversion);
I2C_ReceiveAck();
I2C_Stop();
I2C_Start();
I2C_SendByte(0x90+1);//0x90鍦板潃+1璇讳綅
I2C_ReceiveAck();
Data = I2C_ReceiveByte();
Data =(Data<<8)&0xff00;//鍓?浣?
I2C_SendByte(0);
Data+=I2C_ReceiveByte();//鍚?浣?
I2C_SendByte(1);
I2C_Stop();
return Data;
}
void ADS115_config()
{
ADS1115_Write(REG_config, config_MSB ,config_LSB);
}
void ADS115_config1()
{
ADS1115_Write(REG_config, config_MSB1 ,config_LSB);
}
void ADS115_config2()
{
ADS1115_Write(REG_config, config_MSB2 ,config_LSB);
}
//Delay.h
#ifndef __DELAY_H__
#define __DELAY_H__
void Delay(unsigned int xms);
void Delay300us();
#endif
// Delay.c
#include <intrins.h>
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void Delay300us() //@11.0592MHz
{
unsigned char i;
_nop_();
i = 135;
while (--i);
}
//DHT11.h
#ifndef __DHT11_h__
#define __DHT11_h__
extern unsigned char dht11Data[5];
extern unsigned char wendu[6];
extern unsigned char shidu[4];
void obtainDht11Data();
void DHT11_Init();
#endif
//DHT11.c
#include <REGX52.H>
#include <intrins.h>
#include "Delay.h"
sbit dht11 = P1^2;
unsigned char dht11Data[5];
unsigned char wendu[6];
unsigned char shidu[4];
void Delay40us() //@11.0592MHz
{
unsigned char i;
_nop_();
i = 15;
while (--i);
}
void Delay30ms() //@11.0592MHz
{
unsigned char i, j;
i = 54;
j = 199;
do
{
while (--j);
} while (--i);
}
void dht11Start()
{
dht11 = 1;
dht11 = 0;
Delay30ms();
dht11 = 1;
while(dht11);
while(!dht11);
while(dht11);
}
void obtainDht11Data()
{
unsigned char i,j;
char tmp;
char flag;
dht11Start();
for (i = 0; i < 5; i++){
for (j = 0; j < 8; j++){
while(!dht11);
Delay40us();
if(dht11 == 1){
while(dht11);
flag = 1;
}else{
flag = 0;
}
tmp = tmp << 1;
tmp = tmp | flag;
}
dht11Data[i] = tmp;
}
}
void DHT11_Init()
{
obtainDht11Data();
shidu[0]='0'+(dht11Data[0]/10);
shidu[1]='0'+(dht11Data[0]%10);
wendu[0]='0'+(dht11Data[2]/10);
wendu[1]='0'+(dht11Data[2]%10);
wendu[2]='.';
wendu[3]='0'+(dht11Data[3]%10);
wendu[4]='C';
shidu[2]='%';
wendu[5]='\0';
shidu[3]='\0';
}
//guangzhao.h
#ifndef __guangzhao_h__
#define __guangzhao_h__
void guangzhao_Init();
#endif
//guangzhao.c
#include "ADC1115.h"
unsigned char str[2];
void guangzhao_Init()
{
float v;
unsigned int Data;
ADS115_config2();
Data=ADS1115_ReadAD();
if(Data>0x8000)
v=((float)(0xffff-Data)/32768.0)*6.144;
else
v=((float)Data/32768.0)*6.144;
if(v>=4.3)
{
str[0]='L';
}
else if(v<4.3 && v>3.5)
{
str[0]='M';
}
else if(v<=3.5)
{
str[0]='H';
}
str[1]='\0';
}
//I2C.h
#ifndef __I2C_H__
#define __I2C_H__
void I2C_Start(void);
void I2C_Stop(void);
void I2C_SendByte(unsigned char Byte);
unsigned char I2C_ReceiveByte(void);
void I2C_SendAck(unsigned char AckBit);
unsigned char I2C_ReceiveAck(void);
#endif
// I2C.c
#include <REGX52.H>
sbit I2C_SCL=P2^6;
sbit I2C_SDA=P2^7;
void I2C_Start(void)
{
I2C_SDA=1;
I2C_SCL=1;
I2C_SDA=0;
I2C_SCL=0;
}
void I2C_Stop(void)
{
I2C_SDA=0;
I2C_SCL=1;
I2C_SDA=1;
}
void I2C_SendByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
I2C_SDA=Byte&(0x80>>i);
I2C_SCL=1;
I2C_SCL=0;
}
}
unsigned char I2C_ReceiveByte(void)
{
unsigned char i,Byte=0x00;
I2C_SDA=1;
for(i=0;i<8;i++)
{
I2C_SCL=1;
if(I2C_SDA){Byte|=(0x80>>i);}
I2C_SCL=0;
}
return Byte;
}
void I2C_SendAck(unsigned char AckBit)
{
I2C_SDA=AckBit;
I2C_SCL=1;
I2C_SCL=0;
}
unsigned char I2C_ReceiveAck(void)
{
unsigned char AckBit;
I2C_SDA=1;
I2C_SCL=1;
AckBit=I2C_SDA;
I2C_SCL=0;
return AckBit;
}
//IIC.h
#ifndef __I2C_H__
#define __I2C_H__
#define SGP30_read 0xb1
#define SGP30_write 0xb0
#define ACK 0
#define NACK 1
void I2CStart(void);
void I2CStop(void);
unsigned char I2C_Write_Byte(unsigned char Write_Byte);
unsigned char I2C_Read_Byte(unsigned char AckValue);
void SGP30_Init(void);
void SGP30_Write(unsigned char a, unsigned char b);
unsigned long SGP30_Read(void);
#endif
// IIC.c
#include <REGX52.H>
#include "SGP30.H"
#include "delay.h"
sbit SCL=P2^2;
sbit SDA=P2^3;
void I2CDelay (unsigned char t)
{
while(t--);
}
void I2CStart(void)
{
SDA = 1;
SCL = 1;
I2CDelay(50);
SDA = 0;
I2CDelay(50);
SCL = 0;
I2CDelay(50);
}
void I2CStop(void)
{
SDA = 0;
SCL = 0;
I2CDelay(50);
SCL = 1;
I2CDelay(50);
SDA = 1;
I2CDelay(50);
}
unsigned char I2C_Write_Byte(unsigned char Write_Byte) //Sendbyte
{
unsigned char i;
SCL=0;
I2CDelay(10);
for(i=0; i<8; i++)
{
if(Write_Byte&0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
I2CDelay(5);
SCL=1;
I2CDelay(5);
SCL=0;
I2CDelay(5);
Write_Byte <<= 1;
}
I2CDelay(1);
SDA = 1;
I2CDelay(40);
SCL = 1;
I2CDelay(40);
if(SDA==1)
{
I2CDelay(40);
SCL=0;
return NACK;
}
else
{
I2CDelay(40);
SCL=0;
return ACK;
}
}
unsigned char I2C_Read_Byte(unsigned char AckValue)
{
unsigned char i,RDByte=0;
SCL=0;
I2CDelay(40);
SDA = 1;
for (i=0; i<8; i++)
{
SCL = 1;
RDByte <<= 1;
if(SDA==1)
{
RDByte |= 0x01;
}
else
{
RDByte &= 0xfe;
}
I2CDelay(10);
SCL = 0;
I2CDelay(60);
}
SDA = AckValue;
I2CDelay(30);
SCL = 1;
I2CDelay(50);
SCL = 0;
I2CDelay(150);
return RDByte;
}
void SGP30_Init(void)
{
SGP30_Write(0x20,0x03);
// SGP30_ad_write(0x20,0x61);
// SGP30_ad_write(0x01,0x00);
}
void SGP30_Write(unsigned char a, unsigned char b)
{
I2CStart();
I2C_Write_Byte(SGP30_write);
I2C_Write_Byte(a);
I2C_Write_Byte(b);
I2CStop();
Delay(100);
}
unsigned long SGP30_Read(void)
{
unsigned long dat;
int crc;
I2CStart();
I2C_Write_Byte(SGP30_read);
dat = I2C_Read_Byte(ACK);
dat <<= 8;
dat += I2C_Read_Byte(ACK);
crc = I2C_Read_Byte(ACK);
dat <<= 8;
dat += I2C_Read_Byte(ACK);
dat <<= 8;
dat += I2C_Read_Byte(NACK);
I2CStop();
return(dat);
}
//main.c
#include <REGX52.H>
#include "oled.h"
#include "Delay.h"
#include "DHT11.h"
#include "Timer0.h"
#include "PM2.h"
#include "MQ5.h"
#include "ADC1115.h"
#include "guangzhao.h"
#include "SGP_Init.h"
extern unsigned int CO2Data,TVOCData;
extern float PM,MQ,Data;
unsigned char i;
extern unsigned char str[2];
sbit BEEP = P2^4;
void oled_geren_Init()
{
OLED_ShowCHinese(0,0,0);//黄
OLED_ShowCHinese(18,0,1);//淮
OLED_ShowCHinese(36,0,2);//学
OLED_ShowCHinese(54,0,3);//院
OLED_ShowCHinese(0,2,4);//电
OLED_ShowCHinese(18,2,5);//子
OLED_ShowCHinese(36,2,6);//信
OLED_ShowCHinese(54,2,7);//息
OLED_ShowCHinese(72,2,8);//学
OLED_ShowCHinese(90,2,9);//院
OLED_ShowCHinese(0,4,10);//通
OLED_ShowCHinese(18,4,11);//信
OLED_ShowCHinese(36,4,12);//工
OLED_ShowCHinese(54,4,13);//程
OLED_ShowCHinese(72,4,14);//专
OLED_ShowCHinese(90,4,15);//业
OLED_ShowCHinese(0,6,16);//刘
OLED_ShowCHinese(18,6,17);//泽
OLED_ShowCHinese(36,6,18);//鑫
}
void main()
{ OLED_Init();
oled_geren_Init();
SGP_Init();
DHT11_Init();
Timer0Init();
SGP_Init();
OLED_Clear();
Delay(1000);
while(1)
{
if(CO2Data>=1000 || TVOCData>=400 ||MQ>=200 ||PM>=500)
{
BEEP=0;
Delay(500);
BEEP=1;
Delay(500);
}
OLED_ShowString(0,0,"T:",16);
OLED_ShowString(16,0,wendu,16);
OLED_ShowString(65,0,"RH:",16);
OLED_ShowString(92,0,shidu,16);
OLED_ShowString(0,2,"CO2 TC:",16);
OLED_ShowNum(56,2,CO2Data,3,16);
OLED_ShowNum(84,2,TVOCData,3,16);
OLED_ShowString(108,2,"Pm",12);
OLED_ShowString(108,3,"Pd",12);
OLED_ShowString(0,4,"PM2.5:",16);
OLED_ShowNum(49,4,PM,4,16);
OLED_ShowString(80,4,"ug/m3",16);
OLED_ShowString(0,6,"NG:",16);
OLED_ShowNum(25,6,MQ,4,16);
OLED_ShowString(56,6,"PPm",16);
OLED_ShowString(84,6,"LUX:",16);
OLED_ShowString(116,6,str,16);
for(i=0;i<5;i++)
{
SGP_palydisy();
}
for(i=0;i<=25;i++)
{
PM2_5_display();
}
for(i=0;i<=5;i++)
{
MQ5_Init();
}
for(i=0;i<=5;i++)
{
guangzhao_Init();
}
}
}
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x66;
TH0 = 0xFC;
T0Count++;
if(T0Count>=1500)
{
T0Count=0;
DHT11_Init();
}
}
//MQ-5.h
#ifndef __MQ5_h__
#define __MQ5_h__
void MQ5_Init();
#endif
// MQ-5.c
#include <REGX52.H>
#include "ADC1115.h"
#include "Delay.h"
float MQ;
void MQ5_Init()
{
float v;
unsigned int Data;
ADS115_config1();
Data=ADS1115_ReadAD();
if(Data>0x8000)
v=((float)(0xffff-Data)/32768.0)*2.048;
else
v=((float)Data/32768.0)*2.048;
MQ=v*210+10;
}
//OLEDfont.h
#ifndef __OLEDFONT_H
#define __OLEDFONT_H
//常用ASCII表
//偏移量32
//ASCII字符集
//偏移量32
//大小:12*6
/************************************6*8的点阵************************************/
code unsigned char F6x8[][6] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,// ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08,// -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,// .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02,// /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00,// :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00,// ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14,// =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08,// >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06,// ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,// @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,// A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 55
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,// ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04,// ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40,// _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00,// '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78,// a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z
0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines
};
/****************************************8*16的点阵************************************/
code unsigned char F8X16[]=
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2
0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3
0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4
0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5
0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6
0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 7
0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8
0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9
0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10
0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14
0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25
0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26
0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27
0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29
0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30
0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31
0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34
0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35
0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38
0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40
0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41
0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42
0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43
0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44
0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45
0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47
0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49
0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50
0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51
0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53
0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54
0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55
0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56
0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57
0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58
0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59
0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60
0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61
0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63
0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65
0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66
0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67
0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69
0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71
0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72
0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73
0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74
0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75
0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77
0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79
0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80
0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81
0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83
0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84
0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86
0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87
0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89
0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90
0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91
0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92
0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93
0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};
code char Hzk[][32]={
{0x10,0x10,0x12,0xD2,0x52,0x5F,0x52,0xF2,0x52,0x5F,0x52,0xD2,0x12,0x10,0x10,0x00},
{0x00,0x00,0x00,0x9F,0x52,0x32,0x12,0x1F,0x12,0x32,0x52,0x9F,0x00,0x00,0x00,0x00},/*"黄",0*/
/* (16 X 16 , 宋体 )*/
{0x10,0x60,0x02,0x8C,0x40,0x20,0xF8,0x4F,0x48,0x49,0xFE,0x48,0x48,0x48,0x08,0x00},
{0x04,0x04,0x7E,0x01,0x00,0x00,0xFF,0x22,0x22,0x22,0x3F,0x22,0x22,0x22,0x20,0x00},/*"淮",1*/
/* (16 X 16 , 宋体 )*/
{0x40,0x30,0x11,0x96,0x90,0x90,0x91,0x96,0x90,0x90,0x98,0x14,0x13,0x50,0x30,0x00},
{0x04,0x04,0x04,0x04,0x04,0x44,0x84,0x7E,0x06,0x05,0x04,0x04,0x04,0x04,0x04,0x00},/*"学",2*/
/* (16 X 16 , 宋体 )*/
{0x00,0xFE,0x22,0x5A,0x86,0x10,0x0C,0x24,0x24,0x25,0x26,0x24,0x24,0x14,0x0C,0x00},
{0x00,0xFF,0x04,0x08,0x07,0x80,0x41,0x31,0x0F,0x01,0x01,0x3F,0x41,0x41,0x71,0x00},/*"院",3*/
/* (16 X 16 , 宋体 )*/
{0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0xF8,0x00,0x00,0x00},
{0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x7F,0x88,0x88,0x88,0x88,0x9F,0x80,0xF0,0x00},/*"电",4*/
/* (16 X 16 , 宋体 )*/
{0x80,0x82,0x82,0x82,0x82,0x82,0x82,0xE2,0xA2,0x92,0x8A,0x86,0x82,0x80,0x80,0x00},
{0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"子",5*/
/* (16 X 16 , 宋体 )*/
{0x00,0x80,0x60,0xF8,0x07,0x00,0x04,0x24,0x24,0x25,0x26,0x24,0x24,0x24,0x04,0x00},
{0x01,0x00,0x00,0xFF,0x00,0x00,0x00,0xF9,0x49,0x49,0x49,0x49,0x49,0xF9,0x00,0x00},/*"信",6*/
/* (16 X 16 , 宋体 )*/
{0x00,0x00,0x00,0xFC,0x54,0x54,0x56,0x55,0x54,0x54,0x54,0xFC,0x00,0x00,0x00,0x00},
{0x40,0x30,0x00,0x03,0x39,0x41,0x41,0x45,0x59,0x41,0x41,0x73,0x00,0x08,0x30,0x00},/*"息",7*/
/* (16 X 16 , 宋体 )*/
{0x40,0x30,0x11,0x96,0x90,0x90,0x91,0x96,0x90,0x90,0x98,0x14,0x13,0x50,0x30,0x00},
{0x04,0x04,0x04,0x04,0x04,0x44,0x84,0x7E,0x06,0x05,0x04,0x04,0x04,0x04,0x04,0x00},/*"学",8*/
/* (16 X 16 , 宋体 )*/
{0x00,0xFE,0x22,0x5A,0x86,0x10,0x0C,0x24,0x24,0x25,0x26,0x24,0x24,0x14,0x0C,0x00},
{0x00,0xFF,0x04,0x08,0x07,0x80,0x41,0x31,0x0F,0x01,0x01,0x3F,0x41,0x41,0x71,0x00},/*"院",9*/
/* (16 X 16 , 宋体 )*/
{0x40,0x42,0xCC,0x00,0x00,0xE2,0x22,0x2A,0x2A,0xF2,0x2A,0x26,0x22,0xE0,0x00,0x00},
{0x80,0x40,0x3F,0x40,0x80,0xFF,0x89,0x89,0x89,0xBF,0x89,0xA9,0xC9,0xBF,0x80,0x00},/*"通",10*/
/* (16 X 16 , 宋体 )*/
{0x00,0x80,0x60,0xF8,0x07,0x00,0x04,0x24,0x24,0x25,0x26,0x24,0x24,0x24,0x04,0x00},
{0x01,0x00,0x00,0xFF,0x00,0x00,0x00,0xF9,0x49,0x49,0x49,0x49,0x49,0xF9,0x00,0x00},/*"信",11*/
/* (16 X 16 , 宋体 )*/
{0x00,0x04,0x04,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0x04,0x00,0x00},
{0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00},/*"工",12*/
/* (16 X 16 , 宋体 )*/
{0x24,0x24,0xA4,0xFE,0x23,0x22,0x00,0x3E,0x22,0x22,0x22,0x22,0x22,0x3E,0x00,0x00},
{0x08,0x06,0x01,0xFF,0x01,0x06,0x40,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x41,0x00},/*"程",13*/
/* (16 X 16 , 宋体 )*/
{0x40,0x40,0x48,0x48,0x48,0xC8,0x78,0x4F,0x48,0x48,0x48,0x48,0x48,0x40,0x40,0x00},
{0x00,0x00,0x00,0x00,0x03,0x12,0x12,0x22,0x22,0x52,0x8A,0x06,0x00,0x00,0x00,0x00},/*"专",14*/
/* (16 X 16 , 宋体 )*/
{0x00,0x10,0x60,0x80,0x00,0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,0xC0,0x30,0x00,0x00},
{0x40,0x40,0x40,0x43,0x40,0x7F,0x40,0x40,0x40,0x7F,0x42,0x41,0x40,0x40,0x40,0x00},/*"业",15*/
/* (16 X 16 , 宋体 )*/
{0x08,0x28,0x48,0x89,0x0E,0x88,0x78,0x08,0x08,0x00,0xF8,0x00,0x00,0xFF,0x00,0x00},
{0x40,0x20,0x10,0x09,0x06,0x19,0x60,0x00,0x00,0x00,0x0F,0x40,0x80,0x7F,0x00,0x00},/*"刘",16*/
/* (16 X 16 , 宋体 )*/
{0x10,0x60,0x02,0x8C,0x00,0x82,0x86,0x4A,0x52,0xA2,0x52,0x4A,0x86,0x80,0x80,0x00},
{0x04,0x04,0x7E,0x01,0x00,0x10,0x12,0x12,0x12,0xFF,0x12,0x12,0x12,0x10,0x00,0x00},/*"泽",17*/
/* (16 X 16 , 宋体 )*/
{0x08,0x08,0x88,0xA4,0xEC,0xAA,0xAA,0xF9,0xAA,0xAA,0xEC,0xA4,0x88,0x08,0x08,0x00},
{0x88,0xD4,0x96,0xFD,0x96,0xD4,0x88,0x00,0x88,0xD4,0x96,0xFD,0x96,0xD4,0x88,0x00},/*"鑫",18*/
/* (16 X 16 , 宋体 )*/
};
#endif
//OLED.h
#define __OLED_H
#include "stdlib.h"
#include <REGX52.H>
#define OLED_MODE 0
#define SIZE 8
#define XLevelL 0x00
#define XLevelH 0x10
#define Max_Column 128
#define Max_Row 64
#define Brightness 0xFF
#define X_WIDTH 128
#define Y_WIDTH 64
//-----------------OLED IIC端口定义----------------
#define OLED_SCLK_Clr() P1_0=0//CLK
#define OLED_SCLK_Set() P1_0=1
#define OLED_SDIN_Clr() P1_1=0//DIN
#define OLED_SDIN_Set() P1_1=1
#define OLED_CMD 0 //写命令
#define OLED_DATA 1 //写数据
#define u8 unsigned char
#define u32 unsigned long int
//OLED控制用函数
void OLED_Display_On(void);
void OLED_Display_Off(void);
void OLED_Init(void);
void OLED_Clear(void);
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 char_size);
void OLED_ShowString(u8 x,u8 y, u8 *p,u8 Char_Size);
void OLED_ShowCHinese(u8 x,u8 y,u8 no);
#endif
// OLED.c
#include "oled.h"
#include "stdlib.h"
#include "oledfont.h"
#include "Delay.h"
//OLED的显存
//存放格式如下.
//[0]0 1 2 3 ... 127
//[1]0 1 2 3 ... 127
//[2]0 1 2 3 ... 127
//[3]0 1 2 3 ... 127
//[4]0 1 2 3 ... 127
//[5]0 1 2 3 ... 127
//[6]0 1 2 3 ... 127
//[7]0 1 2 3 ... 127
/**********************************************
//IIC Start
**********************************************/
void IIC_Start()
{
OLED_SCLK_Set();
OLED_SDIN_Set();
OLED_SDIN_Clr();
OLED_SCLK_Clr();
}
/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
OLED_SCLK_Set();
// OLED_SCLK_Clr();
OLED_SDIN_Clr();
OLED_SDIN_Set();
}
void IIC_Wait_Ack()
{
//GPIOB->CRH &= 0XFFF0FFFF; //设置PB12为上拉输入模式
//GPIOB->CRH |= 0x00080000;
// OLED_SDA = 1;
// delay_us(1);
//OLED_SCL = 1;
//delay_us(50000);
/* while(1)
{
if(!OLED_SDA) //判断是否接收到OLED 应答信号
{
//GPIOB->CRH &= 0XFFF0FFFF; //设置PB12为通用推免输出模式
//GPIOB->CRH |= 0x00030000;
return;
}
}
*/
OLED_SCLK_Set();
OLED_SCLK_Clr();
}
/**********************************************
// IIC Write byte
**********************************************/
void Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
unsigned char m,da;
da=IIC_Byte;
OLED_SCLK_Clr();
for(i=0;i<8;i++)
{
m=da;
// OLED_SCLK_Clr();
m=m&0x80;
if(m==0x80)
{OLED_SDIN_Set();}
else OLED_SDIN_Clr();
da=da<<1;
OLED_SCLK_Set();
OLED_SCLK_Clr();
}
}
/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
IIC_Start();
Write_IIC_Byte(0x78); //Slave address,SA0=0
IIC_Wait_Ack();
Write_IIC_Byte(0x00); //write command
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Command);
IIC_Wait_Ack();
IIC_Stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
IIC_Start();
Write_IIC_Byte(0x78); //D/C#=0; R/W#=0
IIC_Wait_Ack();
Write_IIC_Byte(0x40); //write data
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Data);
IIC_Wait_Ack();
IIC_Stop();
}
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
if(cmd)
{
Write_IIC_Data(dat);
}
else {
Write_IIC_Command(dat);
}
}
//坐标设置
void OLED_Set_Pos(unsigned char x, unsigned char y)
{ OLED_WR_Byte(0xb0+y,OLED_CMD);
OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
OLED_WR_Byte((x&0x0f),OLED_CMD);
}
//开启OLED显示
void OLED_Display_On(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON
OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF
OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
}
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
} //更新显示
}
void OLED_On(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA);
} //更新显示
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示
//:选择字体 16/12
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{
unsigned char c=0,i=0;
c=chr-' ';//得到偏移后的值
if(x>Max_Column-1){x=0;y=y+2;}
if(Char_Size ==16)
{
OLED_Set_Pos(x,y);
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
OLED_Set_Pos(x,y+1);
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
}
else {
OLED_Set_Pos(x,y);
for(i=0;i<6;i++)
OLED_WR_Byte(F6x8[c][i],OLED_DATA);
}
}
//m^n函数
u32 oled_pow(u8 m,u8 n)
{
u32 result=1;
while(n--)result*=m;
return result;
}
//显示2个数字
//x,y :起点坐标
//len :数字的位数
//:字体大小
//mode:模式 0,填充模式;1,叠加模式
//num:数值(0~4294967295);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 Char_Size)
{
u8 t,temp;
u8 enshow=0;
for(t=0;t<len;t++)
{
temp=(num/oled_pow(10,len-t-1))%10;
OLED_ShowChar(x+(Char_Size/2)*t,y,temp+'0',Char_Size);
}
}
//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
{
unsigned char j=0;
while (chr[j]!='\0')
{ OLED_ShowChar(x,y,chr[j],Char_Size);
x+=8;
if(x>120){x=0;y+=2;}
j++;
}
}
//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{
u8 t,adder=0;
OLED_Set_Pos(x,y);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
adder+=1;
}
OLED_Set_Pos(x,y+1);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
adder+=1;
}
}
//初始化SSD1306
void OLED_Init(void)
{
OLED_WR_Byte(0xAE,OLED_CMD);//--display off
OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
OLED_WR_Byte(0x40,OLED_CMD);//--set start line address
OLED_WR_Byte(0xB0,OLED_CMD);//--set page address
OLED_WR_Byte(0x81,OLED_CMD); // contract control
OLED_WR_Byte(0xFF,OLED_CMD);//--128
OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap
OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction
OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
OLED_WR_Byte(0x00,OLED_CMD);//
OLED_WR_Byte(0xD5,OLED_CMD);//set osc division
OLED_WR_Byte(0x80,OLED_CMD);//
OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
OLED_WR_Byte(0x05,OLED_CMD);//
OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
OLED_WR_Byte(0xF1,OLED_CMD);//
OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
OLED_WR_Byte(0x12,OLED_CMD);//
OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
OLED_WR_Byte(0x30,OLED_CMD);//
OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
OLED_WR_Byte(0x14,OLED_CMD);//
OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
OLED_Clear();
}
//PM2.h
#ifndef __PM2_5_h__
#define __PM2_5_h__
void PM2_5_display();
#endif
//PM2.c
#include <REGX52.H>
#include "ADC1115.h"
#include "Delay.h"
float PM;
void PM2_5()
{
float v;
unsigned int Data;
ADS115_config();
Data=ADS1115_ReadAD();
if(Data>0x8000)
v=((float)(0xffff-Data)/32768.0)*2.048;
else
v=((float)Data/32768.0)*2.048;
v=v*1000*11;
PM=v;
PM=(PM)*0.17-60;
}
void PM2_5_display()
{
P1_3=0;
Delay(5);
PM2_5();
Delay300us();
P1_3=1;
Delay(2);
}
//SGP_init.h
#ifndef __SGP_h__
#define __SGP_h__
void SGP_Init();
void SGP_palydisy();
#endif
// SGP_init.c
#include <REGX52.H>
#include "IIC.h"
#include "Delay.h"
unsigned long sgp30_dat;
unsigned int CO2Data,TVOCData;
void SGP_Init()
{
SGP30_Init();
Delay(100);
SGP30_Write(0x20,0x08);
sgp30_dat = SGP30_Read();//读取SGP30的值
CO2Data = (sgp30_dat & 0xffff0000) >> 16;
TVOCData = sgp30_dat & 0x0000ffff;
while(CO2Data == 400 && TVOCData == 0)
{
SGP30_Write(0x20,0x08);
sgp30_dat = SGP30_Read();//读取SGP30的值
CO2Data = (sgp30_dat & 0xffff0000) >> 16;//取出CO2浓度值
TVOCData = sgp30_dat & 0x0000ffff; //取出TVOC值
Delay(100);
}
}
void SGP_palydisy()
{
SGP30_Write(0x20,0x08);
(unsigned long)sgp30_dat = (unsigned long)SGP30_Read();//读取SGP30的值
CO2Data = (sgp30_dat & 0xffff0000) >> 16;//取出CO2浓度值
TVOCData = sgp30_dat & 0x0000ffff; //取出TVOC值
Delay(100);
}
//SGP30.h
#ifndef __SGP30_H
#define __SGP30_H
#include <REGX52.H>
#define SGP30_read 0xb1 //SGP30的读地址
#define SGP30_write 0xb0 //SGP30的写地址
#define ACK 0 //应答信号
#define NACK 1 //非应答信号
#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long int
//I2C起始信号
void I2C_Start(void);
//I2C停止信号
void I2C_Stop(void);
//I2C写一个字节数据,返回ACK或者NACK
u8 I2C_SendByte(u8 Write_Byte);
//I2C读一个字节数据,入口参数用于控制应答状态,ACK或者NACK
u8 I2C_ReceiveByte(u8 AckValue);
//初始化SGP30
void SGP30_Init(void);
//向SGP30写数据
void SGP30_Write(u8 a, u8 b);
//从SGP30读数据
u32 SGP30_Read(void);
#endif
//SGP30.c
#include "SGP30.H"
#include "Delay.h"
sbit I2C_SCL=P2^0;
sbit I2C_SDA=P2^1;
unsigned char I2C_ReceiveAck(void)
{
unsigned char AckBit;
I2C_SDA=1;
I2C_SCL=1;
AckBit=I2C_SDA;
I2C_SCL=0;
return AckBit;
}
void SGP30_Write(u8 a, u8 b)
{
I2C_Start();
I2C_SendByte(SGP30_write); //发送器件地址+写指令
I2C_SendByte(a); //发送控制字节
I2C_SendByte(b);
I2C_Stop();
Delay(100);
}
//初始化IIC接口
void SGP30_Init(void)
{
SGP30_Write(0x20,0x03);
// SGP30_ad_write(0x20,0x61);
// SGP30_ad_write(0x01,0x00);
}
unsigned long SGP30_Read(void)
{
unsigned long dat;
int crc;
I2C_Start();
I2C_SendByte(SGP30_read); //发送器件地址+读指令
dat = I2C_ReceiveByte(ACK);
dat <<= 8;
dat += I2C_ReceiveByte(ACK);
crc = I2C_ReceiveByte(ACK); //check数据,舍去
crc = crc; //避免编译产生警告,这句可有可无
dat <<= 8;
dat += I2C_ReceiveByte(ACK);
dat <<= 8;
dat += I2C_ReceiveByte(NACK);
I2C_Stop();
return(dat);
}
// Timer0.h
#ifndef __TIMER0_H__
#define __TIMER0_H__
void Timer0Init(void);
#endif
// Timer0.c
#include <REGX52.H>
void Timer0Init(void)
{
TMOD &= 0xF0;
TMOD |= 0x01;
TL0 = 0x66;
TH0 = 0xFC;
TF0 = 0;
ET0=1;
EA=1;
TR0=1;
PT0=0;
}
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18;
TH0 = 0xFC;
T0Count++;
if(T0Count>=1000)
{
T0Count=0;
}
}
//UART.h
#ifndef __UART_H__
#define __UART_H__
void UART_Init();
void UART_SendByte(unsigned char Byte);
#endif
//UART.c
#include <REGX52.H>
void UART_Init()
{
SCON=0x40;
PCON |= 0x80;
TMOD &= 0x0F;
TMOD |= 0x20;
TL1 = 0xF3;
TH1 = 0xF3;
ET1 = 0;
TR1 = 1;
}
void UART_SendByte(unsigned char Byte)
{
SBUF=Byte;
while(TI==0);
TI=0;
}