找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 22471|回复: 34
收起左侧

lcd1602+DS3231+STC89C53单片机简单时钟制作

  [复制链接]
ID:76190 发表于 2015-4-5 16:07 | 显示全部楼层 |阅读模式
本帖最后由 xiashan 于 2015-4-5 16:14 编辑















1.bell.c
  1. #include "main.h"

  2. // 原始频率表,低音。
  3. uint code  FreTab[12]={262,277,293,311,329,349,370,392,415,440,466,494};
  4. // 1-7.
  5. uchar code  XY_Tab[7]={0,2,4,5,7,9,11};

  6. uint New_FreTab[12];

  7. void Delay_10MS()
  8. {
  9. uchar a,b;
  10. for(a = 50;a>0;a--)
  11.   {
  12.    for(b = 100;b>0;b--);
  13.   }
  14. }
  15. uchar YC_Tab[]={1,2,4,8,16,32,64};

  16. void Beep(uchar num)
  17. {
  18. uint i,j;
  19. uchar D=60,E=20;
  20. switch(num)
  21. {
  22.    case 1:      //开机响铃  ·
  23.    j=0;while(j<300){BEE=!BEE;for(i=0;i<D;i++){;}j++;};
  24.    break;
  25.    case 2:      //简单闹铃  ·
  26.    j=0;while(j<400){BEE=!BEE;for(i=0;i<E;i++){;}j++;}for(i=0;i<18;i++)Delay_10MS();
  27.    j=0;while(j<400){BEE=!BEE;for(i=0;i<E;i++){;}j++;}for(i=0;i<18;i++)Delay_10MS();
  28.    //j=0;while(j<400){BEE=!BEE;for(i=0;i<E;i++){;}j++;}for(i=0;i<12;i++)Delay_10MS();
  29.    j=0;while(j<500){BEE=!BEE;for(i=0;i<E;i++){;}j++;}
  30.    break;
  31.    case 3:      //操作按键响铃  ·
  32.    j=0;while(j<200){BEE=!BEE;for(i=0;i<30;i++){;}j++;};
  33.    break;           

  34.   case 4:     //整点报时响铃   —
  35.    j=0;while(j<2800){BEE=!BEE;for(i=0;i<D;i++){;}j++;}
  36.    break;   
  37. }
  38. BEE=1;
  39. }

  40. // QSD 0-11
  41. // SYD 1-3 1降8度 2不变,3升8度

  42. void JX_New_Few_FerTab(uchar QSD)
  43. {
  44. uchar i,j;

  45. for(i = 0 ;i <12;i++)    // 12次循环
  46.   {
  47.    j = i +QSD;    //根据起始调判断起始音符位置
  48.    if(j >11)     //如果起始调不是最低
  49.     {
  50.      j = j - 12;  // 0-11
  51.      New_FreTab[i] = FreTab[j]*2;// 频率*2
  52.     }
  53.    else        //频率不变
  54.     {
  55.      New_FreTab[i] = FreTab[j];
  56.     }
  57.    /*if(SYD == 1)      //判断升降调。1降调,2不变,3升调。
  58.     {
  59.      New_FreTab[i] >>= 1;//频率减一半
  60.     }
  61.    else
  62.     {
  63.      if(SYD == 3)
  64.       {
  65.        New_FreTab[i] <<= 1;
  66.       }
  67.     }*/
  68.   }
  69. }


  70. void Play_Music(uchar *Sound,uchar QSD)
  71. {
  72. uint GQ_CD = 0;     //歌曲长度
  73. uint GQ_WZ = 0;

  74. uchar GQ_YG = 0;
  75. uchar GQ_YC = 0;

  76. uint YP_PL = 0;

  77. uchar YG_Bai = 0;
  78. uchar YG_Shi = 0;
  79. uchar  YG_Ge = 0;

  80. uchar YC_Bai = 0;
  81. uchar YC_Shi = 0;
  82. uchar  YC_Ge = 0;

  83. uint DSD_PL = 0;

  84. uint YF0 = 0; // 1分音符变量
  85. uint YF1 = 0; // 发音长度时间
  86. uint YF2 = 0; //不发音长度时间
  87. uint YF4 = 0; // 4分音符时间

  88. uint FY_JG = 0;

  89. uint YZ_TC = 0;
  90. uint JF_YF = 0;

  91. uchar i =0;

  92. JX_New_Few_FerTab(QSD);

  93. while(Sound[GQ_CD] != 0)   //判断歌曲长度
  94.   {
  95.    GQ_CD += 2;    //指向下一位音符数据
  96.   }

  97. while(GQ_WZ<GQ_CD && Al_Flag==1)
  98.   {
  99.    GQ_YG = Sound[GQ_WZ];

  100.    YG_Bai = GQ_YG/100;  // 1升半音,0不升
  101.    YG_Shi = GQ_YG/10%10; // 1低音,2为中音,3为高音
  102.    YG_Ge = GQ_YG%10;  // 1-7 音符位;
  103.    YP_PL = New_FreTab[XY_Tab[YG_Ge -1] + YG_Bai];// yg_ge -1 1-7 0-6

  104.    if(YG_Ge != 0)
  105.     {
  106.      switch(YG_Shi)
  107.       {
  108.        case 2: YP_PL <<=1;break;
  109.        case 3: YP_PL <<=2;break;
  110.       }
  111.      DSD_PL = 65536-(50000/YP_PL)*10;
  112.      Time_H = DSD_PL >>8;
  113.      Time_L = DSD_PL & 0xFF;
  114.      TH0 = Time_H;
  115.      TL0 = Time_L;
  116.     }


  117.    GQ_YC = Sound[GQ_WZ +1];

  118.    YC_Bai = GQ_YC/100;  // 1有符点,0无符点
  119.    YC_Shi = GQ_YC/10%10; // 演奏效果0普通,1连音,2顿音
  120.    YC_Ge = GQ_YC%10;  // 几分音符。

  121.    YF0 = YF_YF;
  122.    YF4 = YF0 /4;
  123.    FY_JG =YF4- YF4 *SFYF_JG;

  124.    JF_YF = YC_Tab[YC_Ge];// 几分音符;
  125.    YZ_TC = YF0 /JF_YF;   // 算出对应延时长度多少个10MS
  126.    
  127.    if(YC_Bai == 1)   //判断是否有符点
  128.     {
  129.      YZ_TC = YZ_TC+YZ_TC/2;//有符点
  130.     }

  131.    if(YC_Shi != 1)   //不是连音
  132.     {
  133.      if(YC_Shi == 0) //是否为普通音
  134.       {
  135.        if(JF_YF <= 4) // 是否小于16分音
  136.         {
  137.          YF1 = YZ_TC -FY_JG; // 发音有间隔
  138.         }
  139.        else   // 不小于16分音
  140.         {
  141.          YF1 = YZ_TC * SFYF_JG;//发音无音隔
  142.         }
  143.       }
  144.      else     //是顿音,演奏时间为原来的一半
  145.       {
  146.        YF1 = YZ_TC /2;
  147.       }
  148.     }
  149.    else       //是连音,发音无音隔
  150.     {
  151.      YF1 = YZ_TC;
  152.     }

  153.    if(YG_Ge == 0)    //没有音符数据
  154.     {
  155.      YF1 = 0;    //演奏时间 = 0
  156.     }
  157.    else       //有音符数据
  158.     {
  159.      YF2 = YZ_TC - YF1;

  160.      TR0 =1;
  161.      for(i = YF1; i >0;i --)
  162.       {
  163.        Delay_10MS();
  164.       }
  165.      BEE = 1;
  166.      TR0 = 0;
  167.      for(i = YF2; i >0;i --)
  168.       {
  169.        Delay_10MS();
  170.       }     
  171.     }
  172.    GQ_WZ += 2;     //指向下一个音符
  173.    
  174.   }
  175. }
复制代码

2.bell.h
  1. #ifndef __BELL_H__
  2. #define __BELL_H__

  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5. #define YF_YF  160
  6. #define SFYF_JG 4/5

  7. sbit BEE = P3 ^ 4;

  8. void Beep(uchar num);
  9. void Delay_10MS(void);
  10. void JX_New_Few_FerTab(uchar QSD);
  11. void Play_Music(uchar *Sound,uchar QSD);

  12. #endif
复制代码


3.DS18B20.C
  1. #include "main.h"

  2. uchar temp_I;//测量到的温度的整数部分
  3. uchar xiaoshu1;//小数第一位
  4. //uchar xiaoshu,xiaoshu2;//小数第二位
  5. bit  fg=1;        //温度正负标志,等于0时为负数

  6. //温度处理程序
  7. /***********ds18b20子程序*************************/

  8. /***********ds18b20延迟子函数(晶振12MHz )*******/

  9. void delay_18B20(uchar i)
  10. {
  11.     while(--i);
  12. }

  13. void delay500(void)   //12M延时500us,误差 0us
  14. {
  15.     uchar a,b;
  16.     for(b=71;b>0;b--)
  17.         for(a=2;a>0;a--);
  18. }

  19. /**********ds18b20初始化函数**********************/

  20. bit Init_DS18B20()
  21. {
  22.   bit x=0;
  23.   DQ = 1;          //DQ复位
  24.   delay_18B20(16);  //稍做延时
  25.   DQ = 0;          //单片机将DQ拉低
  26.   delay500(); //精确延时480us-960us
  27.   DQ = 1;          //拉高总线
  28.   delay_18B20(27);//等待60us
  29.   x=DQ;            //如果返回脉冲为低则初始化成功 x=1则初始化失败
  30.   delay_18B20(238); //延时,DS18B20释放总线
  31.   return x;
  32. }

  33. /***********ds18b20读一个字节**************/

  34. uchar ReadOneChar()
  35. {
  36. uchar i=0;
  37. uchar dat = 0;
  38. for (i=8;i>0;i--)
  39. {
  40.   DQ = 0; // 给脉冲信号
  41.   dat>>=1;
  42.   DQ = 1; // 给脉冲信号
  43.   delay_18B20(1);//等待7us
  44.   if(DQ){dat|=0x80;}
  45.   delay_18B20(20);//延时40us,读数据结束
  46.   DQ = 1;
  47.   delay_18B20(1);
  48.   }
  49.   return(dat);
  50. }

  51. /*************ds18b20写一个字节****************/

  52. void WriteOneChar(uchar dat)
  53. {
  54.   uchar i=0;
  55.   for (i=8; i>0; i--)
  56.   {
  57.     DQ = 0;
  58.      delay_18B20(5);
  59.    DQ = dat&0x01;
  60.      delay_18B20(20);
  61.    DQ = 1;
  62.      dat>>=1;
  63. }
  64. }

  65. /**************设定温度精度为10位******************************/
  66. void Write_18B20()
  67. {
  68. if(Init_DS18B20()==0){
  69.   WriteOneChar(0xCC);           //跳过读序号列号的操作
  70.   WriteOneChar(0x4E);           //将设定的温度报警值写入 DS18B20
  71.   WriteOneChar(0x64);  //写TH
  72.   WriteOneChar(0x00);  //写TL
  73.   WriteOneChar(0x3F);           //10位精确度

  74.   Init_DS18B20();
  75.   WriteOneChar(0xCC);           //跳过读序号列号的操作
  76.   WriteOneChar(0x48);           //把暂存器里的温度报警值拷贝到EEROM
  77. }
  78. }

  79. /**************读取ds18b20当前温度************
  80. /*****************************************************************************************
  81. **函数名:ReadTemperature(void)
  82. **输  入:
  83. **输  出:
  84. **说  明:读温度值(低位放tempL;高位放tempH;)
  85. ******************************************************************************************/
  86. bit ReadTemp()
  87. {
  88. uchar tempL,tempH;
  89. if(Init_DS18B20()==0){
  90.   WriteOneChar(0xCC); //跳过读序列号的操作
  91.   WriteOneChar(0x44); //启动温度转换

  92.   Init_DS18B20();
  93.   WriteOneChar(0xCC); //跳过读序列号的操作
  94.   WriteOneChar(0xBE); //读温度寄存器(头两个值分别为温度的低位和高位)
  95.   tempL=ReadOneChar(); //读出温度的低位LSB
  96.   tempH=ReadOneChar(); //读出温度的高位MSB
  97.   
  98.   if(tempH>0x7f)      //最高位为1时温度是负
  99.   {
  100.    tempL=~tempL+1;         //补码转换,取反加一
  101.    tempH=~tempH;      
  102.    fg=1;      //读取温度为负时fg=1
  103.   }
  104.   else fg=0;
  105.   temp_I = tempL/16+tempH*16;      //整数部分
  106.   xiaoshu1 = (tempL&0x0f)*10/16; //小数第一位
  107.   //xiaoshu2 = (tempL&0x0f)*100/16;//小数第二位
  108.   //xiaoshu=xiaoshu1*10+xiaoshu2; //小数两位
  109.   return 0;
  110. }
  111. else return 1;
  112. }
  113. //温度处理程序结束
复制代码

4.DS18B20.H
  1. #ifndef __DS18B20_H__
  2. #define __DS18B20_H__

  3. //DS18B20管脚定义
  4. sbit DQ = P1^0;

  5. extern uchar temp_I;
  6. extern bit fg;

  7. extern bit Init_DS18B20();
  8. void Write_18B20();
  9. extern bit ReadTemp();


  10. #endif#ifndef __DS18B20_H__
  11. #define __DS18B20_H__

  12. //DS18B20管脚定义
  13. sbit DQ = P1^0;

  14. extern uchar temp_I;
  15. extern bit fg;

  16. extern bit Init_DS18B20();
  17. void Write_18B20();
  18. extern bit ReadTemp();


  19. #endif
复制代码

