基于单片机设计的防煤气泄漏装置实验报告,基于单片机的智能可燃气体泄露报警器
墨初 知识笔记 54阅读
数字输出引脚sbit MQ4_AIN P3^1; // MQ4传感器模拟输入引脚sfr IAP_DATA 0xe2; // 定义IAP_DATA寄存器sfr IAP_ADDRH 0xe3; // 定义IAP_ADDRH寄存器sfr IAP_ADDRL 0xe4; // 定义IAP_ADDRL寄存器sfr IAP_CMD 0xe5; // 定义IAP_CMD寄存器sfr IAP_TRIG 0xe6; // 定义IAP_TRIG寄存器sfr IAP_CONTR 0xe7; // 定义IAP_CONTR寄存器// 函数声明void delay(uint ms);void startIIC();void stopIIC();void sendByte(uchar dat);uchar receiveByte();void writeDAC(uchar dat);uchar readADC();void main() { uchar mq4Value; while (1) { mq4Value readADC(); // 读取ADC转换结果 // 处理mq4Value值进行相应操作 delay(100); // 延时一段时间 }}// 延时函数void delay(uint ms) { uint i, j; for(i ms; i > 0; i--) { for(j 110; j > 0; j--); }}// IIC总线起始信号void startIIC() { SDA 1; _nop_(); SCL 1; _nop_(); SDA 0; _nop_(); SCL 0; _nop_();}// IIC总线停止信号void stopIIC() { SDA 0; _nop_(); SCL 1; _nop_(); SDA 1; _nop_();}// 发送一个字节的数据void sendByte(uchar dat) { uchar i; for (i 0; i < 8; i) { SDA dat >> 7; _nop_(); SCL 1; _nop_(); SCL 0; _nop_(); dat << 1; } SDA 1; _nop_(); SCL 1; _nop_(); SCL 0; _nop_();}// 接收一个字节的数据uchar receiveByte() { uchar i, dat 0; SDA 1; for (i 0; i < 8; i) { dat << 1; SCL 1; _nop_(); dat | SDA; SCL 0; _nop_(); } return dat;}// 写入DAC数值void writeDAC(uchar dat) { startIIC(); sendByte(0x90); // 地址和写命令 receiveByte(); // 接收应答 sendByte(0x40); // DAC通道A并写入数据 receiveByte(); // 接收应答 sendByte(dat); // DAC数据 receiveByte(); // 接收应答 stopIIC();}// 读取ADC转换结果uchar readADC() { uchar adcValue; startIIC(); sendByte(0x91); // 地址和读命令 receiveByte(); // 接收应答 adcValue receiveByte(); // 读取ADC数据 stopIIC(); return adcValue;} 4.2 OLED显示屏代码
以下是通过STC89C52控制IIC接口的OLED显示屏显示ADC数据实现代码。

