zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    eslint 的 env 配置是干嘛使的?
    cookie httpOnly 打勾
    如何定制 antd 的样式(theme)
    剑指 Offer 66. 构建乘积数组
    剑指 Offer 65. 不用加减乘除做加法
    剑指 Offer 62. 圆圈中最后剩下的数字
    剑指 Offer 61. 扑克牌中的顺子
    剑指 Offer 59
    剑指 Offer 58
    剑指 Offer 58
  • 原文地址:https://www.cnblogs.com/zackcoder/p/3527668.html
Copyright © 2011-2022 走看看