5.DS3231.C
  1. #include "DS3231.H"

  2. /************************* Global Variables ***************************/
  3. xdata   uchar   sec, min, hour, day, date, month, year;
  4. xdata uchar  Dtemp;

  5. /**************************** functions ******************************/
  6. void delay()
  7. {
  8.   ;;
  9. }

  10. void start()            /* --------- Initiate start condition ---------- */
  11. {
  12. sda = 1; delay();
  13. scl = 1; delay();
  14. sda = 0; delay();
  15. scl = 0;
  16. }
  17. void stop()             /* ---------- Initiate stop condition ----------- */
  18. {
  19. sda = 0; delay();
  20. scl = 1; delay();
  21. sda = 1; delay();
  22. scl = 0;
  23. }

  24. void i2cack()
  25. {
  26. uchar i=0;
  27. scl=1;delay();
  28. while(sda==1 && i<255) i++;
  29. scl=0;delay();
  30. }
  31. void i2cwrite(uchar d)         /* ----------------------------- */
  32. {
  33. uchar i;

  34.   scl = 0;
  35.      for (i = 0;i < 8; i++)
  36.      {
  37.             sda = d & 0x80; /* Send the msbits first */
  38.          scl = 0;delay();
  39.    scl = 1;delay();
  40.          d = d << 1;     /* do shift here to increase scl high time */
  41.          scl = 0;
  42.      }
  43.      sda = 1;delay();        /* Release the sda line */
  44.      scl = 0;delay();
  45. }

  46. uchar i2cread(uchar b)   /* ----------------------------------- */
  47. {
  48. uchar i, d;

  49.         d = 0;
  50.         sda = 1;delay();             /* Let go of sda line */
  51.         scl = 0;delay();
  52.         for (i = 0; i < 8; i++) /* read the msb first */
  53.         {
  54.                 scl = 1;delay();
  55.     d = d << 1;
  56.     d = d | (uchar)sda;
  57.                 scl = 0;delay();
  58.         }
  59.         sda = b;delay();          /* low for ack, high for nack */
  60.         scl = 1;delay();
  61.         scl = 0;delay();
  62.         sda = 1;delay();          /* Release the sda line */
  63.         return d;
  64. }
  65. void i2cwrite_add(uchar address,uchar dat)//指定地址写一个字节数据
  66. {
  67. start();
  68. i2cwrite(ADDRTC);
  69. i2cack();
  70. i2cwrite(address);
  71. i2cack();
  72. i2cwrite(dat);
  73. i2cack();
  74. stop();
  75. }
  76. uchar i2cread_add(uchar address)
  77. //指定地址读一个字节数据
  78. {
  79. uchar dd;
  80. start();
  81. i2cwrite(ADDRTC);
  82. i2cack();
  83. i2cwrite(address);
  84. i2cack();
  85. start();
  86. i2cwrite(ADDRTC);
  87. i2cack();
  88. dd=i2cread(0);
  89. stop();
  90. return dd;
  91. }

  92. void    InitDS3231()     /* ----- set time & date; user data entry ------ */
  93. {
  94.   scl=1;delay();
  95.   sda=1;delay();

  96.      start();
  97.      i2cwrite(ADDRTC);       /* write slave address, write 1339 */
  98.      i2cwrite(0x00);  /* write register address, 1st clock register */
  99.      i2cwrite(0x00); //秒
  100.      i2cwrite(0x01); //分
  101.      i2cwrite(0x01); //时
  102.      i2cwrite(0x03); //星期
  103.      i2cwrite(0x12); //日
  104.      i2cwrite(0x01); //月
  105.      i2cwrite(0x11); //年
  106.      //i2cwrite(0x10); /* enable sqw, 1hz output */
  107.      stop();
  108. }
  109. void    GetTime()     /* --- get date/time from DS3231 --- */
  110. {
  111.         //while(int0);    /* loop until int pin goes low */
  112.         //start();
  113.         //i2cwrite(ADDRTC);
  114.         //i2cwrite(0x0f);
  115.         //i2cwrite(0);            /* clear alarm flags */
  116.         //stop();

  117.         start();
  118.         i2cwrite(ADDRTC);
  119.         i2cwrite(0);
  120.         start();
  121.         i2cwrite(ADDRTC | 1);
  122.         sec = i2cread(ACK);
  123.         min = i2cread(ACK);
  124.         hour= i2cread(ACK);
  125.         day = i2cread(ACK);
  126.         date= i2cread(ACK);
  127.         month= i2cread(ACK);
  128.         year= i2cread(NACK);
  129.         stop();
  130. }

  131. void    read_temp()       /* -------- read temperature -------- */
  132. {
  133. int     itemp;
  134. float   ftemp;

  135.         do
  136.         {
  137.                 start();
  138.                 i2cwrite(ADDRTC);
  139.                 i2cwrite(0x0e);         /* address of control register */
  140.                 start();
  141.                 i2cwrite(ADDRTC + 1);   /* send the device address for read */
  142.                 itemp = i2cread(NACK);  /* get the control register value */
  143.                 stop();
  144.         }       while(itemp & 0x20);            /* wait until CNVT bit goes inactive */

  145.         start();
  146.         i2cwrite(ADDRTC);
  147.         i2cwrite(0x11);                 /* address of temperature MSB */
  148.         start();
  149.         i2cwrite(ADDRTC + 1);           /* send the device address for read */
  150.         itemp = ( (int) i2cread(ACK) << 5 );
  151.         itemp += ( i2cread(NACK) >> 3);
  152.         stop();
  153.         if(itemp & 0x1000)      itemp += 0xe000;        /* if sign bit set, make 16 bit 2's comp */

  154.         ftemp = 0.03125 * (float) itemp;        /* convert to degrees C */
  155.         /* ftemp = ftemp * 9 / 5 + 32;  /* skip this if you don't want degrees F */
  156.   Dtemp  = (uchar) ftemp;
  157. }

  158. /*void    frq_out_tog()   // --- toggle en32khz bit to enable/disable sqw ---
  159. {
  160. uchar   val;

  161.         start();
  162.         i2cwrite(ADDRTC);
  163.         i2cwrite(0x0f);                 // control/status reg address
  164.         start();
  165.         i2cwrite(ADDRTC + 1);           //send the device address for read
  166.         val = i2cread(NACK);
  167.         stop();
  168.         val ^= 0x08;    //toggle en32khz bit
  169.         start();
  170.         i2cwrite(ADDRTC);
  171.         i2cwrite(0x0f);                 //control/status reg address
  172.         i2cwrite(val);
  173.         stop();
  174. }*/

  175. void    init_alrm()     /* --- enable alarm 1 for once-per-second --- */
  176. {
  177.         start();
  178.         i2cwrite(ADDRTC);
  179.         i2cwrite(7);            /* 1st alarm 1 reg address */
  180.         i2cwrite(0x80); /* mask alarm register */
  181.         i2cwrite(0x80);
  182.         i2cwrite(0x80);
  183.         i2cwrite(0x80);
  184.         stop();

  185.         start();
  186.         i2cwrite(ADDRTC);
  187.         i2cwrite(0x0e); /* control/status reg address */
  188.         i2cwrite(0x05); /* enable interrupts, alarm 1 output */
  189. }
  190. void    comm_init()     /* ------ reset DS3231 comm interface ------ */
  191. {
  192.         do      /* because the DS3231 I2C interface is active for both supplies */
  193.         {       /*  after a micro reset, we must get the comm into a known state */
  194.                 sda = 1;        /* make sure master has released SDA */
  195.                 scl = 1;
  196.                 if(sda) /* if sda is high, generate a start */
  197.                 {
  198.                         sda = 0;        /* The DS3231 will recognize a valid start */
  199.                         sda = 1;        /*  condition anywhere in a I2C data transfer */
  200.                 }
  201.                 scl = 0;
  202.         }       while(sda == 0);        /* if the DS3231 is holding sda low, try again */
  203. }
复制代码

6.DS3231.H
  1. #ifndef __DS3231_H__
  2. #define __DS3231_H__

  3. #include <reg52.h>
  4. #include <intrins.h>

  5. #define uchar unsigned char
  6. #define uint  unsigned int

  7. sbit    scl = P1^7;             /* I2C pin definitions */
  8. sbit    sda = P1^6;
  9. sbit    int0 = P3^2;
  10. /**************************** defines *******************************/
  11. #define ADDRTC  0xd0    /* DS3231 slave address (write) */
  12. #define ACK     0
  13. #define NACK    1

  14. extern xdata   uchar   sec, min, hour, day, date, month, year,Dtemp;

  15. /*********************** Function Prototypes **************************/
  16. void    start();
  17. void    stop();
  18. void   i2cwrite(uchar d);
  19. uchar   i2cread(uchar b);
  20. void    writebyte();
  21. void    Init_DS3231();
  22. //void    frq_out_tog();
  23. void    init_alrm();
  24. void    comm_init();
  25. void GetTime(void);
  26. void SetTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec);
  27. void i2cwrite_add(uchar address,uchar dat);
  28. uchar i2cread_add(uchar address);
  29. void InitDS3231();
  30. void    read_temp();

  31. #endif
复制代码



