• DS1302-演示代码


    参考DS1302数据手册,尽管数据手册是英文,但是很有帮助,再结合网上众多的代码写出了下面这个例子,除了涓流充电(trickle charger)功能没使用外,内部的RAM和寄存器功能都使用到了,包括多字节方式(burst mode)。自认为我写的比网上大多数程序清晰,当然已经硬件测试过了。

      1 #include <reg52.h>
      2 
      3 /*DS1302部分*/
      4 
      5 //全部为写入地址,读取地址需要+1
      6 #define YEAR 0x8c
      7 #define MON 0x88
      8 #define DATE 0x86
      9 #define DAY 0x8a
     10 #define HOUR 0x84
     11 #define MIN 0x82
     12 #define SEC 0x80
     13 #define WP 0x8e
     14 #define RAM(n) (0xc0+2*(n))
     15 #define CLBT 0xbe
     16 #define RAMBT 0xfe
     17 
     18 //3个通信引脚
     19 sbit SCLK=P2^1;
     20 sbit IO=P2^0;
     21 sbit RST=P2^4;    //有的使能端叫CE
     22 
     23 unsigned char readbyte(void);
     24 void writebyte(unsigned char dat);
     25 void write1302(unsigned char addr,unsigned char dat);
     26 unsigned char read1302(unsigned char addr);
     27 
     28 
     29 /*数码管部分,6位共阴接在P0*/
     30 sbit we=P2^7;
     31 sbit du=P2^6;
     32 void show(void);
     33 void delayms(unsigned time);
     34 
     35 unsigned char code table[] = {
     36 0x3f , 0x06 , 0x5b , 0x4f,
     37 0x66 , 0x6d , 0x7d , 0x07,
     38 0x7f , 0x6f , 0x77 , 0x7c,
     39 0x39 , 0x5e , 0x79 , 0x71,
     40 0x00 };
     41 
     42 unsigned char num[6]={0};    //用作数码管显示的数组
     43 
     44 /*键盘部分,4个独立键盘接在P3.4-P3.7*/
     45 void keyscan(void);
     46 bit showdate=0;
     47 bit showday=0;
     48 
     49 void main(void)
     50 {
     51     unsigned char temp;
     52 
     53     write1302(WP,0x00);    //允许写入,关闭写保护
     54     
     55     //clock burst 方式赋初值
     56     RST=0;
     57     SCLK=0;
     58     RST=1;
     59     writebyte(CLBT);
     60 
     61     writebyte(0x30);//秒分时
     62     writebyte(0x59);
     63     writebyte(0x23);
     64 
     65     writebyte(0x28);//日月
     66     writebyte(0x02);
     67 
     68     writebyte(0x02);//星期
     69     
     70     writebyte(0x32);//
     71 
     72     writebyte(0x00);
     73     writebyte(0x00);
     74     RST=0;
     75 
     76 //    另一种赋初值方法
     77 //    write1302(HOUR,0x23);
     78 //    write1302(MIN,0x59);
     79 //    write1302(SEC,0x30);    
     80 
     81     while(1)
     82     {
     83         keyscan();
     84         if(showdate)
     85         {
     86             temp=read1302(YEAR+1);
     87             num[5]=temp>>4;
     88             num[4]=temp&0x0f;
     89             temp=read1302(MON+1);
     90             num[3]=temp>>4;
     91             num[2]=temp&0x0f;
     92             temp=showday?read1302(DAY+1):read1302(DATE+1);    
     93             num[1]=temp>>4;
     94             num[0]=temp&0x0f;
     95         }
     96         else
     97         {
     98             temp=read1302(HOUR+1);
     99             num[5]=temp>>4;
    100             num[4]=temp&0x0f;
    101             temp=read1302(MIN+1);
    102             num[3]=temp>>4;
    103             num[2]=temp&0x0f;
    104             temp=read1302(SEC+1);    
    105             num[1]=temp>>4;
    106             num[0]=temp&0x0f;
    107         }
    108         show();
    109     }
    110 
    111 }
    112 
    113 
    114 unsigned char readbyte(void)
    115 {
    116     unsigned char i,ret;
    117     for(i=0;i<8;i++)
    118     {
    119         ret>>=1;
    120         SCLK=1;
    121         SCLK=0;
    122         ret|=IO?0x80:0x00;
    123     }
    124     return ret;
    125 }
    126 
    127 void writebyte(unsigned char dat)
    128 {
    129     unsigned char i;
    130     for(i=0;i<8;i++)
    131     {
    132         IO=dat&1;
    133         SCLK=0;           
    134         SCLK=1;
    135         dat>>=1;
    136     }
    137 }
    138 
    139 void write1302(unsigned char addr,unsigned char dat)     
    140 {
    141     RST=0;
    142     SCLK=0;
    143     RST=1;
    144     writebyte(addr);
    145     writebyte(dat);
    146     RST=0;         
    147 }
    148 
    149 unsigned char read1302(unsigned char addr)
    150 {
    151     unsigned char ret;
    152     RST=0;
    153     SCLK=0;
    154     RST=1;
    155     writebyte(addr);
    156     ret=readbyte();
    157     RST=0;    
    158     return ret;
    159 }
    160 
    161 void show(void)
    162 {
    163     unsigned char i;
    164     
    165     for(i=0;i<6;i++)
    166     {
    167         P0=0xff;
    168         we=1;
    169         we=0;      
    170 
    171         P0=table[num[i]];
    172         du=1;
    173         du=0;
    174 
    175         P0=~(0x20>>i);
    176         we=1;
    177         we=0;
    178 
    179         delayms(1);
    180     }
    181 }
    182 
    183 void delayms(unsigned time)
    184 {
    185     unsigned i,j;
    186 
    187     for(i=time;i>0;i--)
    188         for(j=110;j>0;j--)
    189         ;
    190 }
    191 
    192 void keyscan(void)
    193 {
    194     unsigned char temp;
    195     unsigned char reg[9];
    196 
    197     if((P3|0x0f)!=0xff)
    198     {
    199         delayms(10);
    200         if((temp=P3|0x0f)!=0xff)
    201         {
    202             while((P3|0x0f)!=0xff);
    203             switch(temp)
    204             {
    205             case 0xef:    //显示时间还是日期
    206                 showdate=~showdate;
    207                 break;
    208             case 0xdf:    //日期最后两位显示日还是星期
    209                 showday=~showday;
    210                 break;
    211             case 0xbf:    //将时钟寄存器保存到RAM
    212                 RST=0;
    213                 SCLK=0;
    214                 RST=1;
    215                 writebyte(CLBT+1);
    216                 for(temp=0;temp<9;temp++)
    217                     reg[temp]=readbyte();
    218                 RST=0;
    219 
    220                 //从20号RAM开始存入,起始RAM号随意,只要不超过范围即可
    221                 for(temp=0;temp<9;temp++)
    222                     write1302(RAM(20+temp),reg[temp]);
    223 
    224                 /*    也可以用 RAM burst 写入
    225                 RST=0;
    226                 SCLK=0;
    227                 RST=1;
    228                 writebyte(RAMBT);
    229                 for(temp=0;temp<9;temp++)
    230                     writebyte(reg[temp]);
    231                 RST=0;
    232                 */
    233 
    234                 break;
    235             case 0x7f:    //从RAM恢复到时钟寄存器
    236                 /*    对应的 RAM burst 读取
    237                 RST=0;
    238                 SCLK=0;
    239                 RST=1;
    240                 writebyte(RAMBT+1);
    241                 for(temp=0;temp<9;temp++)
    242                     reg[temp]=readbyte();
    243                 RST=0;
    244                 */
    245 
    246                 for(temp=0;temp<9;temp++)
    247                     reg[temp]=read1302(RAM(20+temp)+1);
    248 
    249                 RST=0;
    250                 SCLK=0;
    251                 RST=1;
    252                 writebyte(CLBT);
    253                 for(temp=0;temp<9;temp++)
    254                     writebyte(reg[temp]);
    255                 RST=0;
    256                 break;
    257             }
    258         }
    259     }
    260 }
    DS1302.c
  • 相关阅读:
    编写测试类实现并发访问固定URL(亲测能用!!!)
    java项目添加log4j打印日志+转换系统时间
    springboot项目没错,但就是报红叉
    我想查看数据库名,输入命令:select name from v$database;为什么会说表和视图不存在
    DRUID连接池的实用 配置详解+使用方法+监控方式(太强大了!!!)
    Druid连接池 属性说明
    springBoot2.2.0+mybatis-xml文件方式+Oracle11g+jsp页面,实现简单的CRUD
    s5-12 RIP
    s5-12 RIP
    s5-13 RIP 为什么会 衰败
  • 原文地址:https://www.cnblogs.com/zackcoder/p/3527668.html
Copyright © 2020-2023  润新知