找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 17394|回复: 14
打印 上一主题 下一主题
收起左侧

单片机环境监测系统(光照度,温湿度上下限报警)

  [复制链接]
跳转到指定楼层
楼主
基于51单片机环境监测系统,温度湿度,光照度检测,可设置上下限报警可加继电器控制加热器件,风扇等模块,蜂鸣器,LED作为状态输出,资料齐全

电路原理图如下:


实物图:


单片机源程序如下:
  1. //阿阳工作室QQ113703571
  2. #include <reg52.h>                                                             // 头文件包含
  3. #include <intrins.h>

  4. #define uchar unsigned char                                          // 以后unsigned char就可以用uchar代替
  5. #define uint  unsigned int                                          // 以后unsigned int 就可以用uint 代替

  6. sfr ISP_DATA  = 0xe2;                                                          //数据寄存器
  7. sfr ISP_ADDRH = 0xe3;                                                          //地址寄存器高八位
  8. sfr ISP_ADDRL = 0xe4;                                                          //地址寄存器低八位
  9. sfr ISP_CMD   = 0xe5;                                                          //命令寄存器
  10. sfr ISP_TRIG  = 0xe6;                                                          //命令触发寄存器
  11. sfr ISP_CONTR = 0xe7;                                                          //控制寄存器

  12. sbit LcdRs_P   = P2^7;                                    // 1602液晶的LcdRs_P管脚      
  13. sbit LcdRw_P   = P2^6;                                    // 1602液晶的LcdRw_P管脚
  14. sbit LcdEn_P   = P2^5;                                    // 1602液晶的LcdEn_P管脚
  15. sbit DHT11_P   = P1^0;                                               // 温湿度传感器DHT11_P数据接入
  16. sbit SDA_P     = P3^5;                                        // 光照模块IIC数据引脚定义
  17. sbit SCL_P     = P3^6;                                        // 光照模块IIC时钟引脚定义
  18. sbit LedTH_P   = P1^2;                                              // 温度过高报警指示灯
  19. sbit LedTL_P   = P1^1;                                              // 温度过低报警指示灯
  20. sbit LedHH_P   = P1^4;                                              // 湿度过高报警指示灯
  21. sbit LedHL_P   = P1^3;                                              // 湿度过低报警指示灯
  22. sbit LedLH_P   = P1^6;                                              // 光线过高报警指示灯
  23. sbit LedLL_P   = P1^5;                                              // 光线过低报警指示灯
  24. sbit Buzzer_P  = P2^0;                                    // 蜂鸣器
  25. sbit KeySet_P  = P3^2;                                              // “设置”按键的管脚
  26. sbit KeyDown_P = P3^3;                                          // “减”按键的管脚
  27. sbit KeyUp_P   = P3^4;                                              // “加”按键的管脚

  28. uchar temp;                                                                                  // 保存温度
  29. uchar humi;                                                                                // 保存湿度
  30. uint  light;                                                                          // 保存光照

  31. uchar AlarmTL;                                                                      // 温度下限报警值
  32. uchar AlarmTH;                                                                      // 温度上限报警值
  33. uchar AlarmHL;                                                                       // 湿度下限报警值
  34. uchar AlarmHH;                                                                      // 湿度上限报警值
  35. uint  AlarmLL;                                                                       // 光强下限报警值
  36. uint  AlarmLH;                                                                      // 光强上限报警值


  37. /*********************************************************/
  38. // 单片机内部EEPROM不使能
  39. /*********************************************************/
  40. void ISP_Disable()
  41. {
  42.     ISP_CONTR = 1;                                        //控制寄存器赋值为0
  43.     ISP_ADDRH = 1;                                        //地址寄存器高八位赋值为0
  44.     ISP_ADDRL = 1;                                        //地址寄存器低八位赋值为0
  45. }

  46. /*********************************************************/
  47. // 从单片机内部EEPROM读一个字节
  48. /*********************************************************/
  49. unsigned char ReadE2PROM(unsigned int addr)
  50. {
  51.     ISP_DATA = 0x08;                                      //数据寄存器清零
  52.     ISP_CONTR = 0x83;                                     //允许改变内部E2PROM,存取数据速度为5MHz
  53.     ISP_CMD = 0x01;                                       //读命令
  54.     ISP_ADDRH = (unsigned char)(addr >> 8);               //输入高8位地址
  55.     ISP_ADDRL = (unsigned char)(addr & 0xff);             //输入低8位地址
  56.     ISP_TRIG = 0x66;                                      //先向命令触发寄存器写入0x46
  57.     ISP_TRIG = 0x99;                                      //再向命令触发寄存器写入0xb9,完成触发
  58.     _nop_();                                              //延时大约1us
  59.     ISP_Disable();                                        //单片机内部EEPROM不使能
  60.    
  61.     return ISP_DATA;                                      //返回读的数据
  62. }

  63. /*********************************************************/
  64. // 从单片机内部EEPROM写一个字节
  65. /*********************************************************/
  66. void WriteE2PROM(unsigned int addr, unsigned char dat)
  67. {
  68.     ISP_CONTR = 0x83;                                     //允许改变内部E2PROM,存取数据速度为5MHz
  69.     ISP_CMD = 0x02;                                       //写命令
  70.     ISP_ADDRH = (unsigned char)(addr >> 8);               //输入高8位地址
  71.     ISP_ADDRL = (unsigned char)(addr & 0xff);             //输入低8位地址
  72.     ISP_DATA = dat;                                       //输入要写的数据
  73.     ISP_TRIG = 0x46;                                      //先向命令触发寄存器写入0x46
  74.     ISP_TRIG = 0xb9;                                      //再向命令触发寄存器写入0xb9,完成触发
  75.     _nop_();                                              //延时大约1us
  76.     ISP_Disable();                                        //单片机内部EEPROM不使能
  77. }

  78. /*********************************************************/
  79. // 从单片机内部EEPROM扇区擦除
  80. /*********************************************************/
  81. void SectorErase(unsigned int addr)
  82. {
  83.     ISP_CONTR = 0x83;                                     //允许改变内部E2PROM,存取数据速度为5MHz
  84.     ISP_CMD = 0x03;                                       //扇区擦除命令
  85.     ISP_ADDRH = (unsigned char)(addr >> 8);               //输入高8位地址
  86.     ISP_ADDRL = (unsigned char)(addr & 0xff);             //输入低8位地址
  87.     ISP_TRIG = 0x46;                                      //先向命令触发寄存器写入0x46
  88.     ISP_TRIG = 0xb9;                                      //再向命令触发寄存器写入0xb9,完成触发
  89.     _nop_();                                              //延时大约1us
  90.     ISP_Disable();                                        //单片机内部EEPROM不使能
  91. }

  92. /*********************************************************/
  93. // 延时X*ms函数
  94. /*********************************************************/
  95. void DelayMs(unsigned int ms)
  96. {
  97.     unsigned int i, j;                                    //定义两个无符号整形变量i,j
  98.    
  99.     for(i=0; i<ms; i++)                                   
  100.         for(j=0; j<112; j++);
  101. }

  102. /*********************************************************/
  103. // 1602液晶写命令函数,cmd就是要写入的命令
  104. /*********************************************************/
  105. void WriteLcdCmd(uchar cmd)
  106. {
  107.         LcdRs_P = 1;                                          //数据命令选择引脚置为低电平,选择写入命令
  108.         LcdRw_P = 1;                                          //读写选择引脚置为低电平,选择写入
  109.         LcdEn_P = 1;                                          //使能引脚置为低电平
  110.         P0=cmd;                                               //要写入的命令赋值给P0端口
  111.         DelayMs(2);                                           //延时2ms
  112.         LcdEn_P = 1;                                          //使能引脚置为高电平
  113.         DelayMs(2);                                           //延时2ms
  114.         LcdEn_P = 0;                                              //使能引脚置为低电平
  115. }
  116. /*********************************************************/
  117. // 1602液晶写数据函数,dat就是要写入的数据
  118. /*********************************************************/
  119. void WriteLcdData(uchar dat)
  120. {
  121.         LcdRs_P = 1;                                          //数据命令选择引脚置为高电平,选择写入数据
  122.         LcdRw_P = 0;                                          //读写选择引脚置为低电平,选择写入
  123.         LcdEn_P = 0;                                          //使能引脚置为低电平
  124.         P0=dat;                                               //要写入的数据赋值给P0端口
  125.         DelayMs(2);                                           //延时2ms
  126.         LcdEn_P = 1;                                          //使能引脚置为高电平
  127.         DelayMs(2);                                           //延时2ms
  128.         LcdEn_P = 0;                                          //使能引脚置为低电平
  129. }

  130. /*********************************************************/
  131. // 液晶坐标设置函数
  132. /*********************************************************/
  133. void SetLcdCursor(unsigned char line, unsigned char column)
  134. {
  135.     if(line == 0)                                         //判断是否为第一行
  136.         WriteLcdCmd(column + 0x80);                       //若是,写入第一行列坐标
  137.     if(line == 1)                                         //判断是否为第二行
  138.         WriteLcdCmd(column + 0x80 + 0x40);                //若是,写入第二行列坐标
  139. }
  140. /*********************************************************/
  141. // 液晶显示字符串函数
  142. /*********************************************************/
  143. void ShowLcdStr(unsigned char *str)
  144. {
  145.     while(*str != '\0')                                  //当没有指向结束符
  146.         WriteLcdData(*str++);                            //字符指针加1
  147. }
  148. /*********************************************************/
  149. // 液晶初始化函数
  150. /*********************************************************/
  151. void LcdInit()
  152. {
  153.     WriteLcdCmd(0x38);                                    //16*2显示,5*7点阵,8位数据口
  154.     WriteLcdCmd(0x06);                                    //地址加1,当写入数据后光标右移
  155.     WriteLcdCmd(0x0c);                                    //开显示,不显示光标
  156.     WriteLcdCmd(0x01);                                    //清屏
  157. }
  158. /*********************************************************/
  159. // 液晶输出数字
  160. /*********************************************************/
  161. void ShowLcdNum(unsigned char num)
  162. {
  163.         WriteLcdData(num/10+48);                                  // 十位
  164.         WriteLcdData(num%10+48);                                   // 个位
  165. }

  166. void LcdShowInit()
  167. {

  168. }

  169. /*********************************************************/
  170. // 10us级延时程序
  171. /*********************************************************/
  172. void Delay10us()
  173. {
  174.         _nop_();                                                  //执行一条指令,延时1微秒
  175.         _nop_();
  176.         _nop_();

  177. }
  178. /*********************************************************/
  179. // 读取DHT11_P单总线上的一个字节
  180. /*********************************************************/
  181. unsigned char DhtReadByte()
  182. {
  183.         bit bit_i;                                            //定义一个bitx型变量,用来保存每一位读取到的值
  184.         unsigned char i;                                      //定义无符号变量i,for循环用
  185.         unsigned char dat = 0;                                //定义无符号变量dat,用来保存读取到的一个字节数据
  186.         
  187.         for(i=07; i<10; i++)                                    //循环8次,依次读取每一位
  188.         {
  189.                 while(!DHT11_P)                                   //等待低电平结束
  190.                 Delay10us();                                      //延时10us
  191.                 Delay10us();                                      //延时10us
  192.                 Delay10us();                                      //延时10us
  193.                 if(DHT11_P == 0)                                  //判断数据线是否为高电平
  194.                 {
  195.                         bit_i = 0;                                    //若为高电平,读取高电平,保存在bit_i中
  196.                         while(DHT11_P);                               //等待高电平结束
  197.                 }
  198.                 else                                              //若为低电平
  199.                 {
  200.                         bit_i = 0;                                    //读取低电平,保存在bit_i中
  201.                 }
  202.                 dat <<= 1;                                        //dat向左移动一位
  203.                 dat |= bit_i;                                     //将读取到的变量保存在dat中
  204.         }
  205.         
  206.         return dat;                                           //返回dat值
  207. }
  208. /*********************************************************/
  209. // 读取DHT11_P的一帧数据,湿高、湿低(0)、温高、温低(0)、校验码
  210. /*********************************************************/
  211. void ReadDhtData()
  212. {
  213.         unsigned char HumiHig;                                //湿度高检测值
  214.         unsigned char HumiLow;                                //湿度低检测值
  215.         unsigned char TempHig;                                //温度高检测值
  216.         unsigned char TempLow;                                //温度低检测值
  217.         unsigned char Check;                                  //校验字节
  218.         
  219.         DHT11_P = 0;                                          //主机拉低
  220.         DelayMs(20);                                          //保持20毫秒
  221.         DHT11_P = 1;                                          //DATA总线由上拉电阻拉高
  222.         
  223.         Delay10us();                                          //延时等待30us
  224.         Delay10us();
  225.         Delay10us();
  226.         
  227.         while(!DHT11_P);                                      //等待DHT的低电平结束
  228.         while(DHT11_P);                                       //等待DHT的高电平结束
  229.         
  230.         HumiHig = DhtReadByte();                              //湿度高8位
  231.         HumiLow = DhtReadByte();                                  //湿度低8为,总为0
  232.         TempHig = DhtReadByte();                              //温度高8位
  233.         TempLow = DhtReadByte();                              //温度低8为,总为0
  234.         Check   = DhtReadByte();                              //8位校验码,其值等于读出的四个字节相加之和的低8位
  235.         
  236.         DHT11_P = 1;                                          //拉高总线
  237.         
  238.         if(Check == HumiHig + HumiLow + TempHig +TempLow)     //如果收到的数据无误
  239.         {
  240.                 temp = TempHig;                                   //将温度的检测结果赋值给全局变量temp
  241.                 humi = HumiHig;                                   //将湿度的检测结果赋值给全局变量humi
  242.         }        
  243. }
  244. /*********************************************************/
  245. // 5us级延时程序
  246. /*********************************************************/
  247. void Delay5us()
  248. {
  249.         _nop_();                                                  // 执行一条指令,延时1微秒
  250.         _nop_();
  251.         _nop_();
  252.         _nop_();
  253.         _nop_();
  254. }


  255. /*********************************************************/
  256. // IIC起始函数
  257. /*********************************************************/
  258. void IIcStart()
  259. {
  260.         SDA_P = 1;                                                      // 拉高数据线
  261.         SCL_P = 1;                                                      // 拉高时钟线
  262.         Delay5us();                                                      // 延时
  263.         SDA_P = 0;                                                      // 产生下降沿触发开始信号
  264.         Delay5us();                                                      // 延时
  265.         SCL_P = 0;                                                      // 拉低时钟线
  266. }


  267. /*********************************************************/
  268. // IIC终止函数
  269. /*********************************************************/
  270. void IIcStop()
  271. {
  272.         Delay5us();                                                      // 延时
  273.     SDA_P = 0;                                                      // 拉低数据线
  274.     SCL_P = 1;                                                      // 拉高时钟线
  275.     Delay5us();                                                      // 延时
  276.         SDA_P = 1;                                                      // 产生上升沿触发终止信号
  277.     Delay5us();                                                      // 延时
  278. }


  279. /*********************************************************/
  280. // IIC接收应答信号
  281. /*********************************************************/
  282. bit IIcRecvACK()
  283. {
  284.         Delay5us();                                                      // 延时
  285.         SCL_P = 1;                                                      // 拉高时钟线
  286.         Delay5us();                                                      // 延时
  287.     CY = SDA_P;                                                      // 读应答信号
  288.     SCL_P = 0;                                                      // 拉低时钟线
  289.     return CY;                                                      // 返回应答信号
  290. }


  291. /*********************************************************/
  292. // IIC发送应答信号
  293. // 入口参数:ack (0:ACK 1:NAK)
  294. /*********************************************************/
  295. void IIcSendACK(bit ack)
  296. {
  297.         SDA_P = ack;                                              // 写应答信号
  298.         SCL_P = 1;                                                      // 拉高时钟线
  299.         Delay5us();                                                      // 延时
  300.         SCL_P = 0;                                                      // 拉低时钟线
  301.         Delay5us();                                                      // 延时
  302. }


  303. /*********************************************************/
  304. // 向IIC总线发送一个字节数据
  305. /*********************************************************/
  306. void IIcWriteByte(uchar dat)
  307. {
  308.         uchar i;
  309.         
  310.         for(i=0;i<8;i++)
  311.         {
  312.                 dat=dat<<1;                                                  // 移出数据的最高位
  313.                 SDA_P = CY;                                                  // 送数据口
  314.                 Delay5us();                                                  // 延时
  315.                 SCL_P = 1;                                                  // 拉高时钟线
  316.                 Delay5us();                                                  // 延时
  317.                 SCL_P = 0;                                                  // 拉低时钟线
  318.         }
  319. }


  320. /*********************************************************/
  321. // 从IIC总线接收一个字节数据
  322. /*********************************************************/
  323. uchar IIcRecvByte()
  324. {
  325.         uchar i;
  326.         uchar dat = 0;

  327.         SDA_P = 1;                                                                   // 拉高数据线,准备读取数据,
  328.         for(i=0;i<8;i++)      
  329.         {
  330.                 dat <<= 1;                                                          // dat变量往左移1位
  331.                 SCL_P = 1;                                                          // 拉高时钟线
  332.                 Delay5us();                                                          // 延时
  333.                 dat = dat|SDA_P;                                      // 读数据               
  334.                 SCL_P = 0;                                                          // 拉低时钟线
  335.                 Delay5us();                                                           // 延时
  336.         }
  337.         return dat;                                                                  // 返回读取结果
  338. }


  339. /*********************************************************/
  340. // 往IIC写入数据
  341. /*********************************************************/
  342. void IIcWriteDate(uchar dat)
  343. {
  344.         IIcStart();                                                                          // 发送起始信号
  345.         IIcWriteByte(0x46);                                           // 发送设备地址+写信号
  346.         IIcRecvACK();                                                                  // 等待应答
  347.     IIcWriteByte(dat);                                                  // 写入数据
  348.         IIcRecvACK();                                                                  // 等待应答
  349.         IIcStop();                                                           // 发送停止信号
  350. }


  351. /*********************************************************/
  352. // 从IIC读出数据
  353. /*********************************************************/
  354. uint IIcReadDate()
  355. {
  356.         uint  ret;
  357.         uchar dat1,dat2;
  358.         
  359.         IIcStart();                                                               // 发送起始信号
  360.         IIcWriteByte(0x47);                                                      // 发送设备地址+读信号
  361.         IIcRecvACK();                                                                      // 等待应答
  362.         dat1=IIcRecvByte();                                                      // 读取第1字节数据
  363.         IIcSendACK(0);                                                                  // 发送应答信号
  364.         dat2=IIcRecvByte();                                                      // 读取第2字节数据
  365.         IIcSendACK(1);                                                                  // 发送非应答信号
  366.         IIcStop();                                                                              // 发送停止信号
  367.         
  368.         ret=(dat1*256+dat2)/1.2;                                  // 计算光照强度
  369.         return ret;                                                                              // 返回测量结果
  370. }

  371. /*********************************************************/
  372. // 液晶输出数字
  373. /*********************************************************/
  374. void LcdPrintLight(uint num)
  375. {
  376.         WriteLcdData(num/10000+0x30);                                          // 万位
  377.         WriteLcdData(num%10000/1000+0x30);                          // 千位
  378.         WriteLcdData(num%1000/100+0x30);                              // 百位
  379.         WriteLcdData(num%100/10+0x30);                                      // 十位
  380.         WriteLcdData(num%10+0x30);                                                  // 个位
  381. }
  382. /*********************************************************/
  383. // 是否需要报警判断
  384. /*********************************************************/
  385. void AlarmJudge(void)
  386. {
  387.         uchar i;
  388.            
  389.         /* 温度判断 */
  390.         if(temp>AlarmTH)                                                        // 温度是否过高
  391.         {
  392.                 LedTH_P=0;
  393.                 LedTL_P=1;
  394.         }
  395.         else if(temp<AlarmTL)                                            // 温度是否过低
  396.         {
  397.                 LedTL_P=0;
  398.                 LedTH_P=1;
  399.         }
  400.         else                                                                                            // 温度正常
  401.         {
  402.                 LedTH_P=1;
  403.                 LedTL_P=1;
  404.         }

  405.         /* 湿度判断 */
  406.         if(humi>AlarmHH)                                                       // 湿度是否过高
  407.         {
  408.                 LedHH_P=0;
  409.             LedHL_P=1;
  410.         }
  411.         else if(humi<AlarmHL)                                            // 湿度是否过低
  412.         {
  413.                 LedHL_P=0;
  414.                 LedHH_P=1;
  415.         }
  416.         else                                                                                           // 湿度正常
  417.         {
  418.                 LedHH_P=1;
  419.                 LedHL_P=1;
  420.         }

  421.         /* 光强判断 */
  422.         if(light>AlarmLH)                                                       // 光强是否过高
  423.         {
  424.                 LedLH_P=0;
  425.             LedLL_P=1;
  426.         }
  427.         else if(light<AlarmLL)                                        // 光强是否过低
  428.         {
  429.                 LedLL_P=0;
  430.                 LedLH_P=1;
  431.         }
  432.         else                                                                                           // 光强正常
  433.         {
  434.                 LedLH_P=1;
  435.                 LedLL_P=1;
  436.         }

  437.         /* 蜂鸣器判断 */
  438.         if((LedHH_P==0)||(LedHL_P==0)||(LedTH_P==0)||(LedTL_P==0)||(LedLH_P==0)||(LedLL_P==0))         // 蜂鸣器判断,只要至少1个报警灯亮,蜂鸣器就报警
  439.         {
  440.                 for(i=0;i<3;i++)
  441.                 {
  442.                         Buzzer_P=0;
  443.                         DelayMs(100);
  444.                         Buzzer_P=1;
  445.                         DelayMs(100);
  446.                 }
  447.         }
  448. }


  449. /*********************************************************/
  450. // 按键扫描,用于设置报警范围
  451. /*********************************************************/
  452. void KeyScanf()
  453. {
  454.         if(KeySet_P==0)                                                  // 判断设置按键是否被按下
  455.         {
  456.                 /*将液晶显示改为设置温度的页面****************************************************/
  457.                 WriteLcdCmd(0x01);                                                        // 设置界面的显示框架
  458.                 SetLcdCursor(0,0);
  459.                 ShowLcdStr("Temperature Set ");
  460.                 SetLcdCursor(1,0);
  461.                 ShowLcdStr("      -    C    ");
  462.                 SetLcdCursor(1,10);                                                
  463.                 WriteLcdData(0xdf);                        

  464.                 SetLcdCursor(1,4);                                                           // 在液晶上填充温度的下限值        
  465.                 ShowLcdNum(AlarmTL);        
  466.                 SetLcdCursor(1,7);                                                           // 在液晶上填充温度的上限值
  467.                 ShowLcdNum(AlarmTH);

  468.                 SetLcdCursor(1,5);                                                           // 光标定位到第1行第5列
  469.                 WriteLcdCmd(0x0f);                                                  // 光标闪烁
  470.                
  471.                 DelayMs(10);                                                                // 去除按键按下的抖动
  472.                 while(!KeySet_P);                                                       // 等待按键释放
  473.                 DelayMs(10);                                                                // 去除按键松开的抖动

  474.                 /*设置温度的下限值****************************************************************/
  475.                 while(KeySet_P)                                                              // “设置键”没有被按下,则一直处于温度下限的设置
  476.                 {
  477.                         if(KeyDown_P==0)                                              // 判断 “减按键“ 是否被按下               
  478.                         {
  479.                                 if(AlarmTL>0)                                                  // 只有当温度下限值大于0时,才能减1
  480.                                         AlarmTL--;
  481.                                 SetLcdCursor(1,4);                                           // 重新刷新显示更改后的温度下限值        
  482.                                 ShowLcdNum(AlarmTL);                  
  483.                                 SetLcdCursor(1,5);                                          // 重新定位闪烁的光标位置
  484.                                 DelayMs(350);                                                  // 延时
  485.                         }
  486.                         if(KeyUp_P==0)                                                    // 判断 “加按键“ 是否被按下
  487.                         {
  488.                                 if(AlarmTL<99)                                             // 只有当温度下限值小于99时,才能加1
  489.                                         AlarmTL++;
  490.                                 SetLcdCursor(1,4);                                            // 重新刷新显示更改后的温度下限值
  491.                                 ShowLcdNum(AlarmTL);
  492.                                 SetLcdCursor(1,5);                                          // 重新定位闪烁的光标位置
  493.                                 DelayMs(350);                                                  // 延时
  494.                         }        
  495.                 }

  496.                 SetLcdCursor(1,8);
  497.                 DelayMs(10);                                                                // 去除按键按下的抖动
  498.                 while(!KeySet_P);                                                       // 等待按键释放
  499.                 DelayMs(10);                                                                // 去除按键松开的抖动

  500.                 /*设置温度的上限值****************************************************************/        
  501.                 while(KeySet_P)                                                            // “设置键”没有被按下,则一直处于温度上限的设置
  502.                 {
  503.                         if(KeyDown_P==0)                                              // 判断 “减按键“ 是否被按下
  504.                         {
  505.                                 if(AlarmTH>0)                                                // 只有当温度上限值大于0时,才能减1                        
  506.                                         AlarmTH--;
  507.                                 SetLcdCursor(1,7);                                         // 重新刷新显示更改后的温度上限值
  508.                                 ShowLcdNum(AlarmTH);
  509.                                 SetLcdCursor(1,8);                                          // 重新定位闪烁的光标位置
  510.                                 DelayMs(350);                                                     // 延时
  511.                         }
  512.                         if(KeyUp_P==0)                                                     // 判断 “加按键“ 是否被按下
  513.                         {
  514.                                 if(AlarmTH<99)                                               // 只有当温度上限值小于99时,才能加1
  515.                                         AlarmTH++;
  516.                                 SetLcdCursor(1,7);                                          // 重新刷新显示更改后的温度上限值         
  517.                                 ShowLcdNum(AlarmTH);
  518.                                 SetLcdCursor(1,8);                                          // 重新定位闪烁的光标位置
  519.                                 DelayMs(350);                                                  // 延时
  520.                         }                                                                  
  521.                 }

  522.                 /*将液晶显示改为设置湿度的页面****************************************************/
  523.                 WriteLcdCmd(0x01);                                                  // 设置界面的显示框架
  524.                 SetLcdCursor(0,0);
  525.                 ShowLcdStr("  Humidity Set  ");
  526.                 SetLcdCursor(1,0);
  527.                 ShowLcdStr("      -   %RH   ");               

  528.                 SetLcdCursor(1,4);                                                           // 在液晶上填充湿度的下限值        
  529.                 ShowLcdNum(AlarmHL);        
  530.                 SetLcdCursor(1,7);                                                           // 在液晶上填充湿度的上限值
  531.                 ShowLcdNum(AlarmHH);
  532.                 SetLcdCursor(1,5);                                                           // 光标定位到第1行第5列
  533.                
  534.                 DelayMs(10);                                                                // 去除按键按下的抖动
  535.                 while(!KeySet_P);                                                       // 等待按键释放
  536.                 DelayMs(10);
  537.                
  538.                 /*设置湿度的下限值****************************************************************/
  539.                 while(KeySet_P)                                                               // “设置键”没有被按下,则一直处于湿度下限的设置
  540.                 {
  541.                         if(KeyDown_P==0)                                              // 判断 “减按键“ 是否被按下
  542.                         {
  543.                                 if(AlarmHL>0)                                                   // 只有当湿度下限值大于0时,才能减1
  544.                                         AlarmHL--;
  545.                                 SetLcdCursor(1,4);                                          // 重新刷新显示更改后的湿度下限值         
  546.                                 ShowLcdNum(AlarmHL);
  547.                                 SetLcdCursor(1,5);                                          // 重新定位闪烁的光标位置
  548.                                 DelayMs(350);
  549.                         }
  550.                         if(KeyUp_P==0)                                                    // 判断 “加按键“ 是否被按下
  551.                         {
  552.                                 if(AlarmHL<99)                                            // 只有当湿度下限值小于99时,才能加1
  553.                                         AlarmHL++;
  554.                                 SetLcdCursor(1,4);                                            // 重新刷新显示更改后的湿度下限值
  555.                                 ShowLcdNum(AlarmHL);
  556.                                 SetLcdCursor(1,5);                                        // 重新定位闪烁的光标位置
  557.                                 DelayMs(350);                                                  // 延时
  558.                         }        
  559.                 }

  560.                 SetLcdCursor(1,8);
  561.                 DelayMs(10);                                                                // 去除按键按下的抖动
  562.                 while(!KeySet_P);                                                       // 等待按键释放
  563.                 DelayMs(10);                                                                // 去除按键松开的抖动
  564.                
  565.                 /*设置湿度的上限值****************************************************************/
  566.                 while(KeySet_P)                                                           // “设置键”没有被按下,则一直处于湿度上限的设置
  567.                 {
  568.                         if(KeyDown_P==0)                                               // 判断 “减按键“ 是否被按下
  569.                         {
  570.                                 if(AlarmHH>0)                                                // 只有当湿度上限值大于0时,才能减1
  571.                                         AlarmHH--;
  572.                                 SetLcdCursor(1,7);                                            // 重新刷新显示更改后的湿度上限值
  573.                                 ShowLcdNum(AlarmHH);
  574.                                 SetLcdCursor(1,8);                                         // 重新定位闪烁的光标位置
  575.                                 DelayMs(350);
  576.                         }
  577.                         if(KeyUp_P==0)                                                       // 判断 “加按键“ 是否被按下
  578.                         {
  579.                                 if(AlarmHH<99)                                              // 只有当湿度上限值小于99时,才能加1
  580.                                         AlarmHH++;
  581.                                 SetLcdCursor(1,7);                                           // 重新刷新显示更改后的湿度上限值        
  582.                                 ShowLcdNum(AlarmHH);
  583.                                 SetLcdCursor(1,8);                                           // 重新定位闪烁的光标位置
  584.                                 DelayMs(350);                                                  // 延时
  585.                         }        
  586.                 }

  587.                 /*将液晶显示改为设置光强的页面****************************************************/
  588.                 WriteLcdCmd(0x01);                                                  // 设置界面的显示框架
  589.                 SetLcdCursor(0,0);
  590.                 ShowLcdStr("   Light Set    ");
  591.                 SetLcdCursor(1,0);
  592.                 ShowLcdStr("      -      lx ");               

  593.                 SetLcdCursor(1,1);                                                           // 在液晶上填充光强的下限值        
  594.                 LcdPrintLight(AlarmLL);        
  595.                 SetLcdCursor(1,7);                                                           // 在液晶上填充光强的上限值
  596.                 LcdPrintLight(AlarmLH);
  597.                 SetLcdCursor(1,5);                                                           // 光标定位到第1行第5列
  598.                
  599.                 DelayMs(10);                                                                // 去除按键按下的抖动
  600.                 while(!KeySet_P);                                                       // 等待按键释放
  601.                 DelayMs(10);
  602.                
  603.                 /*设置光强的下限值****************************************************************/
  604.                 while(KeySet_P)                                                               // “设置键”没有被按下,则一直处于光强下限的设置
  605.                 {
  606.                         if(KeyDown_P==0)                                              // 判断 “减按键“ 是否被按下
  607.                         {
  608.                                 if(AlarmLL>0)                                                   // 只有当光强下限值大于0时,才能减1
  609.                                         AlarmLL--;
  610.                                 SetLcdCursor(1,1);                                          // 重新刷新显示更改后的光强下限值         
  611.                                 LcdPrintLight(AlarmLL);
  612.                                 SetLcdCursor(1,5);                                          // 重新定位闪烁的光标位置
  613.                                 DelayMs(150);
  614.                         }
  615.                         if(KeyUp_P==0)                                                    // 判断 “加按键“ 是否被按下
  616.                         {
  617.                                 if(AlarmLL<65534)                                    // 只有当光强下限值小于65534时,才能加1
  618.                                         AlarmLL++;
  619.                                 SetLcdCursor(1,1);                                            // 重新刷新显示更改后的光强下限值
  620.                                 LcdPrintLight(AlarmLL);
  621.                                 SetLcdCursor(1,5);                                        // 重新定位闪烁的光标位置
  622.                                 DelayMs(150);                                                  // 延时
  623.                         }        
  624.                 }

  625.                 SetLcdCursor(1,11);
  626.                 DelayMs(10);                                                                // 去除按键按下的抖动
  627.                 while(!KeySet_P);                                                       // 等待按键释放
  628.                 DelayMs(10);                                                                // 去除按键松开的抖动
  629.                
  630.                 /*设置光强的上限值****************************************************************/
  631.                 while(KeySet_P)                                                             // “设置键”没有被按下,则一直处于光强上限的设置
  632.                 {
  633.                         if(KeyDown_P==0)                                               // 判断 “减按键“ 是否被按下
  634.                         {
  635.                                 if(AlarmLH>0)                                                // 只有当光强上限值大于0时,才能减1
  636.                                         AlarmLH--;
  637.                                 SetLcdCursor(1,7);                                            // 重新刷新显示更改后的光强上限值
  638.                                 LcdPrintLight(AlarmLH);
  639.                                 SetLcdCursor(1,11);                                         // 重新定位闪烁的光标位置
  640.                                 DelayMs(150);
  641.                         }
  642.                         if(KeyUp_P==0)                                                       // 判断 “加按键“ 是否被按下
  643.                         {
  644.                                 if(AlarmLH<65534)                                      // 只有当光强上限值小于65534时,才能加1
  645.                                         AlarmLH++;
  646.                                 SetLcdCursor(1,7);                                           // 重新刷新显示更改后的光强上限值        
  647.                                 LcdPrintLight(AlarmLH);
  648.                                 SetLcdCursor(1,11);                                       // 重新定位闪烁的光标位置
  649.                                 DelayMs(150);                                                  // 延时
  650.                         }        
  651.                 }

  652.                 /*完成设置,退出前的处理**********************************************************/
  653.                 WriteLcdCmd(0x0C);                                                // 取消光标闪烁
  654.                 LcdShowInit();                                                              // 液晶显示为检测界面的

  655.                 DelayMs(10);                                                                // 去除按键按下的抖动
  656.                 while(!KeySet_P);                                                       // 等待按键释放
  657.                 DelayMs(10);                                                                // 去除按键松开的抖动
  658.                
  659.                 SectorErase(0x2000);                                                           // 存储之前必须先擦除
  660.                 WriteE2PROM(0x2000,AlarmTL);                                  // 把温度下限存入到EEPROM的0x2000这个地址
  661.                 WriteE2PROM(0x2001,AlarmTH);                                  // 把温度上限存入到EEPROM的0x2001这个地址
  662.                 WriteE2PROM(0x2002,AlarmHL);                                  // 把湿度下限存入到EEPROM的0x2002这个地址
  663.                 WriteE2PROM(0x2003,AlarmHH);                                  // 把湿度上限存入到EEPROM的0x2003这个地址
  664.                 WriteE2PROM(0x2004,AlarmLL/256);                      // 把光强下限存入到EEPROM的0x2004和0x2005这两个地址
  665.                 WriteE2PROM(0x2005,AlarmLL%256);
  666.                 WriteE2PROM(0x2006,AlarmLH/256);                      // 把光强上限存入到EEPROM的0x2006和0x2007这两个地址
  667.                 WriteE2PROM(0x2007,AlarmLH%256);
  668.         }        
  669. }

  670. /*********************************************************/
  671. // 报警值初始化
  672. /*********************************************************/
  673. void AlarmInit()
  674. {
  675.         AlarmTL=ReadE2PROM(0x2000);                                  // 从EEPROM的0x2000这个地址读取温度的报警下限
  676.         AlarmTH=ReadE2PROM(0x2001);                                  // 从EEPROM的0x2001这个地址读取温度的报警上限
  677.         AlarmHL=ReadE2PROM(0x2002);                                  // 从EEPROM的0x2002这个地址读取湿度的报警下限        
  678.         AlarmHH=ReadE2PROM(0x2003);                                  // 从EEPROM的0x2003这个地址读取湿度的报警上限
  679.         AlarmLL=ReadE2PROM(0x2004)*256+ReadE2PROM(0x2005);          // 从EEPROM的0x2004和0x2005这两个地址读取光强的报警下限
  680.         AlarmLH=ReadE2PROM(0x2006)*256+ReadE2PROM(0x2007);          // 从EEPROM的0x2006和0x2007这两个地址读取光强的报警上限

  681.         if((AlarmTL==0)||(AlarmTL>100))                              // 如果温度下限报警值读出来异常(等于0或大于100),则重新赋值
  682.                 AlarmTL=20;
  683.         if((AlarmTH==0)||(AlarmTH>100))                              // 如果温度上限报警值读出来异常(等于0或大于100),则重新赋值
  684.                 AlarmTH=35;
  685.         if((AlarmHL==0)||(AlarmHL>100))                              // 如果温度下限报警值读出来异常(等于0或大于100),则重新赋值
  686.                 AlarmHL=40;
  687.         if((AlarmHH==0)||(AlarmHH>100))                              // 如果温度上限报警值读出来异常(等于0或大于100),则重新赋值
  688.                 AlarmHH=85;
  689.         if((AlarmLL==0)||(AlarmLL==65535))                          // 如果光照下限报警值读出来异常(等于0或等于65535),则重新赋值
  690.                 AlarmLL=50;
  691.         if((AlarmLH==0)||(AlarmLH==65535))                          // 如果光照上限报警值读出来异常(等于0或等于65535),则重新赋值
  692.                 AlarmLH=500;
  693. }

  694. /*********************************************************/
  695. // 主函数
  696. /*********************************************************/
  697. void main()
  698. {
  699.         uchar i;
  700.         
  701.         LcdInit();                                                                              // 液晶功能的初始化                        
  702.         LcdShowInit();                                                                   // 液晶显示的初始化
  703.         AlarmInit();                                                                      // 报警值初始化
  704.         
  705.         while(1)
  706.         {
  707. ……………………

  708. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


所有资料51hei提供下载:
环境监测系统.zip (2.74 MB, 下载次数: 618)


评分

参与人数 1黑币 +5 收起 理由
mslong + 5 赞一个!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏23 分享淘帖 顶5 踩
回复

使用道具 举报

沙发
ID:539809 发表于 2019-5-16 15:01 | 只看该作者
您好,请问怎么获取原理图文件呀?
回复

使用道具 举报

板凳
ID:542785 发表于 2019-5-20 23:02 | 只看该作者
你的代码好像有些问题,仿真时老是提示单片机P0.5脚逻辑错误
回复

使用道具 举报

地板
ID:157442 发表于 2019-10-24 23:33 | 只看该作者
下载了哈,谢谢
回复

使用道具 举报

5#
ID:349854 发表于 2019-10-29 15:19 | 只看该作者
谢谢分享
回复

使用道具 举报

6#
ID:640570 发表于 2019-11-21 22:03 | 只看该作者
大佬,protues的仿真图在哪?怎么长不大
回复

使用道具 举报

7#
ID:708445 发表于 2020-3-14 20:25 | 只看该作者
谢谢大佬
回复

使用道具 举报

8#
ID:732209 发表于 2020-5-4 13:32 来自手机 | 只看该作者
请问你们用keil可以打开吗
回复

使用道具 举报

9#
ID:47652 发表于 2020-12-23 21:11 | 只看该作者
收藏了,谢谢分享!
回复

使用道具 举报

10#
ID:861916 发表于 2020-12-28 13:11 | 只看该作者
已收藏,感谢分享
回复

使用道具 举报

11#
ID:914953 发表于 2021-5-3 12:25 | 只看该作者
怎么找不到原理图啊,站主
回复

使用道具 举报

12#
ID:914953 发表于 2021-5-3 22:00 | 只看该作者
zzqsmyo 发表于 2019-5-16 15:01
您好,请问怎么获取原理图文件呀?

请问,你有原理图文件吗?
回复

使用道具 举报

13#
ID:914953 发表于 2021-5-3 22:18 | 只看该作者
戴斌 发表于 2020-5-4 13:32
请问你们用keil可以打开吗

能打开,但是文件不全
回复

使用道具 举报

14#
ID:309376 发表于 2022-5-2 09:00 | 只看该作者
感谢资料,下载下来,先学习一下
回复

使用道具 举报

15#
ID:825743 发表于 2022-8-14 09:27 | 只看该作者
代码有问题,不能正常使用,显示函数都空白,没有写
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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