7.KEY.C
  1. #include "MAIN.H"

  2. xdata uchar keyvalue,SetFlag=0;

  3. void Scan_Key()
  4. {
  5. uchar a=80;
  6. if(SET==0)
  7.     {
  8.         Delay5Ms();
  9.   if(SET==0)
  10.         {
  11.             keyvalue=1;
  12.    Beep(3);
  13.    Disp_b=0; //开始返回菜单计时
  14.         }
  15.         while((SET==0)&&a)
  16.   {
  17.    --a;
  18.    Delay5Ms();
  19.   }
  20.     }
  21.     if(UP==0)
  22.     {
  23.         Delay5Ms();
  24.         if(UP==0)
  25.         {
  26.    keyvalue=2;
  27.    Beep(3);
  28.    Disp_b=0;
  29.         }
  30.         while((UP==0)&&a)
  31.   {
  32.    --a;
  33.    Delay5Ms();
  34.   }
  35.     }
  36.     if(DOWN==0)
  37.     {         
  38.         Delay5Ms();
  39.         if(DOWN==0)
  40.         {
  41.             keyvalue=3;
  42.    Beep(3);
  43.    Disp_b=0;
  44.         }
  45.         while((DOWN==0)&&a)
  46.   {
  47.    --a;
  48.    Delay5Ms();
  49.   }
  50.     }
  51. }

  52. void KeyProcess()//时钟设置程序
  53. {
  54. if(keyvalue==1)
  55. {
  56.   //DisplayStr(0,0,"    Time Set    ");
  57. //      ----------------
  58.   SetFlag++;
  59.   if(SetFlag==14) {SetFlag=0;Disp_Time();}
  60.   keyvalue=0;
  61. }
  62. switch(SetFlag)
  63. {
  64.   case 1:
  65.   {
  66.    Readtime();
  67.    DisplayStr(0,0,"    Adj Year    ");
  68. //       ----------------
  69.    DisplayStr(0,1,"20");
  70.    DisplayChar(2,1,Flash?(year/10+0x30):' ');
  71.    DisplayChar(3,1,Flash?(year%10+0x30):' ');
  72.    DisplayChar(4,1,0x00);
  73.    DisplayChar(5,1,month/10+0x30);
  74.    DisplayChar(6,1,month%10+0x30);
  75.    DisplayChar(7,1,0x01);
  76.    DisplayChar(8,1,date/10+0x30);
  77.    DisplayChar(9,1,date%10+0x30);
  78.    DisplayChar(10,1,0x02);
  79.    DisplayChar(11,1,' ');
  80.    switch(day)
  81.    {
  82.     case 1:DisplayStr(12,1,"Mon");break;
  83.     case 2:DisplayStr(12,1,"Tue");break;
  84.     case 3:DisplayStr(12,1,"Wed");break;
  85.     case 4:DisplayStr(12,1,"Thu");break;
  86.     case 5:DisplayStr(12,1,"Fri");break;
  87.     case 6:DisplayStr(12,1,"Sat");break;
  88.     case 7:DisplayStr(12,1,"Sun");break;
  89.     default :DisplayStr(12,1,"ERR");break;
  90.    }
  91.    DisplayChar(15,1,' ');
  92.    if(keyvalue==2&&SetFlag==1) //年+
  93.       {
  94.           Set(6,0);
  95.           keyvalue=0;
  96.       }
  97.    if(keyvalue==3&&SetFlag==1) //年-
  98.       {
  99.           Set(6,1);
  100.           keyvalue=0;
  101.       }
  102.      }
  103.   break;

  104.   case 2:
  105.   {
  106.    Readtime();
  107.    DisplayStr(0,0,"    Adj Month   ");
  108. //       ----------------
  109.    DisplayStr(0,1,"20");
  110.    DisplayChar(2,1,year/10+0x30);
  111.    DisplayChar(3,1,year%10+0x30);
  112.    DisplayChar(4,1,0x00);
  113.    DisplayChar(5,1,Flash?(month/10+0x30):' ');
  114.    DisplayChar(6,1,Flash?(month%10+0x30):' ');
  115.    DisplayChar(7,1,0x01);
  116.    DisplayChar(8,1,date/10+0x30);
  117.    DisplayChar(9,1,date%10+0x30);
  118.    DisplayChar(10,1,0x02);
  119.    DisplayChar(11,1,' ');
  120.    switch(day)
  121.    {
  122.     case 1:DisplayStr(12,1,"Mon");break;
  123.     case 2:DisplayStr(12,1,"Tue");break;
  124.     case 3:DisplayStr(12,1,"Wed");break;
  125.     case 4:DisplayStr(12,1,"Thu");break;
  126.     case 5:DisplayStr(12,1,"Fri");break;
  127.     case 6:DisplayStr(12,1,"Sat");break;
  128.     case 7:DisplayStr(12,1,"Sun");break;
  129.     default :DisplayStr(12,1,"ERR");break;
  130.    }
  131.    DisplayChar(15,1,' ');
  132.    if(keyvalue==2&&SetFlag==2) //月+
  133.       {
  134.           Set(5,0);
  135.           keyvalue=0;
  136.       }
  137.    if(keyvalue==3&&SetFlag==2) //月-
  138.       {
  139.           Set(5,1);
  140.           keyvalue=0;
  141.       }
  142.      }
  143.   break;

  144.   case 3:
  145.   {
  146.    Readtime();
  147.    DisplayStr(0,0,"    Adj Date    ");
  148. //       ----------------
  149.    DisplayStr(0,1,"20");
  150.    DisplayChar(2,1,year/10+0x30);
  151.    DisplayChar(3,1,year%10+0x30);
  152.    DisplayChar(4,1,0x00);
  153.    DisplayChar(5,1,month/10+0x30);
  154.    DisplayChar(6,1,month%10+0x30);
  155.    DisplayChar(7,1,0x01);
  156.    DisplayChar(8,1,Flash?(date/10+0x30):' ');
  157.    DisplayChar(9,1,Flash?(date%10+0x30):' ');
  158.    DisplayChar(10,1,0x02);
  159.    DisplayChar(11,1,' ');
  160.    switch(day)
  161.    {
  162.     case 1:DisplayStr(12,1,"Mon");break;
  163.     case 2:DisplayStr(12,1,"Tue");break;
  164.     case 3:DisplayStr(12,1,"Wed");break;
  165.     case 4:DisplayStr(12,1,"Thu");break;
  166.     case 5:DisplayStr(12,1,"Fri");break;
  167.     case 6:DisplayStr(12,1,"Sat");break;
  168.     case 7:DisplayStr(12,1,"Sun");break;
  169.     default :DisplayStr(12,1,"ERR");break;
  170.    }
  171.    DisplayChar(15,1,' ');
  172.    if(keyvalue==2&&SetFlag==3) //日+
  173.       {
  174.           Set(4,0);
  175.           keyvalue=0;
  176.       }
  177.    if(keyvalue==3&&SetFlag==3) //日-
  178.       {
  179.           Set(4,1);
  180.           keyvalue=0;
  181.       }
  182.      }
  183.   break;

  184.   case 4:
  185.   {
  186.    Readtime();
  187.    DisplayStr(0,0,"    Adj Hour    ");
  188. //       ----------------
  189.    DisplayChar(0,1,month/10+0x30);
  190.    DisplayChar(1,1,month%10+0x30);
  191.    DisplayChar(2,1,0x01);
  192.    DisplayChar(3,1,date/10+0x30);
  193.    DisplayChar(4,1,date%10+0x30);
  194.    DisplayChar(5,1,0x02);
  195.    DisplayChar(6,1,' ');
  196.    DisplayChar(7,1,' ');
  197.    DisplayChar(8,1,Flash?(hour/10+0x30):' ');
  198.    DisplayChar(9,1,Flash?(hour%10+0x30):' ');
  199.    DisplayChar(10,1,':');
  200.    DisplayChar(11,1,min/10+0x30);
  201.    DisplayChar(12,1,min%10+0x30);
  202.    DisplayChar(13,1,':');
  203.    DisplayChar(14,1,sec/10+0x30);
  204.    DisplayChar(15,1,sec%10+0x30);
  205.    if(keyvalue==2&&SetFlag==4) //时+
  206.    {
  207.        Set(2,0);
  208.        keyvalue=0;
  209.    }
  210.    if(keyvalue==3&&SetFlag==4) //时-
  211.    {
  212.        Set(2,1);
  213.        keyvalue=0;
  214.    }
  215.      }
  216.   break;

  217.   case 5:
  218.   {
  219.    Readtime();
  220.    DisplayStr(0,0,"   Adj Minute   ");
  221. //       ----------------
  222.    DisplayChar(0,1,month/10+0x30);
  223.    DisplayChar(1,1,month%10+0x30);
  224.    DisplayChar(2,1,0x01);
  225.    DisplayChar(3,1,date/10+0x30);
  226.    DisplayChar(4,1,date%10+0x30);
  227.    DisplayChar(5,1,0x02);
  228.    DisplayChar(6,1,' ');
  229.    DisplayChar(7,1,' ');
  230.    DisplayChar(8,1,hour/10+0x30);
  231.    DisplayChar(9,1,hour%10+0x30);
  232.    DisplayChar(10,1,':');
  233.    DisplayChar(11,1,Flash?(min/10+0x30):' ');
  234.    DisplayChar(12,1,Flash?(min%10+0x30):' ');
  235.    DisplayChar(13,1,':');
  236.    DisplayChar(14,1,sec/10+0x30);
  237.    DisplayChar(15,1,sec%10+0x30);
  238.    if(keyvalue==2&&SetFlag==5) //分+
  239.    {
  240.        Set(1,0);
  241.        keyvalue=0;
  242.    }
  243.    if(keyvalue==3&&SetFlag==5) //分-
  244.    {
  245.        Set(1,1);
  246.        keyvalue=0;
  247.    }
  248.   }
  249.   break;

  250.   case 6:
  251.   {
  252.    Readtime();
  253.    DisplayStr(0,0,"   Adj Second   ");
  254. //       ----------------
  255.    DisplayChar(0,1,month/10+0x30);
  256.    DisplayChar(1,1,month%10+0x30);
  257.    DisplayChar(2,1,0x01);
  258.    DisplayChar(3,1,date/10+0x30);
  259.    DisplayChar(4,1,date%10+0x30);
  260.    DisplayChar(5,1,0x02);
  261.    DisplayChar(6,1,' ');
  262.    DisplayChar(7,1,' ');
  263.    DisplayChar(8,1,hour/10+0x30);
  264.    DisplayChar(9,1,hour%10+0x30);
  265.    DisplayChar(10,1,':');
  266.    DisplayChar(11,1,min/10+0x30);
  267.    DisplayChar(12,1,min%10+0x30);
  268.    DisplayChar(13,1,':');
  269.    DisplayChar(14,1,Flash?(sec/10+0x30):' ');
  270.    DisplayChar(15,1,Flash?(sec%10+0x30):' ');
  271.    if(keyvalue==2&&SetFlag==6) //秒+
  272.       {
  273.           Set(0,0);
  274.           keyvalue=0;
  275.       }
  276.    if(keyvalue==3&&SetFlag==6) //秒-
  277.       {
  278.           Set(0,1);
  279.           keyvalue=0;
  280.       }
  281.      }
  282.   break;

  283.   case 7:
  284.   {
  285.    ReadAlarm();
  286.    DisplayStr(0,0,"   Alarm1 Set   ");
  287. //       ----------------
  288. //       ALARM1 OFF **:**
  289.    DisplayStr(0,1,"ALARM1");
  290.    DisplayChar(6,1,' ');
  291.    if((I2CReadAdd(DS3231_CONTROL) & 0x01)==0) DisplayStr(7,1,Flash?("   "):("OFF"));
  292.    else DisplayStr(7,1,Flash?("   "):(" ON"));
  293.    DisplayChar(10,1,' ');
  294.    DisplayChar(11,1,al1_hour/10+0x30);
  295.    DisplayChar(12,1,al1_hour%10+0x30);
  296.    DisplayChar(13,1,':');
  297.    DisplayChar(14,1,al1_min/10+0x30);
  298.    DisplayChar(15,1,al1_min%10+0x30);
  299.    if((keyvalue==2||keyvalue==3)&&SetFlag==7) //闹铃1开关
  300.       {
  301.           Set(50,1);
  302.           keyvalue=0;
  303.       }
  304.      }
  305.   break;

  306.   case 8:
  307.   {
  308.    ReadAlarm();
  309.    DisplayStr(0,0,"  AL1 Adj Hour  ");
  310. //       ----------------
  311.    DisplayStr(0,1,"ALARM1");
  312.    DisplayChar(6,1,' ');
  313.    DisplayStr(7,1,(I2CReadAdd(DS3231_CONTROL) & 0x01)?(" ON"):("OFF"));
  314.    DisplayChar(10,1,' ');
  315.    DisplayChar(11,1,Flash?(al1_hour/10+0x30):' ');
  316.    DisplayChar(12,1,Flash?(al1_hour%10+0x30):' ');
  317.    DisplayChar(13,1,':');
  318.    DisplayChar(14,1,al1_min/10+0x30);
  319.    DisplayChar(15,1,al1_min%10+0x30);
  320.    if(keyvalue==2&&SetFlag==8) //闹铃1时+
  321.       {
  322.           Set(9,0);
  323.           keyvalue=0;
  324.       }
  325.    if(keyvalue==3&&SetFlag==8) //闹铃1时-
  326.       {
  327.           Set(9,1);
  328.           keyvalue=0;
  329.       }
  330.      }
  331.   break;

  332.   case 9:
  333.   {
  334.    ReadAlarm();
  335.    DisplayStr(0,0," AL1 Adj Minute ");
  336. //       ----------------
  337.    DisplayStr(0,1,"ALARM1");
  338.    DisplayChar(6,1,' ');
  339.    DisplayStr(7,1,(I2CReadAdd(DS3231_CONTROL) & 0x01)?(" ON"):("OFF"));
  340.    DisplayChar(10,1,' ');
  341.    DisplayChar(11,1,al1_hour/10+0x30);
  342.    DisplayChar(12,1,al1_hour%10+0x30);
  343.    DisplayChar(13,1,':');
  344.    DisplayChar(14,1,Flash?(al1_min/10+0x30):' ');
  345.    DisplayChar(15,1,Flash?(al1_min%10+0x30):' ');
  346.    if(keyvalue==2&&SetFlag==9) //闹铃1分+
  347.       {
  348.           Set(8,0);
  349.           keyvalue=0;
  350.       }
  351.    if(keyvalue==3&&SetFlag==9) //闹铃1分-
  352.       {
  353.           Set(8,1);
  354.           keyvalue=0;
  355.       }
  356.      }
  357.   break;

  358.   case 10:
  359.   {
  360.    ReadAlarm();
  361.    DisplayStr(0,0,"   Alarm2 Set   ");
  362. //       ----------------
  363. //       ALARM2 OFF **:**
  364.    DisplayStr(0,1,"ALARM2");
  365.    DisplayChar(6,1,' ');
  366.    if((I2CReadAdd(DS3231_CONTROL) & 0x02)==0) DisplayStr(7,1,Flash?("   "):("OFF"));
  367.    else DisplayStr(7,1,Flash?("   "):(" ON"));
  368.    DisplayChar(10,1,' ');
  369.    DisplayChar(11,1,al2_hour/10+0x30);
  370.    DisplayChar(12,1,al2_hour%10+0x30);
  371.    DisplayChar(13,1,':');
  372.    DisplayChar(14,1,al2_min/10+0x30);
  373.    DisplayChar(15,1,al2_min%10+0x30);
  374.    if((keyvalue==2||keyvalue==3)&&SetFlag==10) //闹铃2开关
  375.       {
  376.           Set(60,1);
  377.           keyvalue=0;
  378.       }
  379.      }
  380.   break;

  381.   case 11:
  382.   {
  383.    ReadAlarm();
  384.    DisplayStr(0,0,"  AL2 Adj Hour  ");
  385. //       ----------------
  386.    DisplayStr(0,1,"ALARM2");
  387.    DisplayChar(6,1,' ');
  388.    DisplayStr(7,1,(I2CReadAdd(DS3231_CONTROL) & 0x02)?(" ON"):("OFF"));
  389.    DisplayChar(10,1,' ');
  390.    DisplayChar(11,1,Flash?(al2_hour/10+0x30):' ');
  391.    DisplayChar(12,1,Flash?(al2_hour%10+0x30):' ');
  392.    DisplayChar(13,1,':');
  393.    DisplayChar(14,1,al2_min/10+0x30);
  394.    DisplayChar(15,1,al2_min%10+0x30);
  395.    if(keyvalue==2&&SetFlag==11) //闹铃2时+
  396.       {
  397.           Set(12,0);
  398.           keyvalue=0;
  399.       }
  400.    if(keyvalue==3&&SetFlag==11) //闹铃2时-
  401.       {
  402.           Set(12,1);
  403.           keyvalue=0;
  404.       }
  405.      }
  406.   break;

  407.   case 12:
  408.   {
  409.    ReadAlarm();
  410.    DisplayStr(0,0," AL2 Adj Minute ");
  411. //       ----------------
  412.    DisplayStr(0,1,"ALARM2");
  413.    DisplayChar(6,1,' ');
  414.    DisplayStr(7,1,(I2CReadAdd(DS3231_CONTROL) & 0x02)?(" ON"):("OFF"));
  415.    DisplayChar(10,1,' ');
  416.    DisplayChar(11,1,al2_hour/10+0x30);
  417.    DisplayChar(12,1,al2_hour%10+0x30);
  418.    DisplayChar(13,1,':');
  419.    DisplayChar(14,1,Flash?(al2_min/10+0x30):' ');
  420.    DisplayChar(15,1,Flash?(al2_min%10+0x30):' ');
  421.    if(keyvalue==2&&SetFlag==12) //闹铃2分+
  422.       {
  423.           Set(11,0);
  424.           keyvalue=0;
  425.       }
  426.    if(keyvalue==3&&SetFlag==12) //闹铃2分-
  427.       {
  428.           Set(11,1);
  429.           keyvalue=0;
  430.       }
  431.      }
  432.   break;

  433.   case 13:
  434.   {
  435.    DisplayStr(0,0,"   Sound Set    ");
  436. //       ----------------
  437.    DisplayStr(0,1,"Sound:");
  438.    DisplayChar(6,1,Flash?' ':((uchar)aa+0x30));
  439.    DisplayChar(7,1,' ');
  440.    DisplayStr(8,1,aa?"Music   ":"Beep    ");
  441.    if((keyvalue==2||keyvalue==3)&&SetFlag==13) //闹铃铃声选择
  442.       {
  443.           aa=!aa;
  444.           keyvalue=0;
  445.       }
  446.      }
  447.   break;
  448. }

  449. if(SetFlag==0&&keyvalue==2)
  450. {
  451.   SetFlag=7;
  452.   keyvalue=0;
  453. }
  454. }


  455. void Set(uchar sel,uchar selby)
  456. {
  457. char item;
  458.     uchar max,mini;

  459.     if(sel==0)  {max=59;mini=0;}    //秒
  460.     if(sel==1)  {max=59;mini=0;}    //分钟
  461.     if(sel==2)  {max=23;mini=0;}    //小时
  462. if(month==2)
  463.   if(runnian())
  464.   {
  465.    if(sel==4)  {max=29;mini=1;}
  466.   }
  467.   else
  468.   {
  469.    if(sel==4)  {max=28;mini=1;}
  470.   }
  471. else
  472. {
  473.      if(month==1|month==3|month==5|month==7|month==8|month==10|month==12)
  474.   {   
  475.    if(sel==4)  {max=31;mini=1;}
  476.   }
  477.   if(month==4|month==6|month==9|month==11)
  478.   {   
  479.    if(sel==4)  {max=30;mini=1;}
  480.   }
  481. }
  482.     if(sel==5)  {max=12;mini=1;}    //月
  483.     if(sel==6)  {max=99;mini=0;}    //年
  484.     if(sel==8)  {max=59;mini=0;}    //闹铃1小时
  485.     if(sel==9)  {max=23;mini=0;}    //闹铃1分钟
  486.     if(sel==11)  {max=59;mini=0;}    //闹铃2小时
  487.     if(sel==12)  {max=23;mini=0;}    //闹铃2分钟
  488.     if(sel==50)  { //闹铃1开关
  489.   item=I2CReadAdd(DS3231_CONTROL)^0x01;
  490.   I2CWrite(DS3231_CONTROL,item);
  491. }
  492.     if(sel==60)  {   //闹铃2开关
  493.   item=I2CReadAdd(DS3231_CONTROL)^0x02;
  494.   I2CWrite(DS3231_CONTROL,item);
  495. }
  496. else{
  497.   item=(I2CReadAdd(sel)&0x7F)/16*10+(I2CReadAdd(sel)&0x7F)%16;
  498.      if (selby==0) item++;  else item--;
  499.      if(item>max) item=mini;  
  500.      if(item<mini) item=max;
  501.   I2CWrite(sel,B_BCD(item));
  502.     autoweek();
  503. }
  504. }
