找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于单片机的温湿度监测与控制系统程序设计

[复制链接]
跳转到指定楼层
楼主
ID:354434 发表于 2018-6-19 16:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我们这个系统主要用来采集温室内的温湿度信息,及时的反映出温湿度的变化,以便及时的对温室内的温湿度做出调整,保证一个良好的温湿度环境。在超过温度上下限范围时通过多种控制方式来实现温度的上升或者下降,从而保证在一定范围内的温度。对于湿度的控制也是同样的道理。将系统应用到温室中来控制温室内的一个温湿度,无疑为温室内植被生长提供了更加适宜的温湿度环境。有些植被必须在某些特定环境下才可以生长的很好,这样的情况下安装温湿度装置对其进行监控就是非常有必要的。像温室大棚种植蔬菜、水果、花卉等,我们能够用单片机来实现对温室的一个控制,显而易见会给我们带来很大的一个方便。
我们设计的这个系统可以及时、精确地反映温室内的温度以及湿度的变化,保证温室内温湿度的控制要求。温室温湿监控制系统的设计是一个对实际生产生活非常实用,可行性很高的一个设计,对学生在单片机知识的运用上也是非常好的锻炼课题。
  1. /*主程序*/
  2. #include<reg52.h>
  3. #include"ds1302.h"
  4. #include"12864.h"
  5. #include"DHT11.h"
  6. #include"define.h"
  7. unsigned char TempData[8];
  8. void dis_time()         //向12864写时钟数据//
  9. {
  10.      lcd_pos(0,1);
  11.          write_date(TempData[1]/10+0x30);
  12.          write_date(TempData[1]%10+0x30);
  13.          lcd_pos(0,3);
  14.          write_date(TempData[2]/10+0x30);
  15.          write_date(TempData[2]%10+0x30);
  16.          lcd_pos(0,5);
  17.          write_date(TempData[3]/10+0x30);
  18.          write_date(TempData[3]%10+0x30);
  19.          lcd_pos(1,1);
  20.          write_date(TempData[7]%10+0x30);
  21.          lcd_pos(1,2);
  22.          write_date(TempData[4]/10+0x30);
  23.          write_date(TempData[4]%10+0x30);
  24.          lcd_pos(1,4);
  25.          write_date(TempData[5]/10+0x30);
  26.          write_date(TempData[5]%10+0x30);
  27.          lcd_pos(1,6);
  28.          write_date(TempData[6]/10+0x30);
  29.          write_date(TempData[6]%10+0x30);
  30. }
  31. bit SetFlag;      //更新时间标志位
  32. unsigned char time_buf2[16];
  33. void UART_Init(void)
  34. {
  35.     SCON  = 0x50;                /* SCON: 模式 1, 8-bit UART, 使能接收*/
  36.     TMOD |= 0x20;        /* TMOD: timer 1, mode 2, 8-bit reload  */
  37.     TH1   = 0xFD;       /* TH1:  reload value for 9600 baud @ 11.0592MHz */
  38.     TR1   = 1;           /* TR1:  timer 1 run   */
  39.     EA    = 1;                  /*打开总中断*/
  40.     ES    = 1;                  /*打开串口中断*/
  41. }
  42. main()
  43. {
  44.   unsigned char i;
  45.        UART_Init();               
  46.        ds1302_init(); /*DS302初始化函数*/
  47.        //ds1302_write_time();
  48.        lcd_init();    //初始化LCD
  49.        delay(15);   //延时用于稳定功能
  50.            dht11_receive();
  51.            set_kongzhi();
  52.        while(1)
  53.        {
  54.                 dht11_receive();
  55.                 kongzhi();
  56.             ds1302_read_time();//读取时钟信息
  57.         for(i=1;i<8;i++)
  58.                    TempData[i]=time_buf1[i];
  59.            dis_time();         //液晶显示时间信息
  60.            //KeyPro();
  61.                    if(SetFlag)     //如果接收到串口信息则更新时钟
  62.                      {
  63.                          for(i=0;i<8;i++)
  64.                          {
  65. time_buf1[i]=time_buf2[2*i]*10+time_buf2[2*i+1];//数据整合,如2个数 1和5整合成15
  66.                          }
  67.                          ds1302_write_time(); SetFlag=0; //时钟信息更新后标志位清零
  68.                          }
  69.              }
  70.    }
  71. /******************************************************************/
  72. /*                  串口中断程序                                  */
  73. /******************************************************************/
  74. void UART_SER (void) interrupt 4 //串行中断服务程序
  75. {
  76.     unsigned char Temp;          //定义临时变量
  77.     unsigned char i;
  78.    if(RI)                        //判断是接收中断产生
  79.      {
  80.           RI=0;                      //标志位清零
  81.           Temp=SBUF;                 //读入缓冲区的值
  82.           time_buf2[i]=Temp&0x0F;          i++;
  83.           if(i==16)                  //连续接收16个字符信息
  84.            {
  85.             i=0;SetFlag=1;               //接收完成标志位置1
  86.            }
  87.       SBUF=Temp; //把接收到的值再发回电脑端
  88.           //P1=Temp&0x0F; //调试时候显示
  89.          }
  90.    if(TI)  //如果是发送标志位,清零
  91.      TI=0;
  92. }
  93. /*初始化*/
  94. #ifndef _define_H
  95. #define        _define_H
  96. #define uchar unsigned char
  97. #define uint  unsigned int
  98. sbit speaker=P2^7; //蜂鸣器
  99. sbit ji1=P2^0; //继电器1
  100. sbit ji2=P2^1; //继电器2
  101. sbit ji3=P2^2;  //继电器3
  102. sbit ji4=P2^3; //继电器4
  103. uchar shuzhi[2]={0};       //存储 输入键值
  104. #endif
  105. /*--------------------------------------------------------------------------
  106. REG52.H    STC89C52单片机系统初始化
  107. --------------------------------------------------------------------------*/
  108. #ifndef __REG52_H__
  109. #define __REG52_H__
  110. /*  BYTE Registers  */
  111. sfr P0 = 0x80;sfr P1= 0x90;sfr P2= 0xA0;sfr P3= 0xB0;sfr PSW= 0xD0;
  112. sfr ACC= 0xE0;sfr B= 0xF0;sfr SP = 0x81;sfr DPL= 0x82;sfr DPH= 0x83;
  113. sfr PCON= 0x87;sfr TCON= 0x88;sfr TMOD= 0x89;sfr TL0= 0x8A;
  114. sfr TL1= 0x8B;sfr TH0= 0x8C;sfr TH1= 0x8D;sfr IE= 0xA8;sfr IP= 0xB8;
  115. sfr SCON= 0x98;sfr SBUF= 0x99;
  116. /*  8052 Extensions  */
  117. sfr T2CON= 0xC8;sfr RCAP2L = 0xCA;sfr RCAP2H = 0xCB;
  118. sfr TL2= 0xCC;sfr TH2= 0xCD;
  119. /*  BIT Registers  */
  120. /*  PSW  */
  121. sbit CY = PSW^7;sbit AC= PSW^6;sbit F0= PSW^5;sbit RS1= PSW^4;
  122. sbit RS0= PSW^3;sbit OV= PSW^2;sbit P= PSW^0; //8052 only
  123. /*  TCON  */
  124. sbit TF1= TCON^7;sbit TR1 = TCON^6;sbit TF0= TCON^5;sbit TR0= TCON^4;
  125. sbit IE1= TCON^3;sbit IT1 = TCON^2;sbit IE0= TCON^1;sbit IT0= TCON^0;
  126. /*  IE  */
  127. sbit EA = IE^7;sbit ET2= IE^5; //8052 onlysbit ES= IE^4;sbit ET1 = IE^3;
  128. sbit EX1= IE^2;sbit ET0 = IE^1;sbit EX0= IE^0;
  129. /*  IP  */
  130. sbit PT2 = IP^5;sbit PS= IP^4;sbit PT1= IP^3;sbit PX1= IP^2;
  131. sbit PT0 = IP^1;sbit PX0= IP^0;
  132. /*  P3  */
  133. sbit RD= P3^7;sbit WR= P3^6;sbit T1= P3^5;sbit T0= P3^4;sbit INT1= P3^3;
  134. sbit INT0= P3^2;sbit TXD = P3^1;sbit RXD= P3^0;

  135. /*  SCON  */
  136. sbit SM0= SCON^7;sbit SM1 = SCON^6;sbit SM2= SCON^5;sbit REN= SCON^4;
  137. sbit TB8= SCON^3;sbit RB8= SCON^2;sbit TI= SCON^1;sbit RI = SCON^0;
  138. /*  P1  */
  139. sbit T2EX  = P1^1; // 8052 only   sbit T2    = P1^0; // 8052 only            
  140. /*  T2CON  */
  141. sbit TF2= T2CON^7;sbit EXF2= T2CON^6;sbit RCLK = T2CON^5;
  142. sbit TCLK= T2CON^4;sbit EXEN2= T2CON^3;sbit TR2= T2CON^2;
  143. sbit C_T2= T2CON^1;sbit CP_RL2 = T2CON^0;
  144. #endif
  145. /*  DS1302时钟模块  */
  146. #include <reg52.h>
  147. #include<intrins.h>
  148. sbit SCK=P2^6;                sbit SDA=P2^5;                sbit RST=P2^4;
  149. /*复位脚*/
  150. #define RST_CLR        RST=0/*电平置低*/
  151. #define RST_SET        RST=1/*电平置高*/
  152. /*双向数据*/
  153. #define IO_CLR        SDA=0/*电平置低*/
  154. #define IO_SET        SDA=1/*电平置高*/
  155. #define IO_R        SDA/*电平读取*/
  156. /*时钟信号*/
  157. #define SCK_CLR        SCK=0/*时钟信号*/
  158. #define SCK_SET        SCK=1/*电平置高*/
  159. #define ds1302_sec_add                        0x80                //秒数据地址
  160. #define ds1302_min_add                        0x82                //分数据地址
  161. #define ds1302_hr_add                        0x84                //时数据地址
  162. #define ds1302_date_add                        0x86                //日数据地址
  163. #define ds1302_month_add                0x88                //月数据地址
  164. #define ds1302_day_add                        0x8a                //星期数据地址
  165. #define ds1302_year_add                        0x8c                //年数据地址
  166. #define ds1302_control_add                0x8e                //控制数据地址
  167. #define ds1302_charger_add                0x90                                          
  168. #define ds1302_clkburst_add                0xbe
  169. unsigned char time_buf1[8] = {20,9,3,13,18,51,00,6};//空年月日时分秒周
  170. unsigned char time_buf[8] ;//空年月日时分秒周
  171. /*向DS1302写入一字节数据*/
  172. void ds1302_write_byte(unsigned char addr, unsigned char d) {
  173.         unsigned char i;
  174.         RST_SET;                                        /*启动DS1302总线*/
  175.                 /*写入目标地址:addr*/
  176.         addr = addr & 0xFE;/*最低位置零*/
  177.         for (i = 0; i < 8; i ++) {
  178.                             if (addr & 0x01) {
  179.                         IO_SET;
  180.                         }
  181.                 else {
  182.                         IO_CLR;
  183.                         }
  184.                 SCK_SET;                SCK_CLR;
  185.                 addr = addr >> 1;
  186.                 }
  187.                 /*写入数据:d*/
  188.         for (i = 0; i < 8; i ++) {
  189.                    if (d & 0x01)
  190. {
  191.                         IO_SET;
  192.                         }
  193.                 else {
  194.                         IO_CLR;
  195.                         }
  196.                 SCK_SET;                SCK_CLR;                d = d >> 1;
  197.                 }
  198.         RST_CLR;                                        /*停止DS1302总线*/
  199. }
  200. /*从DS1302读出一字节数据*/
  201. unsigned char ds1302_read_byte(unsigned char addr) {
  202.         unsigned char i;
  203.         unsigned char temp;
  204.         RST_SET;                                        /*启动DS1302总线*/
  205.         /*写入目标地址:addr*/
  206.         addr = addr | 0x01;/*最低位置高*/
  207.         for (i = 0; i < 8; i ++) {
  208.                          if (addr & 0x01) {
  209.                         IO_SET;
  210.                         }
  211.                 else {
  212.                         IO_CLR;
  213.                         }
  214.                 SCK_SET;                SCK_CLR;
  215.                 addr = addr >> 1;
  216.                 }
  217.         /*输出数据:temp*/
  218.         for (i = 0; i < 8; i ++) {
  219.                 temp = temp >> 1;
  220.                 if (IO_R) {
  221.                         temp |= 0x80;
  222.                         }
  223.                 else {
  224.                         temp &= 0x7F;
  225.                         }
  226.                 SCK_SET;                SCK_CLR;
  227.                 }
  228.         RST_CLR;                                        /*停止DS1302总线*/
  229.         return temp;
  230. }
  231. /*向DS302写入时钟数据*/
  232. void ds1302_write_time(void) {
  233.     unsigned char i,tmp;
  234.         for(i=0;i<8;i++){           //BCD处理
  235.                 tmp=time_buf1[i]/10;
  236.                 time_buf[i]=time_buf1[i]%10;
  237.                 time_buf[i]=time_buf[i]+tmp*16;
  238.         }
  239.         ds1302_write_byte(ds1302_control_add,0x00);                        //关闭写保护
  240.         ds1302_write_byte(ds1302_sec_add,0x80);                                //暂停
  241.         ds1302_write_byte(ds1302_charger_add,0xa9);                        //涓流充电
  242.         ds1302_write_byte(ds1302_year_add,time_buf[1]);                //年
  243.         ds1302_write_byte(ds1302_month_add,time_buf[2]);        //月
  244.         ds1302_write_byte(ds1302_date_add,time_buf[3]);                //日
  245.         ds1302_write_byte(ds1302_day_add,time_buf[7]);                //周
  246.         ds1302_write_byte(ds1302_hr_add,time_buf[4]);                //时
  247.         ds1302_write_byte(ds1302_min_add,time_buf[5]);                //分
  248.         ds1302_write_byte(ds1302_sec_add,time_buf[6]);                //秒
  249.         ds1302_write_byte(ds1302_day_add,time_buf[7]);                //周
  250.         ds1302_write_byte(ds1302_control_add,0x80);                        //打开写保护
  251. }
  252. /*从DS1302读出时钟数据*/
  253. void ds1302_read_time(void)  {
  254.                unsigned char i,tmp;
  255.         time_buf[1]=ds1302_read_byte(ds1302_year_add);                //年
  256.         time_buf[2]=ds1302_read_byte(ds1302_month_add);                //月
  257.         time_buf[3]=ds1302_read_byte(ds1302_date_add);                //日
  258.         time_buf[4]=ds1302_read_byte(ds1302_hr_add);                //时
  259.         time_buf[5]=ds1302_read_byte(ds1302_min_add);                //分
  260.         time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7F;//秒
  261.         time_buf[7]=ds1302_read_byte(ds1302_day_add);                //周
  262.         for(i=0;i<8;i++){           //BCD处理
  263.                 tmp=time_buf[i]/16;
  264.                 time_buf1[i]=time_buf[i]%16;
  265.                 time_buf1[i]=time_buf1[i]+tmp*10;
  266.         }
  267. }
  268. /*DS1302初始化函数*/
  269. void ds1302_init(void) {
  270.         RST_CLR;                        /*RST脚置低*/
  271.         SCK_CLR;                        /*SCK脚置低*/
  272. }
  273. /*--------------------------------------------------------------------------
  274. INTRINS.H
  275. Intrinsic functions for C51.
  276. Copyright (c) 1988-2004 Keil Elektronik GmbH and Keil Software, Inc.
  277. All rights reserved.
  278. --------------------------------------------------------------------------*/
  279. #ifndef __INTRINS_H__
  280. #define __INTRINS_H__
  281. extern void          _nop_     (void);
  282. extern bit           _testbit_ (bit);
  283. extern unsigned char _cror_    (unsigned char, unsigned char);
  284. extern unsigned int  _iror_    (unsigned int,  unsigned char);
  285. extern unsigned long _lror_    (unsigned long, unsigned char);
  286. extern unsigned char _crol_    (unsigned char, unsigned char);
  287. extern unsigned int  _irol_    (unsigned int,  unsigned char);
  288. extern unsigned long _lrol_    (unsigned long, unsigned char);
  289. extern unsigned char _chkfloat_(float);
  290. extern void          _push_    (unsigned char _sfr);
  291. extern void          _pop_     (unsigned char _sfr);
  292. #endif
  293. /*12864液晶显示模块*/
  294. #ifndef _12864_H
  295. #define        _12864_H
  296. #include<reg52.h>
  297. #include<intrins.h>  
  298. #define uchar unsigned char
  299. #define uint unsigned int
  300. /*端口定义*/
  301. sbit lcdrs=P3^6;sbit lcdrw=P3^5;sbit lcden=P3^4;sbit lcdpsb=P3^7;
  302. uchar code dis1[]={"20  年  月  日  "};
  303. uchar code dis2[]={"周    时  分  秒"};
  304. uchar code dis3[]={"湿度  % 高  低  "};
  305. uchar code dis4[]={"温度  ℃高  低  "};
  306. void delay(uint z)
  307. {
  308.         uint x,y;        for(x=0;x<z;x++)
  309.         for(y=0;y<110;y++);
  310. }

  311. /*写指令数据到lcd*/
  312. void write_cmd(uchar cmd)
  313. {
  314. lcdrs=0;        lcdrw=0;        lcden=0;        P0=cmd;       
  315. delay(5);        lcden=1;        delay(5);        lcden=0;  
  316. }
  317. /*写显示数据到lcd*/
  318. void write_date(uchar date)
  319. {
  320.     lcdrs=1;        lcdrw=0;    lcdrw=0;        P0=date;
  321.         delay(5);        lcden=1;        delay(5);        lcden=0;   
  322. }
  323. /*设定显示位置*/
  324. void lcd_pos(uchar x,uchar y)
  325. {
  326.     uchar pos;        if(x==0)        {x=0x80;}
  327.         else if(x==1)        {x=0x90;}
  328.         else if(x==2)        {x=0x88;}
  329.         else if(x==3)        {x=0x98;}
  330.         pos=x+y;        write_cmd(pos);
  331. }
  332. void lcd_dis(uchar dis[])
  333. {
  334.     uchar i;        i=0;
  335.         while(dis[i] !='\0')
  336.         {
  337.            write_date(dis[i]);           i++;
  338.         }
  339. }
  340. /********************清屏***************************/
  341. void lcd_clear(void)
  342. {
  343.   write_cmd(0x01);     //显示清屏
  344.   write_cmd(0x34);     // 显示光标移动设置
  345.   write_cmd(0x30);     // 显示开及光标设置
  346. }
  347. void lcd_init()
  348. {
  349.     lcdpsb=1;    write_cmd(0x30);        delay(5);
  350.     write_cmd(0x0C);        delay(5);    write_cmd(0x01);        delay(5);
  351.         lcd_pos(0,0);        lcd_dis(dis1);        lcd_pos(1,0);        lcd_dis(dis2);
  352.         lcd_pos(2,0);        lcd_dis(dis3);        lcd_pos(3,0);        lcd_dis(dis4);
  353. }
  354. #endif
  355. /*DHT11数字温湿度控制模块*/
  356. #ifndef _DHT11_H
  357. #define        _DHT11_H
  358. #include<reg52.h>
  359. #include<intrins.h>
  360. #include"12864.h"
  361. #include"key.h"
  362. #include"define.h"
  363. #define uchar unsigned char
  364. #define uint unsigned int
  365. sbit dht11=P3^2;                uchar data_byte;         uchar RH,RL,TH,TL;
  366. int max_wen,min_wen,max_shi,min_shi;
  367. int input(uint a,uint b)
  368. {
  369.     int k=0;                int zhengshu;
  370.         lcd_pos(a,b);
  371.         while(k<2)
  372.      {          
  373.          ReadKey();                   
  374.          if(l_key<=9)   //输入数字0-9
  375.          {  
  376.                       shuzhi[k]=l_key;
  377.               write_date(shuzhi[k]+0x30);
  378.               l_key=0xff;  k++;   
  379.          }  
  380.       }
  381.            while(k>=2)
  382.       {  
  383.               ReadKey();  
  384.           if(l_key==15) //确定
  385.           {  
  386.                       zhengshu=shuzhi[0]*10+shuzhi[1] ;
  387.               l_key=0xff;                  
  388.               break;
  389.           }  
  390.           }
  391.           return zhengshu;
  392. }       
  393. void dis_dht11(uchar hang,uchar add,char date)
  394. {
  395.     uchar shi,ge;                shi=date/10+0x30;                ge=date%10+0x30;
  396.         lcd_pos(hang,add);                write_date(shi);                        write_date(ge);
  397. }
  398. void delay10us()//延时10us
  399. {
  400.    uchar i;   i--;   i--;   i--;   i--;   i--;   i--;
  401. }
  402. void start()//开始信号
  403. {
  404.    dht11=1;    delay10us();    dht11=0;    delay(40);//>18ms
  405.    dht11=1;    delay10us();//20-40us    delay10us();    delay10us();
  406.    delay10us();   delay10us();
  407. }
  408. uchar receive_byte()//接收一个字节
  409. {
  410.     uchar i,temp,count;
  411.     for(i=0;i<8;i++)
  412.    {
  413.         count=2;
  414.         while((!dht11)&&count++)//等待50us低电平结束
  415.         temp=0;         delay10us();                delay10us();                        delay10us();
  416.                 delay10us();
  417.         if(dht11==1) temp=1;         count=2;
  418.         while((dht11)&&count++);
  419.         if(count==1)  break;
  420.         data_byte<<=1;          data_byte|=temp;   
  421.     }
  422.     return data_byte;
  423. }
  424. void dht11_receive()//接收数据
  425. {
  426.     uchar T_H,T_L,R_H,R_L,check,num_check;
  427.     uchar count;     start();//开始信号
  428.     dht11=1;
  429.     if(!dht11)//读取DHT11响应信号
  430.     {
  431.          count=2;     while((!dht11)&&count++);//DHT11高电平80us是否结束
  432.          count=2;    while((dht11)&&count++);
  433.          R_H=receive_byte();           R_L=receive_byte();
  434.          T_H=receive_byte();          T_L=receive_byte();
  435.          check=receive_byte();          dht11=0;//拉低延时50us
  436.          delay10us();                 delay10us();                 delay10us();
  437.                  delay10us();                 delay10us();         dht11=1;
  438.          num_check=R_H+R_L+T_H+T_L;
  439.          if(num_check=check)
  440.          {
  441.              RH=R_H;  RL=R_L;  TH=T_H;   TL=T_L;
  442.              check=num_check;
  443.          }                                        
  444.     }
  445.     dis_dht11(3,2,TH);                dis_dht11(2,2,RH);
  446. }
  447. void set_kongzhi()
  448. {
  449.     max_wen=input(3,5) ;        min_wen=input(3,7) ;
  450.         max_shi=input(2,5) ;        min_shi=input(2,7) ;
  451.     if(TH>max_wen)
  452.      {
  453.            speaker=0;           ji1=0   ;
  454.          }
  455.          else
  456.          if(TH<min_wen)
  457.          {
  458.            speaker=0;           ji2=0   ;
  459.          }
  460.            if(RH>max_shi)
  461.      {
  462.            speaker=0;           ji3=0   ;
  463.          }
  464.          else
  465.          if(RH<min_shi)
  466.          {
  467.            speaker=0;           ji4=0   ;
  468.          }
  469. }
  470. void kongzhi()
  471. {
  472.    if(TH>max_wen)     {            speaker=0;           ji1=0   ;         }
  473.          else         if(TH<min_wen)         {            speaker=0;           ji2=0   ;         }
  474.         if(RH>max_shi)     {            speaker=0;           ji3=0   ;         }
  475.          else         if(RH<min_shi)         {            speaker=0;           ji4=0   ;         }
  476. }       
  477. #endif
  478. /*4*4矩阵键盘模块*/
  479. #ifndef _KEY_H
  480. #define        _KEY_H
  481. #include<reg52.h>
  482. #include<intrins.h>
  483. #define uchar unsigned char
  484. #define uint unsigned int
  485. Code uchar key_tab[17]={0xd7,0xee,0xde,0xbe,0xed,0xdd,0xbd,0xeb,                         0xdb,0xbb,0x7e,0x7d, 0x7b,0x77,0xb7,0xe7,0XFF};
  486. //========================此数组为键盘编码
  487. // 1 2 3 a                0x01 0x02 0x03 0x0a
  488. // 4 5 6 b 对应16进制码 0x04 0x05 0x06 0x0b
  489. // 7 8 9 c                0x07 0x08 0x09 0x0c
  490. // e 0 f d                0x0e 0x00 0x0f 0x0d
  491. //键盘的读取我们采用分时扫描
  492. uchar l_key=0xff;  //定义变量存放键值  
  493. uchar l_keyold=0xFF; //做为按键松开否的凭证     
  494. void ReadKey(void)      //读键盘值
  495. {      uchar i,j,key;      j=0xfe;
  496.      key=0xff;       //设定初值
  497.      for (i=0;i<4;i++)
  498.          {   
  499.           P1=j;    //P2口低4位循环输出0扫描键盘
  500.           if ((P1&0xf0)!=0xf0)
  501.               {                  //如果有键按下P2高4位不会全为1
  502.                       delay(10);                              P1=j;
  503.                           if ((P1&0xf0)!=0xf0)
  504.                           {
  505.               key=P1;       //读取P2口退出循环否则循环下次
  506.               break;  
  507.                           }
  508.           }
  509.           j=_crol_(j,1);        //此函数功能为左循环移位
  510.      }
  511.      if (key==0xff)
  512.          {         //如果读取不到P1口的值比如是干扰不做键值处理返回
  513.           l_keyold=0xff;           return;
  514.      }        
  515.      if(l_keyold==key)
  516.          {        //检测按键放开否如
  517.           return;
  518.      }   
  519.      l_keyold=key;   //获取键码做为放开的凭证
  520.      for(i=0;i<17;i++)
  521.          {                   //查表获得相应的16进制值存放l_key变量中
  522.           if (key==key_tab[i])
  523.                   {
  524.               l_key=i;  break;
  525.           }
  526.      } //程序运行到这里就表明有键值被读取存放于l_key变量中主程序就可以检测此变量//
  527. }   
  528. #endif

复制代码

附录二程序.docx

23.8 KB, 下载次数: 16, 下载积分: 黑币 -5

基于单片机的温湿度监测与控制系统程序设计

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

使用道具 举报

沙发
ID:361606 发表于 2018-6-30 13:05 | 只看该作者
没有电路图······
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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