找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机实现温度传感器和按键调节时钟 附源程序

[复制链接]
跳转到指定楼层
楼主
这个暑假做了基于51单片机实现12864实现DHT11温湿度传感器和DS1302实现闹钟和温湿度显示在同一个界面上,可以通过四个独立按键控制时钟的暂停,时分秒年月日位置的切换,可以实现时钟的加法,减法,里面还有许多的小BUG,很是难以调整,有兴趣可以看一下如何进行代码的优化,总而言之,基本的功能是可以实现的了,由于我那单片机多个矩阵按键损坏,导致矩阵按键的位置有所不同,大家注意一下就好了。
不知道这么附录代码,你们下载看一下就好了

//提前透露出一些小BUG,有的受K3按键按下去,但是中断并没有开启,时钟也没有暂停,
原因不知出现在哪里,总之你们有兴趣随便看一下就行了,写的是烂了点,望大佬指点以下

单片机源程序如下:
  1. #include "all.h"
  2. #include"DHT11.h"

  3. sbit K1=P3^4;
  4. sbit K2=P3^5;
  5. sbit K3=P3^2;  //右上角是这个按键电灯,触发了外部中断0
  6. sbit K4=P3^3;  //管脚接线
  7. sbit Beep = P3^1;
  8. unsigned char  Temp[8];
  9. char val_flag = 0;
  10. static unsigned char SetState,SetPlace,Place;
  11. static int  k = 1, q = 1,e = 1,r = 1,t = 1;
  12. static int w = 1;

  13. void  tiaojie();
  14. char Key_Scan();
  15. void hanshuming();
  16. void Int0Configuration();
  17. void Delay10ms();
  18. char Key_Scan();
  19. void SCLKTemp();
  20. void BeepHear();

  21. /*8421码转换*/
  22. unsigned char ChangeTime(unsigned char tim)
  23. {
  24.            //tim = Time_buf[7]=0x4A,0x0A,10
  25. unsigned char Time;
  26. if((tim&0x0F)>9)      //如果个位超过9,则十位加一后,个位清零
  27. {
  28.   tim=((tim+0x10)&0xF0);    //0x4A+0x10=0x5A&0xF0=0x50
  29.            
  30. }          //如果没有则跳过该部分

  31.            //Timebuf = 0x50
  32. Time = (tim>>4)*10+(tim&0x0f);   //把8421码转变成10进制的数
  33.            //0x50>>4=0x05*10=50,0x50&0x0f=0x00=0 ;50  DS1302_Write_Time(void)

  34. return Time;      

  35. }

  36. void DS1302()
  37. {

  38. uchar tishi1[] ="设置闹铃";

  39. unsigned char sec_buf = 0x00; //用来保存上一次的秒数
  40. unsigned char i,j;
  41.   
  42. Init_12684();             //12864初始化
  43. DS1302_Init();     //DS1302初始化
  44. DS1302_Write_Time();   //初始化数据

  45.    for(i = 0; i < 8;i++)
  46.   {
  47.      Temp[i] = Time_buf[i];
  48.   }
  49.     while(1)
  50.   {
  51.      static char k ;
  52.      Rec_DHTI0();
  53.    if(0 == val_flag)
  54.    {
  55.     DS1302_Read_Time();
  56.    }
  57.         
  58.        if(SetState==0)
  59.      {
  60.       DS1302_Read_Time();
  61.      }
  62.      
  63.      else
  64.      {
  65.      
  66.        if(K1==0)  //检测按键K1是否按下
  67.      {
  68.       
  69.       Delay10ms(); //消除抖动
  70.       if(K1==0)
  71.       {
  72.        SetPlace++;
  73.       
  74.         for(j = 0; j < SetPlace;j++)//1 2 3 4  5 6 7   //按照的这个结果是地址成功加到7
  75.         {
  76.          if(SetPlace>=8)   //按键可以控制分秒年月日的切换 按键按到6的时候可以实现年的切换,之后按键到7没有任何显示 再按一次重新回到秒的切换
  77.           SetPlace=0;   
  78.          
  79.          if(SetPlace == 6)
  80.          {
  81.            SetPlace = 7;
  82.          }
  83.          
  84.          xianshi();
  85.         }
  86.         j = 0;
  87.       }
  88.       
  89.       while((i<50)&&(K1==0))  //检测按键是否松开
  90.       {
  91.        Delay10ms();
  92.        i++;
  93.       }
  94.       i=0;
  95.      }
  96.      
  97.      if(K2==0)  //检测按键K2是否按下
  98.      {
  99.       Delay10ms(); //消除抖动
  100.       if(K2==0)
  101.       {
  102.       
  103.         Time_buf[SetPlace]++;
  104.        if((Time_buf[SetPlace]&0x0f)>9)      //换成BCD码。
  105.        {
  106.         xianshi();
  107.        Time_buf[SetPlace]=Time_buf[SetPlace]+6;
  108.        }
  109.        if((Time_buf[SetPlace]>=0x60)&&(SetPlace<2))  //秒
  110.        {
  111.         Time_buf[SetPlace]=0;
  112.        }
  113.        if((Time_buf[SetPlace]>=0x60)&&(SetPlace==2))  //分钟
  114.        {
  115.         Time_buf[SetPlace]=0;
  116.        }
  117.        if((Time_buf[SetPlace]>=0x24)&&(SetPlace==3))  // 小时
  118.        {
  119.         Time_buf[SetPlace]=0;
  120.        }
  121.        if((Time_buf[SetPlace]>=0x31)&&(SetPlace==4))  //日       //日期显示有问题
  122.        {
  123.         Time_buf[SetPlace]=0;
  124.        }
  125.        if((Time_buf[SetPlace]>=0x13)&&(SetPlace==5))  //月
  126.        {
  127.         Time_buf[SetPlace]=1;
  128.        }  
  129.   //     if(SetPlace==5)  //月只能到12
  130.   //     {
  131.   //      TIME[SetPlace]=;
  132.   //     }
  133.       }
  134.       
  135.       while((i<50)&&(K2==0))  //检测按键是否松开
  136.       {
  137.        Delay10ms();
  138.        i++;
  139.       }
  140.       i=0;
  141.       
  142.      }  
  143.            if(K4==0)  //检测按键K2是否按下
  144.      {
  145.        //xianshi();
  146.       Delay10ms(); //消除抖动
  147.       if(K4==0)
  148.       {
  149.       
  150.         Time_buf[SetPlace]--; //减法需要将减到到0的时候置为为 0x59之类的
  151.        if((Time_buf[SetPlace]&0x0f)>9)      //换成BCD码。
  152.        {
  153.        // xianshi();
  154.        Time_buf[SetPlace]=Time_buf[SetPlace]-6;
  155.        }
  156.        if((Time_buf[SetPlace]<= 0x00)&&(SetPlace < 2))  //分钟
  157.        {
  158.         Time_buf[SetPlace]=0x59;
  159.        }
  160.       
  161.        if((Time_buf[SetPlace]<= 0x00)&&(SetPlace==2))  //分钟
  162.        {
  163.         Time_buf[SetPlace]=0x59;
  164.        }
  165.        if((Time_buf[SetPlace]<= 0x00)&&(SetPlace==3))  // 小时
  166.        {
  167.         Time_buf[SetPlace]= 0x23;
  168.        }
  169.       
  170.       
  171.        if((Time_buf[SetPlace] <= 0x00)&&(SetPlace==4))  //日
  172.        {
  173.         Time_buf[SetPlace]=0x30;
  174.        }
  175.        if((Time_buf[SetPlace] <= 0x00)&&(SetPlace==5))  //月
  176.        {
  177.         Time_buf[SetPlace]=0x12;
  178.        }  
  179.       
  180.   //     if(SetPlace==5)  //月只能到12
  181.   //     {
  182.   //      TIME[SetPlace]=;
  183.   //     }
  184.       }
  185.       
  186.       while((i<50)&&(K4==0))  //检测按键是否松开
  187.       {
  188.        Delay10ms();
  189.        i++;
  190.       }
  191.       i=0;
  192.      
  193.      }   
  194.          
  195.          
  196.       
  197.               
  198.    }
  199.    
  200.    
  201.    
  202.   if(Key_Scan() == 8)
  203. {
  204.       
  205.    write_command(0x01);
  206.   
  207.    print(1,0,tishi1);
  208.    SCLKTemp();
  209.     while(Key_Scan() != 9)
  210.    {
  211.       tiaojie();
  212.       SCLKTemp();
  213.       
  214.    }
  215. }

  216. else
  217. {   
  218.   Init_12684();
  219.    LCD_Display();
  220. }
  221.   if(Time_buf[1] == Temp[1] && Time_buf[2] == Temp[2] && Time_buf[3] == Temp[3] ) //闹钟蜂鸣器
  222. {
  223.    BeepHear();
  224.    
  225. }

  226.   }
  227. }
  228. void BeepHear()
  229. {
  230.    int i = 0;
  231. for(i = 0; i < 200; i++)
  232.   {
  233.    Beep = 0;
  234.   Delay10ms();
  235. }
  236. Beep = 1;

  237. }
  238. void  tiaojie()
  239. {
  240. static unsigned char Place = 0;
  241.   uchar i,j;
  242.      if(K1==0)  //检测按键K1是否按下
  243.      {
  244.       
  245.       Delay10ms(); //消除抖动
  246.       if(K1==0)
  247.       {
  248.        Place++;
  249.       
  250.         for(j = 0; j < Place;j++)//1 2 3 4  5 6 7   //按照的这个结果是地址成功加到7
  251.         {
  252.          if(Place>=4)   //按键可以控制分秒年月日的切换 按键按到6的时候可以实现年的切换,之后按键到7没有任何显示 再按一次重新回到秒的切换
  253.           Place=1;   
  254.          
  255.    
  256.          
  257.          xianshi();
  258.         }
  259.         j = 0;
  260.       }
  261.       
  262.       while((i<50)&&(K1==0))  //检测按键是否松开
  263.       {
  264.        Delay10ms();
  265.        i++;
  266.       }
  267.       i=0;
  268.      }
  269.      
  270.      if(K2==0)  //检测按键K2是否按下
  271.      {
  272.       Delay10ms(); //消除抖动
  273.       if(K2==0)
  274.       {
  275.       
  276.         Temp[Place]++;
  277.        if((Temp[Place]&0x0f)>9)      //换成BCD码。
  278.        {
  279.         xianshi();
  280.        Temp[Place]=Temp[Place]+6;
  281.        }
  282.        if((Temp[Place]>=0x60)&&(Place<2))  //秒
  283.        {
  284.         Temp[Place]=0;
  285.        }
  286.        if((Temp[Place]>=0x60)&&(Place==2))  //分钟
  287.        {
  288.         Temp[Place]=0;
  289.        }
  290.        if((Temp[Place]>=0x24)&&(Place==3))  // 小时
  291.        {
  292.         Temp[Place]=0;
  293.        }
  294.       
  295.   //     if(SetPlace==5)  //月只能到12
  296.   //     {
  297.   //      TIME[SetPlace]=;
  298.   //     }
  299.       }
  300.       
  301.       while((i<50)&&(K2==0))  //检测按键是否松开
  302.       {
  303.        Delay10ms();
  304.        i++;
  305.       }
  306.       i=0;
  307.      while(!K2);
  308.      }  

  309.            if(K4==0)  //检测按键K2是否按下
  310.      {
  311.        //xianshi();
  312.       Delay10ms(); //消除抖动
  313.       if(K4==0)
  314.       {
  315.       
  316.         Temp[Place]--; //减法需要将减到到0的时候置为为 0x59之类的
  317.        if((Temp[Place]&0x0f)>9)      //换成BCD码。
  318.        {
  319.        // xianshi();
  320.        Temp[Place]=Temp[Place]-6;
  321.        }
  322.        if((Temp[Place]<= 0x00)&&(Place < 2))  //分钟
  323.        {
  324.         Temp[Place]=0x59;
  325.        }
  326.       
  327.        if((Temp[Place]<= 0x00)&&(Place==2))  //分钟
  328.        {
  329.         Temp[Place]=0x59;
  330.        }
  331.        if((Temp[Place]<= 0x00)&&(Place==3))  // 小时
  332.        {
  333.         Temp[Place]= 0x23;
  334.        }
  335.       
  336.   //     if(SetPlace==5)  //月只能到12
  337.   //     {
  338.   //      TIME[SetPlace]=;
  339.   //     }
  340.       }
  341.       
  342.       while((i<50)&&(K4==0))  //检测按键是否松开
  343.       {
  344.        Delay10ms();
  345.        i++;
  346.       }
  347.       i=0;
  348.       while(!K4);
  349.      
  350.      }   
  351.          
  352.          
  353. }
  354. void main()
  355. {



  356. Beep = 1;
  357. Int0Configuration();   
  358. DS1302();

  359. }

  360. void Int0Configuration()
  361. {
  362. //设置INT0                          //设置外部中断一,方式为下降沿触发
  363. IT0=1;//跳变沿出发方式(下降沿)
  364. EX0=1;//打开INT0的中断允许。
  365. EA=1;//打开总中断
  366. }
  367. void Int0() interrupt 0   
  368. {
  369. static val = 0;
  370.   int i = 2;
  371. if(val == 0)
  372. {
  373.   val = 1;
  374.   DS1302_Data_Input(DS1302_SEC_ADD,0x80);
  375. }
  376. else
  377. {
  378.     DS1302_Write_Time();
  379.      DS1302_Data_Input(DS1302_SEC_ADD,0x00);
  380.   val = 0;
  381. }
  382. val_flag = val;

  383. }
  384. void Delay10ms(void)   //误差 0us
  385. {
  386.     unsigned char a,b,c;
  387.     for(c=1;c>0;c--)
  388.         for(b=38;b>0;b--)
  389.             for(a=130;a>0;a--);
  390. }
  391. void hanshuming()
  392. {
  393. write_command(0x80);
  394. write_data('2');
  395. write_data('0');
  396. write_data('0'+Time_buf[7]/16);   //年
  397. write_data('0'+(Time_buf[7]&0x0f));
  398. write_data('-');
  399. write_data('0'+Time_buf[5]/16);   //月
  400. write_data('0'+(Time_buf[5]&0x0f));
  401. write_data('-');
  402. write_data('0'+Time_buf[4]/16);
  403. write_data('0'+(Time_buf[4]&0x0f));   //日
  404.    
  405. write_command(0x90);
  406. write_data('0'+Time_buf[3]/16);    //时
  407. write_data('0'+(Time_buf[3]&0x0f));     
  408. write_data('-');
  409. write_data('0'+Time_buf[2]/16);    //分
  410. write_data('0'+(Time_buf[2]&0x0f));
  411. write_data('-');
  412. write_data('0'+Time_buf[1]/16);    //秒
  413. write_data('0'+(Time_buf[1]&0x0f));

  414. }
  415. void SCLKTemp()
  416. {
  417.    
  418. write_command(0x88);
  419. write_data('0'+Temp[3]/16);    //时
  420. write_data('0'+(Temp[3]&0x0f));     
  421. write_data('-');
  422. write_data('0'+Temp[2]/16);    //分
  423. write_data('0'+(Temp[2]&0x0f));
  424. write_data('-');
  425. write_data('0'+Temp[1]/16);    //秒
  426. write_data('0'+(Temp[1]&0x0f));
  427. }
  428. char Key_Scan()
  429. {
  430. static char key=16;
  431. uchar x, y, z;
  432. P1 = 0x0f;                 //置数,行扫描
  433. if(P1 != 0x0f)             //判断按键是否按下
  434. {
  435.   delay(10);               //消抖
  436.   if(P1 != 0X00)           //确定按键已经按下
  437.   {
  438.    x = P1&0x0f;           //保存按键状态
  439.    P1 = 0xf0;             //列扫描
  440.    y = P1&0xf0;           //保存按键状态
  441.    z = x|y;               //取出健值
  442.    switch(z)
  443.    {
  444.     case 0xbd: key=1;break;
  445.     case 0xdd: key=2;break;      
  446.     case 0xed: key=3;break;
  447.    
  448.    
  449.     case 0xdb: key=5;break;      
  450.     case 0xeb: key=6;break;
  451.    
  452.    
  453.     case 0xb7: key=7;break;
  454.    
  455.     case 0xd7: key=8;break;  
  456.     case 0xe7: key=9;break;
  457.    
  458.     default: return 0;
  459.       break;
  460.          
  461.    }
  462.    
  463.   }
  464. }
  465. return key;
  466. }

  467. /*******************************************************************************
  468. * 文件名 : DS1302.c
  469. * 实现功能:DS1302驱动程序
  470. * 版本     作者            日期            说明
  471. * V1.0     HE             2017/02/06       初始版本
  472. * 描述   : MCU: STC15F2K60S2     晶振:22.1184    MHz
  473.            
  474. *******************************************************************************/  
  475. #include "DS1302.h"

  476. void DHT11();
  477. void Init_12684();
  478. void xianshi();
  479. void Rec_DHTI0();
  480. uchar Read_8bit();
  481. void  LCD_Display();
  482. uchar k,j;
  483. unsigned char Time_buf[8]={0x20,0x50,0x59,0x23,0x24,0x08,0x05,0x20};//年,秒,分,时,日,月,星期,年
  484. //                              _______________

  485. //                         年    秒    分  十    日   月   星期   年
  486. /*******************************************************************************
  487. * 功能描述 : DS1302初始化
  488. * 函数属性 : 外部
  489. * 输入参数 : 无
  490. * 返回参数 : 无
  491. * 函数详解 :上电运行时,在VCC大于或小于2.5V之前,RST必须
  492. *   保持低电平,只有在SCLK为低电平时,RST才能被置高
  493. *******************************************************************************/
  494. void DS1302_Init()
  495. {
  496. RST = 0;      //片选
  497. SCLK = 0;
  498. }
  499. /*******************************************************************************
  500. * 功能描述 : 数据输入函数
  501. * 函数属性 : 外部
  502. * 输入参数 : 无
  503. * 返回参数 : 无
  504. * 函数详解 : 数据输入,一个字节的输入将在下8个时钟周期的上升沿完成,
  505. *    数据传输从字节最低位开始
  506. *******************************************************************************/
  507. void DS1302_Data_Input(unsigned char Address,unsigned char Data)  //整个函数是先写入地址后写入数据
  508. {
  509. unsigned char i;
  510. RST = 1;//启动DS1302总线
  511. Address = Address & 0xFE;//最低位置0,寄存器0位时写,1时读,这时为写数据 这个时候ADDress的值根本没有改变
  512. for(i=0;i<8;i++)
  513. {
  514.   SCLK = 0;
  515.   if(Address&0x01)  //判断最低位是否为高电平 ,如果为高电平,则传入1给IO口
  516.   {
  517.    DAT = 1;
  518.   }
  519.   else    //判断最低位的是否为低电平  ,如果为低电平,则传入0给IO口
  520.   {
  521.    DAT = 0;
  522.   }
  523.   SCLK = 1;//上升沿写入指令
  524.   Address = Address>>1;   //向右移动移位,依次判断剩下的高位数据
  525. }
  526. for(i=0;i<8;i++)   //写入数据
  527. {
  528.   SCLK = 0;
  529.   if(Data&0x01)
  530.   {
  531.    DAT = 1;
  532.   }
  533.   else
  534.   {
  535.    DAT = 0;
  536.   }
  537.   SCLK = 1;//上升沿写入数据
  538.   Data = Data>>1;
  539. }
  540. SCLK = 0;
  541. RST = 0;//关闭DS1302总线
  542. }
  543. /*
  544. */
  545. /*******************************************************************************
  546. * 功能描述 : 数据输出函数
  547. * 函数属性 : 外部
  548. * 输入参数 : 无
  549. * 返回参数 : 无
  550. * 函数详解 : 数据输出,一个字节的数据将在下个8个时钟周期的下降沿被输出。注意第一位输出
  551. *    是在最后一位控制指令所在的下降沿被输出,要求RST保持位高电平
  552. *******************************************************************************/
  553. unsigned char DS1302_Data_Output(unsigned char Address)
  554. {
  555. unsigned char i;
  556. unsigned char temp;
  557. RST = 1;
  558. Address = Address | 0x01;
  559. for(i=0;i<8;i++)
  560. {
  561.   SCLK = 0;
  562.   if(Address&0x01)
  563.   {
  564.    DAT = 1;
  565.   }
  566.   else
  567.   {
  568.    DAT = 0;
  569.   }
  570.   SCLK = 1;
  571.   Address = Address>>1;
  572. }

  573. for(i=0;i<8;i++)
  574. {
  575.   SCLK=0;
  576.   temp = temp >> 1;
  577.   if (DAT)
  578.   {
  579.    temp |= 0x80;
  580.   }
  581.   else
  582.   {
  583.    temp &= 0x7F;
  584.   }
  585.   SCLK=1;
  586. }
  587. SCLK=0;
  588. RST = 0;
  589. return temp;

  590. }
  591. /*******************************************************************************
  592. * 功能描述 : 初始化时间
  593. * 函数属性 : 外部
  594. * 输入参数 : 无
  595. * 返回参数 : 无
  596. * 函数详解 :
  597. *******************************************************************************/
  598. void DS1302_Write_Time(void)
  599. {
  600. DS1302_Data_Input(DS1302_CONTROL_ADD,0x00);  //关闭写保护,允许数据写入寄存器,数据内容为0(写入允许)
  601. DS1302_Data_Input(DS1302_SEC_ADD,0x80);   //CH位置高,振荡器停止,置低,振荡器工作允许
  602. DS1302_Data_Input(DS1302_CHARGER_ADD,0xa9);
  603. //涓流充电,7~4位TCS=1010,使能涓流充电
  604. //3~2位DS=01,选择一个二极管,DS=10,选择两个二极管,等于其他值,均被禁止充电
  605. //1~0位RS=00,无电阻,不能充电,RS=01,2k,RS=10,4k,RS=11,8k

  606. /*初始值*/
  607. DS1302_Data_Input(DS1302_SEC_ADD,Time_buf[1]);  //秒寄存器地址     //后面这个数组好像是设置一个初始值
  608. DS1302_Data_Input(DS1302_MIN_ADD,Time_buf[2]);  //分钟寄存器
  609. DS1302_Data_Input(DS1302_HR_ADD,Time_buf[3]);  //时
  610. DS1302_Data_Input(DS1302_DAY_ADD,Time_buf[4]);  //日
  611. DS1302_Data_Input(DS1302_MONTH_ADD,Time_buf[5]); //月
  612. DS1302_Data_Input(DS1302_WEEK_ADD,Time_buf[6]);  //星期
  613. DS1302_Data_Input(DS1302_YEAR_ADD,Time_buf[7]);  //年

  614. DS1302_Data_Input(DS1302_CONTROL_ADD,0x80);   //打开写保护
  615. }
  616. /*******************************************************************************
  617. * 功能描述 : 读取时间
  618. * 函数属性 : 外部
  619. * 输入参数 : 无
  620. * 返回参数 : 无
  621. * 函数详解 :
  622. *******************************************************************************/
  623. void DS1302_Read_Time(void)  
  624. {
  625. Time_buf[1]=(DS1302_Data_Output(DS1302_SEC_ADD))&0x7f; //秒,屏蔽秒的第7位,避免超出59
  626. Time_buf[2]=DS1302_Data_Output(DS1302_MIN_ADD);   //分
  627. Time_buf[3]=DS1302_Data_Output(DS1302_HR_ADD)&0x3F;  //时  3f -- 0011 1111
  628. Time_buf[4]=DS1302_Data_Output(DS1302_DAY_ADD);   //日
  629. Time_buf[5]=DS1302_Data_Output(DS1302_MONTH_ADD);  //月
  630. Time_buf[6]=DS1302_Data_Output(DS1302_WEEK_ADD);  //星期
  631. Time_buf[7]=DS1302_Data_Output(DS1302_YEAR_ADD);  //年
  632. }


  633. sbit led1 = P2^5;
  634. sbit led2 = P2^6;
  635. sbit led3 = P2^7;
  636. sbit DHTI0 = P3^0;
  637. uchar RL_data, RH_data, TH_data, TL_data, CK_data;
  638. uchar undata;

  639. //uchar code lcd[]={"当前的温湿度"};
  640. uchar code lcd1[]={"温度:    ℃"};
  641. uchar code lcd2[]={"湿度:    %RH"};
  642. uchar  str1[]={"   "};
  643. uchar  str2[]={"   "};
  644. void delay1s()
  645. {  
  646.     int i ,j;
  647.     for(i = 0;i<110; ++i)
  648.     {
  649.    for(j = 0;j<1000;++j)
  650.        {;}
  651.   }
  652. }

  653. void Rec_DHTI0()
  654. {
  655. //主机信号
  656. DHTI0 = 1;        //拉高
  657. Delay1000ms();   //延时1s以上 等待状态稳定
  658. DHTI0 = 0;        //拉低
  659. Delay18ms();     //主机拉低25Ms
  660. DHTI0 = 1;        //拉高
  661. Delay40us();  //主机拉高40us
  662. //从机响应信号
  663. if(!DHTI0)
  664. {
  665.     while(!DHTI0);    //while(!0)==(1)判断从机是否发出80毫秒的低电平响应信号
  666.    while(DHTI0);     //判断从机是否发出80毫秒的高电平 , 发出则开始采集数据
  667.     RH_data = Read_8bit();  //温度整数部分
  668.     RL_data = Read_8bit();  //温度小数部分
  669.     TH_data = Read_8bit();  //湿度整数部分
  670.     TL_data = Read_8bit();  //湿度小数部分
  671.     CK_data = Read_8bit();  //校验位
  672.   
  673.     undata = RH_data + RL_data + TH_data + TL_data; //校验获取的数据
  674. }
  675. //湿度整数 (温湿度传感器存在疑惑)
  676. str1[0] = (char)(0x30 + RH_data/10);   //0x30将数字0-9转化为字符0-9
  677. str1[1] = (char)(0x30 + RH_data%10);
  678. //温度整数
  679. str2[0] = (char)(0x30 + TH_data/10);
  680. str2[1] = (char)(0x30 + TH_data%10);

  681. if(TH_data > 30)  //温度报警
  682. {
  683.    BeepHear();
  684. }


  685. }
  686. uchar Read_8bit()
  687. {
  688. uint i;
  689. uchar temp = 0;
  690. uchar dat;
  691. for(i = 0;i < 8;i++)
  692. {
  693.   //以下部分判断数据是0或是1
  694.   while(!DHTI0);  //等待50毫秒的低电平结束
  695.   Delay30us();
  696.    temp = 0;
  697.   if(DHTI0 == 1)
  698.   {
  699.    temp = 1;
  700.   }
  701.   while(DHTI0);   //等待高电平结束
  702.    dat<<=1;
  703.   dat = dat|temp;
  704. }
  705. return dat;
  706. }
  707. void  LCD_Display()
  708. {
  709.    

  710.     hanshuming();
  711.     print(3,1,lcd1);
  712.     print(4,1,lcd2);
  713. //  温度
  714. for(j = 0;j < 2;j++)
  715. {
  716.    //ad_ope(uchar x,uchar y)
  717.   ad_ope(3,j+4);  //显示位置,第3行,j为0或1,j+4为第几位开始显示
  718.   write_data(str2[j]);   //void write_data(uchar dat)
  719. }
  720. //  湿度
  721. for(k = 0;k < 2;k++)
  722. {
  723.   ad_ope(4,k+4);
  724.    write_data(str1[k]);
  725. }
  726. }
  727. void xianshi()
  728. {
  729.     //点亮第一个灯
  730.     led1 = 0;
  731.     led2 = 1;
  732.     led3 = 1;
  733.    
  734. //延时1s
  735.    delay1s();
  736.     //点亮第二个灯
  737.     led1 = 1;
  738.     led2 = 0;
  739.     led3 = 1;
  740.    
  741.     //延时1s
  742. delay1s();
  743.    
  744.     //点亮剩余的灯
  745.    
  746.     led1 = 1;
  747.     led2 = 1;
  748.     led3 = 0;
  749.    
  750. //延时1s
  751.    delay1s();
  752.     led1 = 1;
  753.     led2 = 1;
  754.     led3 = 1;
  755.    
  756. //延时1s
  757.    delay1s();
  758.     led1 = 1;
  759.     led2 = 1;
  760.     led3 = 1;
  761. //延时1s
  762. delay1s();
  763.    
  764. }