复制代码



8.KEY.H
  1. #ifndef __KEY_H__
  2. #define __KEY_H__


  3. #define uchar unsigned char
  4. #define uint  unsigned int

  5. sbit SET  = P3^7;
  6. sbit UP  = P3^6;
  7. sbit DOWN  = P3^5;

  8. extern xdata uchar keyvalue,SetFlag;

  9. void Scan_Key();
  10. void KeyProcess();
  11. void Set(uchar sel,uchar selby);

  12. #endif
复制代码



9.LCD1602.C
  1. #include "main.h"

  2. uchar lastsec=0xFF;
  3. uchar code mychar[8][8]={
  4. 0x08,0x0F,0x12,0x0F,0x0A,0x1F,0x02,0x02, //年 0x00
  5. 0x0F,0x09,0x0F,0x09,0x0F,0x09,0x13,0x00, //月 0x01
  6. 0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x00, //日 0x02
  7. 0x07,0x05,0x07,0x00,0x00,0x00,0x00,0x00, //°  0x03
  8. //0x02,0x05,0x05,0x02,0x00,0x00,0x00,0x00, //°  0x03
  9. 0x01,0x03,0x1D,0x11,0x1D,0x03,0x01,0x00,  //小喇叭标记 0x04
  10. 0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,  //闹铃1标记  0x05
  11. 0x00,0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,  //闹铃2标记  0x06
  12. 0x00,0x0C,0x00,0x00,0x0C,0x0C,0x00,0x00  //闹铃1+2标记  0x07
  13. };
  14.       
  15. void Delay5Ms()
  16. {
  17.     uchar a,b;
  18.     for(b=19;b>0;b--)
  19.         for(a=130;a>0;a--);
  20. }

  21. void WriteDataLCM(uchar WDLCM)
  22. {
  23.    ReadStatusLCM(); //检测忙
  24.    LCM_Data = WDLCM;
  25.    LCM_RS = 1;
  26.    LCM_RW = 0;
  27.    LCM_E = 0;
  28.    LCM_E = 0; //延时
  29.    LCM_E = 1;
  30. }


  31. void WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测
  32. {
  33.    if(BuysC) ReadStatusLCM(); //根据需要检测忙
  34.    LCM_Data = WCLCM;
  35.    LCM_RS = 0;
  36.    LCM_RW = 0;
  37.    LCM_E = 0;
  38.    LCM_E = 0;
  39.    LCM_E = 1;
  40. }


  41. uchar ReadStatusLCM()
  42. {
  43.    LCM_Data = 0xFF;
  44.    LCM_RS = 0;
  45.    LCM_RW = 1;
  46.    LCM_E = 0;
  47.    LCM_E = 0;
  48.    LCM_E = 1;
  49.    while (LCM_Data & 0x80); //检测忙信号
  50.    return(LCM_Data);
  51. }


  52. void LCMInit()
  53. {
  54.    LCM_Data = 0;
  55.    WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
  56.    Delay5Ms();
  57.    WriteCommandLCM(0x38,0);
  58.    Delay5Ms();
  59.    WriteCommandLCM(0x38,0);
  60.    Delay5Ms();
  61. WriteCGRAM();
  62.    WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
  63.    WriteCommandLCM(0x08,1); //关闭显示
  64.    WriteCommandLCM(0x01,1); //显示清屏
  65.    WriteCommandLCM(0x06,1); // 显示光标移动设置
  66.    WriteCommandLCM(0x0C,1); // 显示开及光标设置
  67. }


  68. void DisplayChar(uchar X, uchar Y, uchar DData)
  69. {
  70.    Y &= 0x01;
  71.    X &= 0x0F; //限制X不能大于15,Y不能大于1
  72.    if(Y) X |= 0x40; //当要显示第二行时地址码+0x40;
  73.    X |= 0x80; //算出指令码
  74.    WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
  75.    WriteDataLCM(DData);
  76. }


  77. void DisplayStr(uchar X, uchar Y, uchar code *DData)
  78. {
  79.    uchar ListLength,j;
  80.    ListLength = strlen(DData);
  81.    Y &= 0x01;
  82.    X &= 0x0F; //限制X不能大于15,Y不能大于1
  83.     if (X <= 0x0F) //X坐标应小于0xF
  84.     {
  85.   for(j=0;j<ListLength;j++)
  86.   {
  87.              DisplayChar(X, Y, DData[j]); //显示单个字符
  88.              X++;
  89.   }
  90. }
  91. }

  92. void WriteCGRAM() //CGRAM区写入自定义的字符
  93. {
  94. uchar x,y;
  95. WriteCommandLCM(0x40,0);
  96. for(y=0;y<8;y++)
  97. {
  98.   for(x=0;x<8;x++)
  99.   {
  100.    WriteDataLCM(mychar[y][x]);
  101.   }
  102. }

  103. }

  104. void Disp_Time()
  105. {
  106. Readtime();
  107. if(F_500ms){
  108.   DisplayChar(2,1,' ');
  109.   DisplayChar(5,1,' ');
  110. }
  111. else{
  112.   DisplayChar(2,1,':');
  113.   DisplayChar(5,1,':');
  114. }
  115. if(sec!=lastsec){
  116.   DisplayChar(2,1,':');
  117.   DisplayChar(5,1,':');
  118.   F_500ms_b=0;F_500ms=0;
  119.   DisplayStr(0,0,"20");
  120.   DisplayChar(2,0,year/10+0x30);
  121.   DisplayChar(3,0,year%10+0x30);
  122.   DisplayChar(4,0,0x00);
  123.   DisplayChar(5,0,month/10+0x30);
  124.   DisplayChar(6,0,month%10+0x30);
  125.   DisplayChar(7,0,0x01);
  126.   DisplayChar(8,0,date/10+0x30);
  127.   DisplayChar(9,0,date%10+0x30);
  128.   DisplayChar(10,0,0x02);
  129.   DisplayChar(11,0,' ');
  130.   DisplayChar(12,0,' ');
  131.   switch(day)
  132.   {
  133.    case 1:DisplayStr(13,0,"Mon");break;
  134.    case 2:DisplayStr(13,0,"Tue");break;
  135.    case 3:DisplayStr(13,0,"Wed");break;
  136.    case 4:DisplayStr(13,0,"Thu");break;
  137.    case 5:DisplayStr(13,0,"Fri");break;
  138.    case 6:DisplayStr(13,0,"Sat");break;
  139.    case 7:DisplayStr(13,0,"Sun");break;
  140.    default :DisplayStr(13,0,"ERR");break;
  141.   }
  142.   
  143.   DisplayChar(0,1,(hour<10)?' ':(hour/10+0x30));
  144.   DisplayChar(1,1,hour%10+0x30);
  145.   DisplayChar(3,1,min/10+0x30);
  146.   DisplayChar(4,1,min%10+0x30);
  147.   DisplayChar(6,1,sec/10+0x30);
  148.   DisplayChar(7,1,sec%10+0x30);
  149.   switch(I2CReadAdd(DS3231_CONTROL) & 0x03)
  150.   {
  151.    case 1: DisplayChar(8,1,0x04);DisplayChar(9,1,0x05);break;
  152.    case 2: DisplayChar(8,1,0x04);DisplayChar(9,1,0x06);break;
  153.    case 3: DisplayChar(8,1,0x04);DisplayChar(9,1,0x07);break;
  154.    default: DisplayChar(8,1,' ');DisplayChar(9,1,' ');break;
  155.   }
  156.   if((I2CReadAdd(DS3231_CONTROL) & 0x02)==1 && (I2CReadAdd(DS3231_CONTROL) & 0x01)==0) DisplayChar(9,1,0x06);

  157.   if(ReadTemp()==1){
  158.    DisplayChar(10,1,' ');
  159.    DisplayChar(11,1,' ');
  160.    DisplayChar(12,1,(Dtemp<10)?' ':(Dtemp/10+0x30));
  161.    DisplayChar(13,1,Dtemp%10+0x30);
  162.    DisplayChar(14,1,0x03);
  163.    DisplayChar(15,1,'C');
  164.   }
  165.   lastsec=sec;
  166. }
  167. }
复制代码



10.LCD1602.H
  1. #ifndef __LCD1602_H__
  2. #define __LCD1602_H__

  3. #define LCM_Data  P0
  4. #define uchar unsigned char
  5. #define uint  unsigned int

  6. sbit LCM_RS = P2 ^ 1;
  7. sbit LCM_RW = P2 ^ 2;
  8. sbit LCM_E = P2 ^ 5;

  9. void Delay5Ms();
  10. void Delay400ms();
  11. void WriteDataLCM(uchar WDLCM);
  12. void WriteCommandLCM(uchar WCLCM,BuysC);
  13. uchar ReadStatusLCM(void);
  14. void LCMInit(void);
  15. void DisplayChar(uchar X, uchar Y, uchar DData);
  16. void DisplayStr(uchar X, uchar Y, uchar code *DData);
  17. void WriteCGRAM(void);
  18. void Disp_Time(void);
  19. void Disp_Temp(void);


  20. #endif
复制代码



11.main.C
  1. //CPU: AT89C52/STC89C53   OSC 12MHZ
  2. //1602 液晶 左上接口      
  3. //Vo接10K可调电阻分别到5V和GND
  4. //DS3231 3.3V

  5. #include "main.h"
  6. #include "music.h"

  7. uchar F_100ms=0,F_100ms_b;
  8. uchar F_500ms=0,F_500ms_b;
  9. uchar re_disp,re_disp_b=0;//500ms返回菜单循环计数
  10. uchar Disp_b = 0; //显示延时计数
  11. bit  Flash  = 0; //调时闪烁用标志变量
  12. bit  Al_Flag  = 0; //闹铃标志位
  13. bit  aa = 0; //铃声选择
  14. uchar alarmmin; //闹铃时间2分钟
  15. uchar Time_H = 0;
  16. uchar Time_L = 0;

  17. void Timer0Init() //音乐闹铃用定时器 T0方式1
  18. {
  19. TMOD = 0x01;
  20. TH0 = 0xFF;
  21. TL0 = 0xFF;
  22. EA = 1;
  23. ET0 =1;
  24. TR0 = 0;
  25. }

  26. void Timer1Init() //25ms定时器 T1方式1
  27. {
  28.     TMOD = 0x10;
  29.     TH1 = 0x9E;
  30.     TL1 = 0x58;
  31. EA = 1;
  32.     ET1 = 1;
  33.     TR1 = 1;
  34. }

  35. void Alarm_Int0_Init() //中断0开启
  36. {
  37. EA = 1;
  38. EX0 = 1;
  39. IT0 = 0;//电平的触发方式
  40. }

  41. void main()
  42. {
  43. Delay5Ms();
  44. Delay5Ms();
  45. Timer0Init(); //开启定时器0中断
  46. Timer1Init(); //开启定时器1中断
  47. Alarm_Int0_Init(); //开启外部中断0
  48. while(!F_500ms) ; //启动等待,等LCM讲入工作状态
  49.    Beep(1); //开机提示音
  50. Write_18B20();
  51.     InitDS3231(); //初始化DS3231
  52.    autoweek(); //开机自动星期转换
  53. LCMInit(); //LCM初始化
  54. while(1)
  55. {
  56.   if(F_100ms&&SetFlag==0)
  57.   {
  58.    Disp_Time();
  59.    F_100ms=0;F_100ms_b=0;
  60.   }
  61.   if(Al_Flag==1 && aa==0) Beep(2);
  62.   if(Al_Flag==1 && aa==1) Play_Music(MusicTwo,5);
  63.   if((min-alarmmin)==2) Al_Flag=0; //闹铃响2分钟,停止闹铃
  64.   Scan_Key();
  65.   KeyProcess();
  66.   if(Disp_b>=20) SetFlag=0;//10s没有按下按键,则返回时间显示
  67. }

  68. }

  69. void Alarm_Int0() interrupt 0
  70. {
  71. Al_Flag=1; //闹铃标志位置位
  72. alarmmin=min; //初始化闹铃时间
  73. I2CWrite(DS3231_STATUS,0x00); //清DS3231内部闹钟标志位
  74. //Beep2();
  75. }

  76. void Timer0() interrupt 1
  77. {
  78. BEE = !BEE;
  79. TH0 = Time_H;
  80. TL0 = Time_L;
  81. }

  82. void Timer1() interrupt 3
  83. {
  84.    TH1=0x9E;
  85.    TL1=0x58;
  86. F_100ms_b++;
  87. F_500ms_b++;
  88. re_disp_b++;
  89.    if(SET==0||UP==0||DOWN==0) Al_Flag=0; //按下按键关闭闹铃
  90. if(F_100ms_b>=4) {F_100ms=1;  F_100ms_b=0;}
  91.    if(F_500ms_b>=20) {F_500ms=1;  F_500ms_b=0;}
  92. if(re_disp_b>=20) {re_disp=1;re_disp_b=0;Flash=!Flash;Disp_b++;if(Disp_b>=100) Disp_b=100;}
  93. }
复制代码

12.main.h
  1. #ifndef __MAIN_H__
  2. #define __MAIN_H__

  3. #include <reg52.h>
  4. #include <string.h>
  5. #include "LCD1602.H"
  6. #include "DS3231_2.H"
  7. #include "bell.h"
  8. #include "key.h"
  9. #include "ds18b20.h"

  10. #define uchar unsigned char
  11. #define uint  unsigned int

  12. extern uchar F_500ms,F_500ms_b,Disp_b,Time_H,Time_L;
  13. extern bit aa,Flash,Al_Flag;

  14. #endif
复制代码




回复

使用道具 举报

ID:78901 发表于 2015-5-4 23:07 | 显示全部楼层
不错,收下,看看能不能仿制一个
回复

使用道具 举报

ID:79278 发表于 2015-5-8 09:46 | 显示全部楼层
买了个模块,初始化时间时经常只能部份准确,15他变成2035,时钟小时大于10也会出错,不知是何故
回复

使用道具 举报

ID:79992 发表于 2015-5-14 17:20 | 显示全部楼层
如果只用到ds3231时钟芯片和lcd602,要怎么样改程序?就是不要声音、闹铃和温度
回复

使用道具 举报

ID:79992 发表于 2015-5-14 17:22 | 显示全部楼层
如果只用到ds3231时钟芯片和lcd602,要怎么样改程序?就是不要声音、闹铃和温度
回复

