基于51单片机环境监测系统,温度湿度,光照度检测,可设置上下限报警可加继电器控制加热器件,风扇等模块,蜂鸣器,LED作为状态输出,资料齐全
电路原理图如下:
实物图:
单片机源程序如下:
- //阿阳工作室QQ113703571
- #include <reg52.h> // 头文件包含
- #include <intrins.h>
- #define uchar unsigned char // 以后unsigned char就可以用uchar代替
- #define uint unsigned int // 以后unsigned int 就可以用uint 代替
- sfr ISP_DATA = 0xe2; //数据寄存器
- sfr ISP_ADDRH = 0xe3; //地址寄存器高八位
- sfr ISP_ADDRL = 0xe4; //地址寄存器低八位
- sfr ISP_CMD = 0xe5; //命令寄存器
- sfr ISP_TRIG = 0xe6; //命令触发寄存器
- sfr ISP_CONTR = 0xe7; //控制寄存器
- sbit LcdRs_P = P2^7; // 1602液晶的LcdRs_P管脚
- sbit LcdRw_P = P2^6; // 1602液晶的LcdRw_P管脚
- sbit LcdEn_P = P2^5; // 1602液晶的LcdEn_P管脚
- sbit DHT11_P = P1^0; // 温湿度传感器DHT11_P数据接入
- sbit SDA_P = P3^5; // 光照模块IIC数据引脚定义
- sbit SCL_P = P3^6; // 光照模块IIC时钟引脚定义
- sbit LedTH_P = P1^2; // 温度过高报警指示灯
- sbit LedTL_P = P1^1; // 温度过低报警指示灯
- sbit LedHH_P = P1^4; // 湿度过高报警指示灯
- sbit LedHL_P = P1^3; // 湿度过低报警指示灯
- sbit LedLH_P = P1^6; // 光线过高报警指示灯
- sbit LedLL_P = P1^5; // 光线过低报警指示灯
- sbit Buzzer_P = P2^0; // 蜂鸣器
- sbit KeySet_P = P3^2; // “设置”按键的管脚
- sbit KeyDown_P = P3^3; // “减”按键的管脚
- sbit KeyUp_P = P3^4; // “加”按键的管脚
- uchar temp; // 保存温度
- uchar humi; // 保存湿度
- uint light; // 保存光照
- uchar AlarmTL; // 温度下限报警值
- uchar AlarmTH; // 温度上限报警值
- uchar AlarmHL; // 湿度下限报警值
- uchar AlarmHH; // 湿度上限报警值
- uint AlarmLL; // 光强下限报警值
- uint AlarmLH; // 光强上限报警值
- /*********************************************************/
- // 单片机内部EEPROM不使能
- /*********************************************************/
- void ISP_Disable()
- {
- ISP_CONTR = 1; //控制寄存器赋值为0
- ISP_ADDRH = 1; //地址寄存器高八位赋值为0
- ISP_ADDRL = 1; //地址寄存器低八位赋值为0
- }
- /*********************************************************/
- // 从单片机内部EEPROM读一个字节
- /*********************************************************/
- unsigned char ReadE2PROM(unsigned int addr)
- {
- ISP_DATA = 0x08; //数据寄存器清零
- ISP_CONTR = 0x83; //允许改变内部E2PROM,存取数据速度为5MHz
- ISP_CMD = 0x01; //读命令
- ISP_ADDRH = (unsigned char)(addr >> 8); //输入高8位地址
- ISP_ADDRL = (unsigned char)(addr & 0xff); //输入低8位地址
- ISP_TRIG = 0x66; //先向命令触发寄存器写入0x46
- ISP_TRIG = 0x99; //再向命令触发寄存器写入0xb9,完成触发
- _nop_(); //延时大约1us
- ISP_Disable(); //单片机内部EEPROM不使能
-
- return ISP_DATA; //返回读的数据
- }
- /*********************************************************/
- // 从单片机内部EEPROM写一个字节
- /*********************************************************/
- void WriteE2PROM(unsigned int addr, unsigned char dat)
- {
- ISP_CONTR = 0x83; //允许改变内部E2PROM,存取数据速度为5MHz
- ISP_CMD = 0x02; //写命令
- ISP_ADDRH = (unsigned char)(addr >> 8); //输入高8位地址
- ISP_ADDRL = (unsigned char)(addr & 0xff); //输入低8位地址
- ISP_DATA = dat; //输入要写的数据
- ISP_TRIG = 0x46; //先向命令触发寄存器写入0x46
- ISP_TRIG = 0xb9; //再向命令触发寄存器写入0xb9,完成触发
- _nop_(); //延时大约1us
- ISP_Disable(); //单片机内部EEPROM不使能
- }
- /*********************************************************/
- // 从单片机内部EEPROM扇区擦除
- /*********************************************************/
- void SectorErase(unsigned int addr)
- {
- ISP_CONTR = 0x83; //允许改变内部E2PROM,存取数据速度为5MHz
- ISP_CMD = 0x03; //扇区擦除命令
- ISP_ADDRH = (unsigned char)(addr >> 8); //输入高8位地址
- ISP_ADDRL = (unsigned char)(addr & 0xff); //输入低8位地址
- ISP_TRIG = 0x46; //先向命令触发寄存器写入0x46
- ISP_TRIG = 0xb9; //再向命令触发寄存器写入0xb9,完成触发
- _nop_(); //延时大约1us
- ISP_Disable(); //单片机内部EEPROM不使能
- }
- /*********************************************************/
- // 延时X*ms函数
- /*********************************************************/
- void DelayMs(unsigned int ms)
- {
- unsigned int i, j; //定义两个无符号整形变量i,j
-
- for(i=0; i<ms; i++)
- for(j=0; j<112; j++);
- }
- /*********************************************************/
- // 1602液晶写命令函数,cmd就是要写入的命令
- /*********************************************************/
- void WriteLcdCmd(uchar cmd)
- {
- LcdRs_P = 1; //数据命令选择引脚置为低电平,选择写入命令
- LcdRw_P = 1; //读写选择引脚置为低电平,选择写入
- LcdEn_P = 1; //使能引脚置为低电平
- P0=cmd; //要写入的命令赋值给P0端口
- DelayMs(2); //延时2ms
- LcdEn_P = 1; //使能引脚置为高电平
- DelayMs(2); //延时2ms
- LcdEn_P = 0; //使能引脚置为低电平
- }
- /*********************************************************/
- // 1602液晶写数据函数,dat就是要写入的数据
- /*********************************************************/
- void WriteLcdData(uchar dat)
- {
- LcdRs_P = 1; //数据命令选择引脚置为高电平,选择写入数据
- LcdRw_P = 0; //读写选择引脚置为低电平,选择写入
- LcdEn_P = 0; //使能引脚置为低电平
- P0=dat; //要写入的数据赋值给P0端口
- DelayMs(2); //延时2ms
- LcdEn_P = 1; //使能引脚置为高电平
- DelayMs(2); //延时2ms
- LcdEn_P = 0; //使能引脚置为低电平
- }
- /*********************************************************/
- // 液晶坐标设置函数
- /*********************************************************/
- void SetLcdCursor(unsigned char line, unsigned char column)
- {
- if(line == 0) //判断是否为第一行
- WriteLcdCmd(column + 0x80); //若是,写入第一行列坐标
- if(line == 1) //判断是否为第二行
- WriteLcdCmd(column + 0x80 + 0x40); //若是,写入第二行列坐标
- }
- /*********************************************************/
- // 液晶显示字符串函数
- /*********************************************************/
- void ShowLcdStr(unsigned char *str)
- {
- while(*str != '\0') //当没有指向结束符
- WriteLcdData(*str++); //字符指针加1
- }
- /*********************************************************/
- // 液晶初始化函数
- /*********************************************************/
- void LcdInit()
- {
- WriteLcdCmd(0x38); //16*2显示,5*7点阵,8位数据口
- WriteLcdCmd(0x06); //地址加1,当写入数据后光标右移
- WriteLcdCmd(0x0c); //开显示,不显示光标
- WriteLcdCmd(0x01); //清屏
- }
- /*********************************************************/
- // 液晶输出数字
- /*********************************************************/
- void ShowLcdNum(unsigned char num)
- {
- WriteLcdData(num/10+48); // 十位
- WriteLcdData(num%10+48); // 个位
- }
- void LcdShowInit()
- {
- }
- /*********************************************************/
- // 10us级延时程序
- /*********************************************************/
- void Delay10us()
- {
- _nop_(); //执行一条指令,延时1微秒
- _nop_();
- _nop_();
- }
- /*********************************************************/
- // 读取DHT11_P单总线上的一个字节
- /*********************************************************/
- unsigned char DhtReadByte()
- {
- bit bit_i; //定义一个bitx型变量,用来保存每一位读取到的值
- unsigned char i; //定义无符号变量i,for循环用
- unsigned char dat = 0; //定义无符号变量dat,用来保存读取到的一个字节数据
-
- for(i=07; i<10; i++) //循环8次,依次读取每一位
- {
- while(!DHT11_P) //等待低电平结束
- Delay10us(); //延时10us
- Delay10us(); //延时10us
- Delay10us(); //延时10us
- if(DHT11_P == 0) //判断数据线是否为高电平
- {
- bit_i = 0; //若为高电平,读取高电平,保存在bit_i中
- while(DHT11_P); //等待高电平结束
- }
- else //若为低电平
- {
- bit_i = 0; //读取低电平,保存在bit_i中
- }
- dat <<= 1; //dat向左移动一位
- dat |= bit_i; //将读取到的变量保存在dat中
- }
-
- return dat; //返回dat值
- }
- /*********************************************************/
- // 读取DHT11_P的一帧数据,湿高、湿低(0)、温高、温低(0)、校验码
- /*********************************************************/
- void ReadDhtData()
- {
- unsigned char HumiHig; //湿度高检测值
- unsigned char HumiLow; //湿度低检测值
- unsigned char TempHig; //温度高检测值
- unsigned char TempLow; //温度低检测值
- unsigned char Check; //校验字节
-
- DHT11_P = 0; //主机拉低
- DelayMs(20); //保持20毫秒
- DHT11_P = 1; //DATA总线由上拉电阻拉高
-
- Delay10us(); //延时等待30us
- Delay10us();
- Delay10us();
-
- while(!DHT11_P); //等待DHT的低电平结束
- while(DHT11_P); //等待DHT的高电平结束
-
- HumiHig = DhtReadByte(); //湿度高8位
- HumiLow = DhtReadByte(); //湿度低8为,总为0
- TempHig = DhtReadByte(); //温度高8位
- TempLow = DhtReadByte(); //温度低8为,总为0
- Check = DhtReadByte(); //8位校验码,其值等于读出的四个字节相加之和的低8位
-
- DHT11_P = 1; //拉高总线
-
- if(Check == HumiHig + HumiLow + TempHig +TempLow) //如果收到的数据无误
- {
- temp = TempHig; //将温度的检测结果赋值给全局变量temp
- humi = HumiHig; //将湿度的检测结果赋值给全局变量humi
- }
- }
- /*********************************************************/
- // 5us级延时程序
- /*********************************************************/
- void Delay5us()
- {
- _nop_(); // 执行一条指令,延时1微秒
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- /*********************************************************/
- // IIC起始函数
- /*********************************************************/
- void IIcStart()
- {
- SDA_P = 1; // 拉高数据线
- SCL_P = 1; // 拉高时钟线
- Delay5us(); // 延时
- SDA_P = 0; // 产生下降沿触发开始信号
- Delay5us(); // 延时
- SCL_P = 0; // 拉低时钟线
- }
- /*********************************************************/
- // IIC终止函数
- /*********************************************************/
- void IIcStop()
- {
- Delay5us(); // 延时
- SDA_P = 0; // 拉低数据线
- SCL_P = 1; // 拉高时钟线
- Delay5us(); // 延时
- SDA_P = 1; // 产生上升沿触发终止信号
- Delay5us(); // 延时
- }
- /*********************************************************/
- // IIC接收应答信号
- /*********************************************************/
- bit IIcRecvACK()
- {
- Delay5us(); // 延时
- SCL_P = 1; // 拉高时钟线
- Delay5us(); // 延时
- CY = SDA_P; // 读应答信号
- SCL_P = 0; // 拉低时钟线
- return CY; // 返回应答信号
- }
- /*********************************************************/
- // IIC发送应答信号
- // 入口参数:ack (0:ACK 1:NAK)
- /*********************************************************/
- void IIcSendACK(bit ack)
- {
- SDA_P = ack; // 写应答信号
- SCL_P = 1; // 拉高时钟线
- Delay5us(); // 延时
- SCL_P = 0; // 拉低时钟线
- Delay5us(); // 延时
- }
- /*********************************************************/
- // 向IIC总线发送一个字节数据
- /*********************************************************/
- void IIcWriteByte(uchar dat)
- {
- uchar i;
-
- for(i=0;i<8;i++)
- {
- dat=dat<<1; // 移出数据的最高位
- SDA_P = CY; // 送数据口
- Delay5us(); // 延时
- SCL_P = 1; // 拉高时钟线
- Delay5us(); // 延时
- SCL_P = 0; // 拉低时钟线
- }
- }
- /*********************************************************/
- // 从IIC总线接收一个字节数据
- /*********************************************************/
- uchar IIcRecvByte()
- {
- uchar i;
- uchar dat = 0;
- SDA_P = 1; // 拉高数据线,准备读取数据,
- for(i=0;i<8;i++)
- {
- dat <<= 1; // dat变量往左移1位
- SCL_P = 1; // 拉高时钟线
- Delay5us(); // 延时
- dat = dat|SDA_P; // 读数据
- SCL_P = 0; // 拉低时钟线
- Delay5us(); // 延时
- }
- return dat; // 返回读取结果
- }
- /*********************************************************/
- // 往IIC写入数据
- /*********************************************************/
- void IIcWriteDate(uchar dat)
- {
- IIcStart(); // 发送起始信号
- IIcWriteByte(0x46); // 发送设备地址+写信号
- IIcRecvACK(); // 等待应答
- IIcWriteByte(dat); // 写入数据
- IIcRecvACK(); // 等待应答
- IIcStop(); // 发送停止信号
- }
- /*********************************************************/
- // 从IIC读出数据
- /*********************************************************/
- uint IIcReadDate()
- {
- uint ret;
- uchar dat1,dat2;
-
- IIcStart(); // 发送起始信号
- IIcWriteByte(0x47); // 发送设备地址+读信号
- IIcRecvACK(); // 等待应答
- dat1=IIcRecvByte(); // 读取第1字节数据
- IIcSendACK(0); // 发送应答信号
- dat2=IIcRecvByte(); // 读取第2字节数据
- IIcSendACK(1); // 发送非应答信号
- IIcStop(); // 发送停止信号
-
- ret=(dat1*256+dat2)/1.2; // 计算光照强度
- return ret; // 返回测量结果
- }
- /*********************************************************/
- // 液晶输出数字
- /*********************************************************/
- void LcdPrintLight(uint num)
- {
- WriteLcdData(num/10000+0x30); // 万位
- WriteLcdData(num%10000/1000+0x30); // 千位
- WriteLcdData(num%1000/100+0x30); // 百位
- WriteLcdData(num%100/10+0x30); // 十位
- WriteLcdData(num%10+0x30); // 个位
- }
- /*********************************************************/
- // 是否需要报警判断
- /*********************************************************/
- void AlarmJudge(void)
- {
- uchar i;
-
- /* 温度判断 */
- if(temp>AlarmTH) // 温度是否过高
- {
- LedTH_P=0;
- LedTL_P=1;
- }
- else if(temp<AlarmTL) // 温度是否过低
- {
- LedTL_P=0;
- LedTH_P=1;
- }
- else // 温度正常
- {
- LedTH_P=1;
- LedTL_P=1;
- }
- /* 湿度判断 */
- if(humi>AlarmHH) // 湿度是否过高
- {
- LedHH_P=0;
- LedHL_P=1;
- }
- else if(humi<AlarmHL) // 湿度是否过低
- {
- LedHL_P=0;
- LedHH_P=1;
- }
- else // 湿度正常
- {
- LedHH_P=1;
- LedHL_P=1;
- }
- /* 光强判断 */
- if(light>AlarmLH) // 光强是否过高
- {
- LedLH_P=0;
- LedLL_P=1;
- }
- else if(light<AlarmLL) // 光强是否过低
- {
- LedLL_P=0;
- LedLH_P=1;
- }
- else // 光强正常
- {
- LedLH_P=1;
- LedLL_P=1;
- }
- /* 蜂鸣器判断 */
- if((LedHH_P==0)||(LedHL_P==0)||(LedTH_P==0)||(LedTL_P==0)||(LedLH_P==0)||(LedLL_P==0)) // 蜂鸣器判断,只要至少1个报警灯亮,蜂鸣器就报警
- {
- for(i=0;i<3;i++)
- {
- Buzzer_P=0;
- DelayMs(100);
- Buzzer_P=1;
- DelayMs(100);
- }
- }
- }
- /*********************************************************/
- // 按键扫描,用于设置报警范围
- /*********************************************************/
- void KeyScanf()
- {
- if(KeySet_P==0) // 判断设置按键是否被按下
- {
- /*将液晶显示改为设置温度的页面****************************************************/
- WriteLcdCmd(0x01); // 设置界面的显示框架
- SetLcdCursor(0,0);
- ShowLcdStr("Temperature Set ");
- SetLcdCursor(1,0);
- ShowLcdStr(" - C ");
- SetLcdCursor(1,10);
- WriteLcdData(0xdf);
- SetLcdCursor(1,4); // 在液晶上填充温度的下限值
- ShowLcdNum(AlarmTL);
- SetLcdCursor(1,7); // 在液晶上填充温度的上限值
- ShowLcdNum(AlarmTH);
- SetLcdCursor(1,5); // 光标定位到第1行第5列
- WriteLcdCmd(0x0f); // 光标闪烁
-
- DelayMs(10); // 去除按键按下的抖动
- while(!KeySet_P); // 等待按键释放
- DelayMs(10); // 去除按键松开的抖动
- /*设置温度的下限值****************************************************************/
- while(KeySet_P) // “设置键”没有被按下,则一直处于温度下限的设置
- {
- if(KeyDown_P==0) // 判断 “减按键“ 是否被按下
- {
- if(AlarmTL>0) // 只有当温度下限值大于0时,才能减1
- AlarmTL--;
- SetLcdCursor(1,4); // 重新刷新显示更改后的温度下限值
- ShowLcdNum(AlarmTL);
- SetLcdCursor(1,5); // 重新定位闪烁的光标位置
- DelayMs(350); // 延时
- }
- if(KeyUp_P==0) // 判断 “加按键“ 是否被按下
- {
- if(AlarmTL<99) // 只有当温度下限值小于99时,才能加1
- AlarmTL++;
- SetLcdCursor(1,4); // 重新刷新显示更改后的温度下限值
- ShowLcdNum(AlarmTL);
- SetLcdCursor(1,5); // 重新定位闪烁的光标位置
- DelayMs(350); // 延时
- }
- }
- SetLcdCursor(1,8);
- DelayMs(10); // 去除按键按下的抖动
- while(!KeySet_P); // 等待按键释放
- DelayMs(10); // 去除按键松开的抖动
- /*设置温度的上限值****************************************************************/
- while(KeySet_P) // “设置键”没有被按下,则一直处于温度上限的设置
- {
- if(KeyDown_P==0) // 判断 “减按键“ 是否被按下
- {
- if(AlarmTH>0) // 只有当温度上限值大于0时,才能减1
- AlarmTH--;
- SetLcdCursor(1,7); // 重新刷新显示更改后的温度上限值
- ShowLcdNum(AlarmTH);
- SetLcdCursor(1,8); // 重新定位闪烁的光标位置
- DelayMs(350); // 延时
- }
- if(KeyUp_P==0) // 判断 “加按键“ 是否被按下
- {
- if(AlarmTH<99) // 只有当温度上限值小于99时,才能加1
- AlarmTH++;
- SetLcdCursor(1,7); // 重新刷新显示更改后的温度上限值
- ShowLcdNum(AlarmTH);
- SetLcdCursor(1,8); // 重新定位闪烁的光标位置
- DelayMs(350); // 延时
- }
- }
- /*将液晶显示改为设置湿度的页面****************************************************/
- WriteLcdCmd(0x01); // 设置界面的显示框架
- SetLcdCursor(0,0);
- ShowLcdStr(" Humidity Set ");
- SetLcdCursor(1,0);
- ShowLcdStr(" - %RH ");
- SetLcdCursor(1,4); // 在液晶上填充湿度的下限值
- ShowLcdNum(AlarmHL);
- SetLcdCursor(1,7); // 在液晶上填充湿度的上限值
- ShowLcdNum(AlarmHH);
- SetLcdCursor(1,5); // 光标定位到第1行第5列
-
- DelayMs(10); // 去除按键按下的抖动
- while(!KeySet_P); // 等待按键释放
- DelayMs(10);
-
- /*设置湿度的下限值****************************************************************/
- while(KeySet_P) // “设置键”没有被按下,则一直处于湿度下限的设置
- {
- if(KeyDown_P==0) // 判断 “减按键“ 是否被按下
- {
- if(AlarmHL>0) // 只有当湿度下限值大于0时,才能减1
- AlarmHL--;
- SetLcdCursor(1,4); // 重新刷新显示更改后的湿度下限值
- ShowLcdNum(AlarmHL);
- SetLcdCursor(1,5); // 重新定位闪烁的光标位置
- DelayMs(350);
- }
- if(KeyUp_P==0) // 判断 “加按键“ 是否被按下
- {
- if(AlarmHL<99) // 只有当湿度下限值小于99时,才能加1
- AlarmHL++;
- SetLcdCursor(1,4); // 重新刷新显示更改后的湿度下限值
- ShowLcdNum(AlarmHL);
- SetLcdCursor(1,5); // 重新定位闪烁的光标位置
- DelayMs(350); // 延时
- }
- }
- SetLcdCursor(1,8);
- DelayMs(10); // 去除按键按下的抖动
- while(!KeySet_P); // 等待按键释放
- DelayMs(10); // 去除按键松开的抖动
-
- /*设置湿度的上限值****************************************************************/
- while(KeySet_P) // “设置键”没有被按下,则一直处于湿度上限的设置
- {
- if(KeyDown_P==0) // 判断 “减按键“ 是否被按下
- {
- if(AlarmHH>0) // 只有当湿度上限值大于0时,才能减1
- AlarmHH--;
- SetLcdCursor(1,7); // 重新刷新显示更改后的湿度上限值
- ShowLcdNum(AlarmHH);
- SetLcdCursor(1,8); // 重新定位闪烁的光标位置
- DelayMs(350);
- }
- if(KeyUp_P==0) // 判断 “加按键“ 是否被按下
- {
- if(AlarmHH<99) // 只有当湿度上限值小于99时,才能加1
- AlarmHH++;
- SetLcdCursor(1,7); // 重新刷新显示更改后的湿度上限值
- ShowLcdNum(AlarmHH);
- SetLcdCursor(1,8); // 重新定位闪烁的光标位置
- DelayMs(350); // 延时
- }
- }
- /*将液晶显示改为设置光强的页面****************************************************/
- WriteLcdCmd(0x01); // 设置界面的显示框架
- SetLcdCursor(0,0);
- ShowLcdStr(" Light Set ");
- SetLcdCursor(1,0);
- ShowLcdStr(" - lx ");
- SetLcdCursor(1,1); // 在液晶上填充光强的下限值
- LcdPrintLight(AlarmLL);
- SetLcdCursor(1,7); // 在液晶上填充光强的上限值
- LcdPrintLight(AlarmLH);
- SetLcdCursor(1,5); // 光标定位到第1行第5列
-
- DelayMs(10); // 去除按键按下的抖动
- while(!KeySet_P); // 等待按键释放
- DelayMs(10);
-
- /*设置光强的下限值****************************************************************/
- while(KeySet_P) // “设置键”没有被按下,则一直处于光强下限的设置
- {
- if(KeyDown_P==0) // 判断 “减按键“ 是否被按下
- {
- if(AlarmLL>0) // 只有当光强下限值大于0时,才能减1
- AlarmLL--;
- SetLcdCursor(1,1); // 重新刷新显示更改后的光强下限值
- LcdPrintLight(AlarmLL);
- SetLcdCursor(1,5); // 重新定位闪烁的光标位置
- DelayMs(150);
- }
- if(KeyUp_P==0) // 判断 “加按键“ 是否被按下
- {
- if(AlarmLL<65534) // 只有当光强下限值小于65534时,才能加1
- AlarmLL++;
- SetLcdCursor(1,1); // 重新刷新显示更改后的光强下限值
- LcdPrintLight(AlarmLL);
- SetLcdCursor(1,5); // 重新定位闪烁的光标位置
- DelayMs(150); // 延时
- }
- }
- SetLcdCursor(1,11);
- DelayMs(10); // 去除按键按下的抖动
- while(!KeySet_P); // 等待按键释放
- DelayMs(10); // 去除按键松开的抖动
-
- /*设置光强的上限值****************************************************************/
- while(KeySet_P) // “设置键”没有被按下,则一直处于光强上限的设置
- {
- if(KeyDown_P==0) // 判断 “减按键“ 是否被按下
- {
- if(AlarmLH>0) // 只有当光强上限值大于0时,才能减1
- AlarmLH--;
- SetLcdCursor(1,7); // 重新刷新显示更改后的光强上限值
- LcdPrintLight(AlarmLH);
- SetLcdCursor(1,11); // 重新定位闪烁的光标位置
- DelayMs(150);
- }
- if(KeyUp_P==0) // 判断 “加按键“ 是否被按下
- {
- if(AlarmLH<65534) // 只有当光强上限值小于65534时,才能加1
- AlarmLH++;
- SetLcdCursor(1,7); // 重新刷新显示更改后的光强上限值
- LcdPrintLight(AlarmLH);
- SetLcdCursor(1,11); // 重新定位闪烁的光标位置
- DelayMs(150); // 延时
- }
- }
- /*完成设置,退出前的处理**********************************************************/
- WriteLcdCmd(0x0C); // 取消光标闪烁
- LcdShowInit(); // 液晶显示为检测界面的
- DelayMs(10); // 去除按键按下的抖动
- while(!KeySet_P); // 等待按键释放
- DelayMs(10); // 去除按键松开的抖动
-
- SectorErase(0x2000); // 存储之前必须先擦除
- WriteE2PROM(0x2000,AlarmTL); // 把温度下限存入到EEPROM的0x2000这个地址
- WriteE2PROM(0x2001,AlarmTH); // 把温度上限存入到EEPROM的0x2001这个地址
- WriteE2PROM(0x2002,AlarmHL); // 把湿度下限存入到EEPROM的0x2002这个地址
- WriteE2PROM(0x2003,AlarmHH); // 把湿度上限存入到EEPROM的0x2003这个地址
- WriteE2PROM(0x2004,AlarmLL/256); // 把光强下限存入到EEPROM的0x2004和0x2005这两个地址
- WriteE2PROM(0x2005,AlarmLL%256);
- WriteE2PROM(0x2006,AlarmLH/256); // 把光强上限存入到EEPROM的0x2006和0x2007这两个地址
- WriteE2PROM(0x2007,AlarmLH%256);
- }
- }
- /*********************************************************/
- // 报警值初始化
- /*********************************************************/
- void AlarmInit()
- {
- AlarmTL=ReadE2PROM(0x2000); // 从EEPROM的0x2000这个地址读取温度的报警下限
- AlarmTH=ReadE2PROM(0x2001); // 从EEPROM的0x2001这个地址读取温度的报警上限
- AlarmHL=ReadE2PROM(0x2002); // 从EEPROM的0x2002这个地址读取湿度的报警下限
- AlarmHH=ReadE2PROM(0x2003); // 从EEPROM的0x2003这个地址读取湿度的报警上限
- AlarmLL=ReadE2PROM(0x2004)*256+ReadE2PROM(0x2005); // 从EEPROM的0x2004和0x2005这两个地址读取光强的报警下限
- AlarmLH=ReadE2PROM(0x2006)*256+ReadE2PROM(0x2007); // 从EEPROM的0x2006和0x2007这两个地址读取光强的报警上限
- if((AlarmTL==0)||(AlarmTL>100)) // 如果温度下限报警值读出来异常(等于0或大于100),则重新赋值
- AlarmTL=20;
- if((AlarmTH==0)||(AlarmTH>100)) // 如果温度上限报警值读出来异常(等于0或大于100),则重新赋值
- AlarmTH=35;
- if((AlarmHL==0)||(AlarmHL>100)) // 如果温度下限报警值读出来异常(等于0或大于100),则重新赋值
- AlarmHL=40;
- if((AlarmHH==0)||(AlarmHH>100)) // 如果温度上限报警值读出来异常(等于0或大于100),则重新赋值
- AlarmHH=85;
- if((AlarmLL==0)||(AlarmLL==65535)) // 如果光照下限报警值读出来异常(等于0或等于65535),则重新赋值
- AlarmLL=50;
- if((AlarmLH==0)||(AlarmLH==65535)) // 如果光照上限报警值读出来异常(等于0或等于65535),则重新赋值
- AlarmLH=500;
- }
- /*********************************************************/
- // 主函数
- /*********************************************************/
- void main()
- {
- uchar i;
-
- LcdInit(); // 液晶功能的初始化
- LcdShowInit(); // 液晶显示的初始化
- AlarmInit(); // 报警值初始化
-
- while(1)
- {
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
环境监测系统.zip
(2.74 MB, 下载次数: 622)
|