MSP430:实时时钟-DS1302

 1 /*
 2  * DS1302.h
 3  *
 4  *  Created on: 2013-11-27
 5  *      Author: Allen
 6  */
 7 
 8 #ifndef DS1302_H_
 9 #define DS1302_H_
10 
11 #include     <MSP430G2553.h>
12 #include    "MyType.h"
13 
14 //时间结构体
15 typedef struct
16 {
17     uchar year;    //00-99,前面自己加入20,比如读出13为2013
18     uchar month;
19     uchar date;
20     uchar hour;
21     uchar min;
22     uchar sec;
23     uchar week;
24 }_calendar_obj;
25 
26 extern _calendar_obj calendar;    //日历结构体
27 
28 #define delay_time              0
29 //DS1302地址定义
30 #define ds1302_sec_add            0x80        //秒数据地址
31 #define ds1302_min_add            0x82        //分数据地址
32 #define ds1302_hr_add            0x84        //时数据地址
33 #define ds1302_date_add            0x86        //日数据地址
34 #define ds1302_month_add        0x88        //月数据地址
35 #define ds1302_day_add            0x8a        //星期数据地址
36 #define ds1302_year_add            0x8c        //年数据地址
37 #define ds1302_control_add        0x8e        //控制数据地址
38 #define ds1302_charger_add        0x90
39 #define ds1302_clkburst_add        0xbe
40 
41 //SCLK:P2.3
42 #define        SCLK_DIR        (P2DIR)
43 #define        SCLK_OUT        (P2OUT)
44 #define        SCLK_REN        (P2REN)
45 #define        SCLK_PIN        (BIT3)
46 
47 #define        SCLK_UP            (Set_Bit(SCLK_REN,SCLK_PIN))
48 #define        SCLK_DirOut        (Set_Bit(SCLK_DIR,SCLK_PIN))
49 #define        SCLK_H            (Set_Bit(SCLK_OUT,SCLK_PIN))
50 #define        SCLK_L            (Clr_Bit(SCLK_OUT,SCLK_PIN))
51 
52 
53 //DS_SDA:P2.4
54 #define        IO_DIR            (P2DIR)
55 #define        IO_OUT            (P2OUT)
56 #define        IO_IN            (P2IN)
57 #define        IO_REN            (P2REN)
58 #define        IO_PIN            (BIT4)
59 
60 #define        IO_UP            (Set_Bit(IO_REN,IO_PIN))
61 #define        IO_DirOut        (Set_Bit(IO_DIR,IO_PIN))
62 #define        IO_H            (Set_Bit(IO_OUT,IO_PIN))
63 #define        IO_L            (Clr_Bit(IO_OUT,IO_PIN))
64 
65 
66 #define        IO_DirIn        (Clr_Bit(IO_DIR,IO_PIN))
67 #define        IO_Data            (Get_Bit(IO_IN,IO_PIN))
68 
69 //RST:P2.5
70 #define        RST_DIR            (P2DIR)
71 #define        RST_OUT            (P2OUT)
72 #define        RST_IN            (P2IN)
73 #define        RST_REN            (P2REN)
74 #define        RST_PIN            (BIT5)
75 
76 #define        RST_UP            (Set_Bit(RST_REN,RST_PIN))
77 #define        RST_DirOut        (Set_Bit(RST_DIR,RST_PIN))
78 #define        RST_H            (Set_Bit(RST_OUT,RST_PIN))
79 #define        RST_L            (Clr_Bit(RST_OUT,RST_PIN))
80 
81 
82 void DS1302_Init(void);
83 static void delay_us( unsigned int k );
84 void ds1302_write_byte(uchar addr, uchar data);
85 uchar ds1302_read_byte(uchar addr);
86 void ds1302_write_time(uchar year,uchar month,uchar day,uchar hour,uchar min,uchar sec,uchar week);
87 void ds1302_read_time(void);
88 void ds1302_sendtime_uart(void);
89 
90 #endif
DS1302.h
  1 /*
  2  * DS1302.c
  3  *
  4  *  Created on: 2013-11-29
  5  *      Author: Allen
  6  */
  7 
  8 #include    "DS1302.h"
  9 #include     <MSP430G2553.h>
 10 #include    "uart.h"
 11 
 12 _calendar_obj calendar;
 13 
 14 void DS1302_Init(void)
 15 {
 16     SCLK_DirOut;
 17     RST_DirOut;
 18     IO_DirOut;
 19     SCLK_L;
 20     RST_L;
 21     delay_us(10);
 22     SCLK_H;
 23 }
 24 
 25 
 26 static void delay_us( unsigned int k )
 27 {
 28     while(k--)
 29     _nop();
 30 
 31 }
 32 
 33 //向DS1302写入一字节数据
 34 void ds1302_write_byte(uchar addr, uchar data)
 35 {
 36     uchar i;
 37     IO_DirOut;
 38     RST_H;                    //启动DS1302总线
 39     //写入目标地址:addr
 40     addr = addr & 0xFE;   //最低位置零,寄存器0位为0时写,为1时读
 41     for (i = 0; i < 8; i ++) {
 42         if (addr & 0x01) {
 43             IO_H;
 44             }
 45         else {
 46             IO_L;
 47             }
 48         SCLK_H;      //产生时钟
 49         delay_us(delay_time);
 50         SCLK_L;
 51         delay_us(delay_time);
 52         addr = addr >> 1;
 53         }
 54     //写入数据:d
 55     for (i = 0; i < 8; i ++) {
 56         if (data & 0x01) {
 57             IO_H;
 58             }
 59         else {
 60             IO_L;
 61             }
 62         SCLK_H;      //产生时钟
 63         delay_us(delay_time);
 64         SCLK_L;
 65         delay_us(delay_time);
 66         data = data >> 1;
 67         }
 68     RST_L;        //停止DS1302总线
 69 }
 70 
 71 //从DS1302读出一字节数据
 72 uchar ds1302_read_byte(uchar addr)
 73 {
 74 
 75     uchar i,temp;
 76     RST_H;                    //启动DS1302总线
 77     //写入目标地址:addr
 78     addr = addr | 0x01;    //最低位置高,寄存器0位为0时写,为1时读
 79     IO_DirOut;
 80     for (i = 0; i < 8; i ++)
 81     {
 82         if (addr & 0x01)
 83         {
 84             IO_H;
 85         }
 86         else
 87         {
 88             IO_L;
 89         }
 90         SCLK_H;      //产生时钟
 91         delay_us(delay_time);
 92         SCLK_L;
 93         delay_us(delay_time);
 94         addr = addr >> 1;
 95     }
 96     //输出数据:temp
 97     IO_DirIn;
 98     for (i = 0; i < 8; i ++)
 99     {
100         temp = temp >> 1;
101         if (IO_Data)
102 //        if( P2IN & BIT4)
103         {
104             temp |= 0x80;
105         }
106         else
107         {
108             temp &= 0x7F;
109         }
110         SCLK_H;      //产生时钟
111         delay_us(delay_time);
112         SCLK_L;
113         delay_us(delay_time);
114         }
115     RST_L;                    //停止DS1302总线
116     return temp;
117 }
118 
119 //向DS302写入时钟数据
120 void ds1302_write_time(uchar year,uchar month,uchar day,uchar hour,uchar min,uchar sec,uchar week)
121 {
122     uchar temp=0;
123     ds1302_write_byte(ds1302_control_add,0x00);            //关闭写保护
124     ds1302_write_byte(ds1302_sec_add,0x80);                //暂停时钟
125     //ds1302_write_byte(ds1302_charger_add,0xa9);        //涓流充电
126 
127     temp=(year/10<<4)|(year%10&0x0F);
128     ds1302_write_byte(ds1302_year_add,119);        //
129 
130     temp=(month/10<<4)|(month%10&0x0F);
131     ds1302_write_byte(ds1302_month_add,temp);    //
132 
133     temp=(day/10<<4)|(day%10&0x0F);
134     ds1302_write_byte(ds1302_date_add,temp);        //
135 
136     temp=((hour/10<<4)|(hour%10&0x0F))&0x3F;
137     ds1302_write_byte(ds1302_hr_add,temp);        //
138 
139     temp=(min/10<<4)|(min%10&0x0F);
140     ds1302_write_byte(ds1302_min_add,temp);        //
141 
142     temp=(sec/10<<4)|(sec%10&0x0F);
143     temp=temp&0x7f;
144     ds1302_write_byte(ds1302_sec_add,temp);        //
145 
146     temp=week;
147     ds1302_write_byte(ds1302_day_add,temp);        //
148 
149     ds1302_write_byte(ds1302_control_add,0x80);            //打开写保护
150 }
151 
152 //从DS302读出时钟数据
153 void ds1302_read_time(void)
154 {
155     uchar temp=0;
156 
157     temp=ds1302_read_byte(ds1302_year_add);//
158     calendar.year=(temp>>4)*10+temp&0x0F; //
159 
160     temp=ds1302_read_byte(ds1302_month_add);//
161     calendar.month=(temp>>4)*10+temp&0x0F;    //
162 
163     temp=ds1302_read_byte(ds1302_date_add);//
164     calendar.date=((temp&0x70)>>4)*10 + (temp&0x0F);  //
165 
166     temp=ds1302_read_byte(ds1302_hr_add);//
167     calendar.hour=((temp&0x70)>>4)*10 + (temp&0x0F);
168 
169     temp=ds1302_read_byte(ds1302_min_add);    //
170     calendar.min=((temp&0x70)>>4)*10 + (temp&0x0F);    //
171 
172     temp=(ds1302_read_byte(ds1302_sec_add))&0x7f;//秒,屏蔽秒的第7位,避免超出59,此位控制时钟是否开启
173     calendar.sec=((temp&0x70)>>4)*10 + (temp&0x0F);//秒,屏蔽秒的第7位,避免超出59
174 
175     temp=ds1302_read_byte(ds1302_day_add); //
176     calendar.week=(temp>>4)*10+temp&0x0F; //
177 }
178 
179 void ds1302_sendtime_uart(void)
180 {
181 
182     uart_send_ch(calendar.year/10+'0');
183     uart_send_ch(calendar.year%10+'0');
184     uart_send_ch('-');
185     uart_send_ch(calendar.month/10+'0');
186     uart_send_ch(calendar.month%10+'0');
187     uart_send_ch('-');
188     uart_send_ch(calendar.date/10+'0');
189     uart_send_ch(calendar.date%10+'0');
190     uart_send_ch(' ');
191 
192     uart_send_ch(calendar.hour/10+'0');
193     uart_send_ch(calendar.hour%10+'0');
194     uart_send_ch(':');
195     uart_send_ch(calendar.min/10+'0');
196     uart_send_ch(calendar.min%10+'0');
197     uart_send_ch(':');
198     uart_send_ch(calendar.sec/10+'0');
199     uart_send_ch(calendar.sec%10+'0');
200 
201     uart_send_ch(' ');
202     uart_send_ch(calendar.week/10+'0');
203     uart_send_ch(calendar.week%10+'0');
204 
205     uart_send_ch('
');
206 }
DS1302.c


运行很简单:

main:

    DS1302_Init();
    ds1302_write_time(13,12,1,20,33,23,7);
    ds1302_read_time();
    ds1302_sendtime_uart();

注意:年份不需要20,只写后面两位,范围00-99,所以年份范围是2000-2099

如果需要读出时间:

    ds1302_read_time();
    ds1302_sendtime_uart();

还是很好操作的,两个电源pin角,电池以及外接直流。

至于寄存器,时钟,细看SPEC吧

这里采取24小时制式。

原文地址:https://www.cnblogs.com/wwjdwy/p/3452986.html