使用道具 举报

ID:62033 发表于 2015-5-18 09:40 | 显示全部楼层
DS3231内部有温度寄存器。
不需要外围温度器件。
楼主用的LCD1602怎么显示中文的?是把某几个字符改掉的吗?
这些改掉的字符掉电后还在吗?
回复

使用道具 举报

ID:62033 发表于 2015-5-20 09:11 | 显示全部楼层
jjbboox 发表于 2015-5-18 09:40
DS3231内部有温度寄存器。
不需要外围温度器件。
楼主用的LCD1602怎么显示中文的?是把某几个字符改掉的 ...

自己回去试了一下。
自己来回答提出的问题。

LCD1602没有FLASH内存,所以掉电以后这些字符肯定就是没有了。
不光掉电后没了。只要程序里面对1602进行初始化以后,也会丢失。

不过楼主的作品给了我很大的启发,谢谢
回复

使用道具 举报

ID:86421 发表于 2015-10-13 21:10 | 显示全部楼层
sbit    int0 = P3^2;这个是接哪的呀?
回复

使用道具 举报

ID:92746 发表于 2015-11-19 14:12 | 显示全部楼层
sbit    int0 = P3^2;这个是接哪的呀?<18b20>
回复

使用道具 举报

ID:86796 发表于 2015-11-19 21:15 | 显示全部楼层
照方抓药,我也弄一个
回复

使用道具 举报

ID:92746 发表于 2016-5-2 07:12 | 显示全部楼层
文件不全
回复

使用道具 举报

ID:109731 发表于 2016-5-4 11:18 | 显示全部楼层
可以发一个打包好的程序吗
回复

使用道具 举报

ID:146910 发表于 2016-11-15 22:53 | 显示全部楼层

可以发一个打包好的程序吗
回复

使用道具 举报

ID:146910 发表于 2016-11-23 14:01 | 显示全部楼层
可以发一个打包好的程序吗
回复

使用道具 举报

ID:148518 发表于 2016-11-24 15:24 | 显示全部楼层
好东西,做的真漂亮。
回复

使用道具 举报

ID:158623 发表于 2016-12-29 14:16 来自手机 | 显示全部楼层
跪求打包程序
回复

使用道具 举报

ID:155671 发表于 2017-1-6 20:32 | 显示全部楼层
Keil uVision5 编译后,HEX文件超过26KB。stc89c52rc的程序空间不够用,即便是c53的程序空间也不够。
回复

使用道具 举报

ID:168287 发表于 2017-3-23 15:00 | 显示全部楼层
跪求打包程序
回复

使用道具 举报

ID:200120 发表于 2017-5-12 21:56 | 显示全部楼层
可以求一个工程文件吗?
回复

使用道具 举报

ID:236312 发表于 2017-10-16 21:22 | 显示全部楼层
原理图和程序对不上。。。
回复

使用道具 举报

ID:123860 发表于 2017-10-17 18:34 | 显示全部楼层
学习一下
回复

使用道具 举报

ID:164850 发表于 2017-12-14 23:08 | 显示全部楼层
原理图和程序对不上的,自己改改,上传一个完整工程文件

ds32311602时钟.rar

125.81 KB, 下载次数: 156, 下载积分: 黑币 -5

回复

使用道具 举报

ID:392520 发表于 2018-9-2 10:59 | 显示全部楼层
谢谢楼主提供的代码,学习了
回复

使用道具 举报

ID:389903 发表于 2018-9-2 18:57 | 显示全部楼层
谢谢分享。学习中。
回复

使用道具 举报

ID:389903 发表于 2018-9-2 20:26 | 显示全部楼层
luxianjun 发表于 2017-12-14 23:08
原理图和程序对不上的,自己改改,上传一个完整工程文件

扣了我5黑币,文件却没下载下来!
回复

使用道具 举报

ID:408289 发表于 2018-10-15 14:29 | 显示全部楼层
这个项目较好,可以参考。
回复

使用道具 举报

ID:6743 发表于 2018-12-19 15:46 | 显示全部楼层
最近在弄DS3231,谢谢楼主分享
回复

使用道具 举报

ID:229361 发表于 2019-1-21 13:38 | 显示全部楼层
谢谢楼主的分享了
回复

使用道具 举报

ID:585455 发表于 2019-7-28 12:18 | 显示全部楼层
今天來測試 感謝
回复

使用道具 举报

ID:879141 发表于 2021-2-4 20:29 来自手机 | 显示全部楼层
很有參考價值。多謝分享!
回复

使用道具 举报

ID:652804 发表于 2021-3-27 08:38 | 显示全部楼层
谢谢楼主的分享了,参考一下。
回复

使用道具 举报

ID:1003154 发表于 2022-1-23 02:23 | 显示全部楼层
luxianjun 发表于 2017-12-14 23:08
原理图和程序对不上的,自己改改,上传一个完整工程文件

好东西
回复

使用道具 举报

ID:267707 发表于 2022-1-28 13:03 | 显示全部楼层

自己动手丰衣足食,DIY精神永垂不朽!
回复

使用道具 举报

ID:1009101 发表于 2022-3-9 11:16 | 显示全部楼层
jjbboox 发表于 2015-5-18 09:40
DS3231内部有温度寄存器。
不需要外围温度器件。
楼主用的LCD1602怎么显示中文的?是把某几个字符改掉的 ...

LCD1602显示的简单汉字字模代码,在单片机程序中,发送给LCD1602显示RAM
回复

使用道具 举报

ID:516216 发表于 2022-8-12 14:48 | 显示全部楼层
感谢楼主的分享,DSC231的走时精度比DS1302好多了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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