复制代码



  1.            
  2. /*******************************************************************************/  
  3. #ifndef __DS1302_H__
  4. #define __DS1302_H__

  5. #include "all.h"
  6. sbit SCLK =  P4^4;//串行时钟输入端口
  7. sbit DAT  =  P4^2;//数据IO端口
  8. sbit RST  =  P4^1;//复位输入端

  9. sbit K1=P3^4;
  10. sbit K2=P3^5;
  11. sbit K3=P3^2;  //右上角是这个按键电灯,触发了外部中断0
  12. sbit K4=P3^3;  //管脚接线

  13. #define  DS1302_SEC_ADD   0x80//秒
  14. #define  DS1302_MIN_ADD   0x82//分
  15. #define  DS1302_HR_ADD   0x84//时
  16. #define  DS1302_DAY_ADD   0x86//日
  17. #define  DS1302_MONTH_ADD  0x88//月
  18. #define  DS1302_WEEK_ADD   0x8A//星期
  19. #define  DS1302_YEAR_ADD   0x8C//年
  20. #define  DS1302_CONTROL_ADD  0x8E//控制
  21. #define  DS1302_CHARGER_ADD  0x90//涓流充电      
  22. #define  DS1302_CLKBURST_ADD  0xBE//时钟多字节

  23. extern void DS1302_Init();             //初始化DS1302
  24. extern void DS1302_Data_Input(unsigned char Address,unsigned char Data); //数据输入
  25. extern unsigned char DS1302_Data_Output(unsigned char Address);    //数据输出
  26. extern void DS1302_Write_Time(void);          //写入初始化时间
  27. extern void DS1302_Read_Time(void);           //读取时间

  28. #endif
复制代码
下载: 15可以设置闹钟时间的加减温度报警.zip (152.89 KB, 下载次数: 19)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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