#include <reg51.h>#define SCL P1_0 // IIC时钟线#define SDA P1_1 // IIC数据线#define OLED_ADDR 0x78 // OLED显示屏的IIC地址// OLED显示屏初始化函数void OLED_Init() { // 初始化OLED显示屏 // ... // 发送初始化命令到OLED显示屏 // ...}// IIC总线开始信号void IIC_Start() { SDA 1; SCL 1; SDA 0; SCL 0;}// IIC总线停止信号void IIC_Stop() { SDA 0; SCL 1; SDA 1;}// IIC总线发送一个字节的数据void IIC_WriteByte(unsigned char dat) { unsigned char i; for (i 0; i < 8; i) { SCL 0; if (dat & 0x80) SDA 1; else SDA 0; SCL 1; dat << 1; } SCL 0; SDA 1; SCL 1;}// 设置OLED显示屏光标位置void OLED_SetPos(unsigned char x, unsigned char y) { IIC_Start(); IIC_WriteByte(OLED_ADDR); IIC_WriteByte(0xb0 y); IIC_WriteByte(((x & 0xf0) >> 4) | 0x10); IIC_WriteByte((x & 0x0f) | 0x01); IIC_Stop();}// 在OLED显示屏上显示一个字符void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char ch) { unsigned char c 0, i 0; c ch - ; // 获取字符在字库中的偏移量 if (x > 128 - 8 || y > 64 - 16) return; // 超出屏幕范围退出函数 OLED_SetPos(x, y); for (i 0; i < 8; i) { IIC_Start(); IIC_WriteByte(OLED_ADDR); IIC_WriteByte(0x40); IIC_WriteByte(*(OLED_CharSet c * 16 i)); IIC_Stop(); x; }}// 在OLED显示屏上显示字符串void OLED_ShowString(unsigned char x, unsigned char y, unsigned char *str) { while (*str) { OLED_ShowChar(x, y, *str); x 8; str; }}// ADC模拟数值转换为字符串void ADC_ToString(unsigned int adcValue, unsigned char *str) { unsigned char i, j; unsigned int temp; temp adcValue; for (i 0; i < 4; i) { str[i] temp % 10 0; temp / 10; } // 反转字符串 i 0; j 3; while (i < j) { temp str[i]; str[i] str[j]; str[j] temp; i; j--; } str[4] \0; // 字符串结束符}// 主函数void main() { unsigned int adcValue 0; unsigned char str[5]; // 初始化OLED显示屏 OLED_Init(); while (1) { // 读取ADC数据 adcValue ADC_Read(); // 假设使用的函数为ADC_Read()用于读取ADC数据 // 将ADC数据转换为字符串 ADC_ToString(adcValue, str); // 在OLED显示屏上显示ADC数据 OLED_ShowString(0, 0, ADC Value:); OLED_ShowString(0, 2, str); }}
4.3 主代码逻辑 #include <reg51.h>#define SCL P1_0 // IIC时钟线#define SDA P1_1 // IIC数据线#define OLED_ADDR 0x78 // OLED显示屏的IIC地址#define MQ4_PIN P2 // MQ4传感器连接的引脚sbit Buzzer P3^0; // 蜂鸣器控制引脚sbit VentilationFan P3^1; // 换气扇控制引脚// 全局变量unsigned int alarmThreshold 100; // 报警阈值默认为100unsigned int adcValue 0; // 保存ADC采集到的数值// IIC总线开始信号void IIC_Start() { SDA 1; SCL 1; SDA 0; SCL 0;}// IIC总线停止信号void IIC_Stop() { SDA 0; SCL 1; SDA 1;}// IIC总线发送一个字节的数据void IIC_WriteByte(unsigned char dat) { unsigned char i; for (i 0; i < 8; i) { SCL 0; if (dat & 0x80) SDA 1; else SDA 0; SCL 1; dat << 1; } SCL 0; SDA 1; SCL 1;}// 设置OLED显示屏光标位置void OLED_SetPos(unsigned char x, unsigned char y) { IIC_Start(); IIC_WriteByte(OLED_ADDR); IIC_WriteByte(0xb0 y); IIC_WriteByte(((x & 0xf0) >> 4) | 0x10); IIC_WriteByte((x & 0x0f) | 0x01); IIC_Stop();}// 在OLED显示屏上显示一个字符void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char ch) { unsigned char c 0, i 0; c ch - ; // 获取字符在字库中的偏移量 if (x > 128 - 8 || y > 64 - 16) return; // 超出屏幕范围退出函数 OLED_SetPos(x, y); for (i 0; i < 8; i) { IIC_Start(); IIC_WriteByte(OLED_ADDR); IIC_WriteByte(0x40); IIC_WriteByte(*(OLED_CharSet c * 16 i)); IIC_Stop(); x; }}// 在OLED显示屏上显示字符串void OLED_ShowString(unsigned char x, unsigned char y, unsigned char *str) { while (*str) { OLED_ShowChar(x, y, *str); x 8; str; }}// ADC转换函数unsigned int ADC_Convert(unsigned char channel) { ADC_CONTR ADC_POWER | ADC_START | channel | ADC_SPEED; _nop_(); _nop_(); _nop_(); _nop_(); while (!(ADC_CONTR & ADC_FLAG)) ; ADC_CONTR & ~ADC_FLAG; return (ADC_RES * 256 ADC_RESL);}// ADC模拟数值转换为字符串void ADC_ToString(unsigned int adcValue, unsigned char *str) { unsigned char i, j; unsigned int temp; temp adcValue; for (i 0; i < 4; i) { str[i] temp % 10 0; temp / 10; } // 反转字符串 i 0; j 3; while (i < j) { temp str[i]; str[i] str[j]; str[j] temp; i; j--; } str[4] \0; // 字符串结束符} 主函数void main() { unsigned char str[5]; // 初始化OLED显示屏 OLED_Init(); // 设置初始报警阈值 SetAlarmThreshold(); while (1) { // 读取MQ4传感器的ADC数值 adcValue ADC_Convert(0); // 假设MQ4传感器连接到ADC的通道0 // 将ADC数值转换为字符串 ADC_ToString(adcValue, str); // 在OLED显示屏上显示ADC数值 OLED_ShowString(0, 0, Gas Level:); OLED_ShowString(0, 2, str); // 判断是否触发报警 if (adcValue > alarmThreshold) { // 触发报警 ActivateAlarm(); } else { // 取消报警 DeactivateAlarm(); } // 检测是否按下设置阈值的按键 if (IsThresholdButtonPressed()) { // 设置报警阈值 SetAlarmThreshold(); } // 检测是否按下通风换气的按键 if (IsVentilationButtonPressed()) { // 控制通风换气 ControlVentilation(); } }}
标签: