单片机
返回首页

MSP430:实时时钟-DS1302

2017-11-03 来源:eefocus

 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    

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



  1 /*

  2  * DS1302.c

  3  *

  4  *  Created on: 2013-11-29

  5  *      Author: Allen

  6  */

  7 

  8 #include    'DS1302.h'

  9 #include    

 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('\n');

206 }



运行很简单:


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小时制式。


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • 用数字电路CD4069制作的万能遥控轻触开关

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 开关电源的基本组成及工作原理

  • 用NE555制作定时器

  • 带有短路保护系统的5V直流稳压电源电路图

    相关电子头条文章