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