DS1302时钟

  1 /*********************************************************************************
  2 * 【编写时间】: 2016年02月15日
  3 * 【作    者】: 清翔电子:03
  4 * 【版    本】: 1.0
  5 * 【网    站】: http://www.qxmcu.com/ 
  6 * 【淘宝店铺】: http://qxmcu.taobao.com/ 
  7 * 【实验平台】: QX-MCS51 单片机开发板
  8 * 【外部晶振】: 11.0592mhz    
  9 * 【主控芯片】: STC89C52
 10 * 【编译环境】: Keil μVisio3    
 11 * 【程序功能】: LCD1602液晶显示DS1302时钟日历                                                   
 12 * 【使用说明】: 试验前请用杜邦线分别把j5排针根据背面丝印相应接到P10、P11、P12
 13                   并接上LCD1602液晶调节好对比度再下载此程序
 14 
 15 *  说明:免费开源,不提供源代码分析.
 16 **********************************************************************************/
 17 
 18 //调用1602显示驱动,在此文件内已包含51头文件和定义数据类型
 19 #include "LCD1602.h"
 20 /*====================================
 21  IO接口定义
 22 ====================================*/
 23 sbit TSCLK = P1^0; //时钟
 24 sbit TIO = P1^1;   //数据
 25 sbit TRST = P1^2;  //使能
 26 
 27 #define MAIN_Fosc        11059200UL    //宏定义主时钟HZ
 28 #define DS1302_W_ADDR 0x80  //写时钟日历寄存器起始地址
 29 #define DS1302_R_ADDR 0x81    //读时钟日历寄存器起始地址
 30 
 31 //时钟日历暂存数组,秒、分、时、日、月、周、年 初值为= 16年2月15日 周1 23:58:50
 32 uchar TimeData[7]={50, 58, 23, 15, 2, 1, 16};
 33 
 34 /*=================================================
 35 *函数名称:Delay_Ms
 36 *函数功能:12T 51单片机自适应主时钟毫秒级延时函数
 37 *说明:需定义MAIN_Fosc(晶振主频单位HZ)
 38 *输入:ms:要延时的毫秒
 39 =================================================*/
 40 void Delay_Ms(INT16U ms)
 41 {
 42      INT16U i;
 43      do{
 44           i = MAIN_Fosc / 96000; 
 45           while(--i);   //96T per loop
 46      }while(--ms);
 47 }
 48 /*=================================================
 49 *函数名称:DS1302_W_Byte
 50 *函数功能:DS1302写一字节数据
 51 *输入:dat:要写入的数据
 52 =================================================*/
 53 void DS1302_W_Byte(uchar dat)
 54 {
 55     uchar i;
 56     for(i = 0; i < 8; i++) //每次写1bit,写8次
 57     {
 58         TSCLK = 0;           //拉低时钟总线
 59         TIO = dat & 0x01;  //从一字节最低位开始写
 60         TSCLK = 1;           //拉高时钟总线,DS1302把数据读走
 61         dat >>= 1;           //数据右移一位 
 62     }    
 63 }
 64 /*=================================================
 65 *函数名称:DS1302_R_Byte
 66 *函数功能:DS1302读一字节
 67 *输出:dat:读取的数据
 68 =================================================*/
 69 uchar DS1302_R_Byte()
 70 {
 71     uchar i, dat;
 72     for(i = 0; i < 8; i++)  //每次写1bit,写8次
 73     {
 74         TSCLK = 0;            //拉低时钟总线,DS1302把数据放到数据总线上
 75         dat >>= 1;             //数据右移一位,数据从最低位开始读 
 76         if(TIO)    dat |= 0x80;//读取数据
 77         TSCLK = 1;            //拉高时钟总线
 78     }
 79     return dat;                //返回读取的数据
 80 }
 81 /*=================================================
 82 *函数名称:DS1302_W_DAT
 83 *函数功能:写DS1302数据一次写2个字节
 84 *说明:先写命令后写数据
 85 *调用:DS1302_W_Byte()
 86 *输入:cmd:需要写的命令 ,dat:需要些的数据
 87 =================================================*/
 88 void DS1302_W_DAT(uchar cmd, uchar dat)
 89 {
 90     TRST = 0;             //拉低使能端
 91     TSCLK = 0;             //拉低数据总线
 92     TRST = 1;             //拉高使能端,开始写数据
 93     DS1302_W_Byte(cmd);     //写命令
 94     DS1302_W_Byte(dat);     //写数据
 95 }
 96 /*=================================================
 97 *函数名称:DS1302_R_DAT
 98 *函数功能:读DS1302数据
 99 *说明:先写入命令字节后读出对应数据
100 *调用:    DS1302_W_Byte();DS1302_R_Byte();
101 *输入:    cmd:需要写的命令
102 *输出:    dat:读出的数据
103 =================================================*/
104 uchar DS1302_R_DAT(uchar cmd)
105 {
106     uchar dat;
107     TRST = 0;                 //拉低使能端
108     TSCLK = 0;                //拉低数据总线
109     TRST = 1;                //拉高使能端,开始写数据
110     DS1302_W_Byte(cmd);        //写命令
111     dat = DS1302_R_Byte();    //读出数据
112     return dat;                //返回读出数据
113 }
114 
115 /*=================================================
116 *函数名称:DS1302_Clear_WP
117 *函数功能:清除DS1302写保护
118 *说明:先写入命令0x8e(写控制寄存器)接着向该寄存器写0
119 *调用:DS1302_W_DAT()
120 =================================================*/
121 void DS1302_Clear_WP()
122 {
123     DS1302_W_DAT(0x8e,0x00);  //把控制寄存器WP位置0
124 }
125 /*=================================================
126 *函数名称:DS1302_Clear_WP
127 *函数功能:设置DS1302写保护
128 *说明:先写入命令0x8e(写控制寄存器)接着向该寄存器写0x80
129 *调用:DS1302_W_DAT()
130 =================================================*/
131 void DS1302_Set_WP()
132 {    
133     DS1302_W_DAT(0x8e,0x80); //把控制寄存器WP位置1
134     TRST = 0;                 //拉低使能端
135     TSCLK = 0;                 //拉低数据总线
136 } 
137 /*=================================================
138 *函数名称:Set_DS1302_Time
139 *函数功能:设置DS1302时钟日历数据
140 *说明:把时钟日历暂存数组TimeData数据转换为BCD码并
141        写入到DS1302时钟日历寄存器中
142 *调用:DS1302_Clear_WP();DS1302_W_DAT();DS1302_Set_WP();
143 *输入:addr:需要写入寄存器的地址 ,TimeData数组:时钟日历初始值
144 =================================================*/
145 void Set_DS1302_Time(uchar addr)
146 {
147     uchar i, j;
148     DS1302_Clear_WP();        //清除写保护
149     for(i = 0; i < 7; i++)    //写入7个字节的时钟初始值
150     {
151         j = TimeData[i]/10;     //BCD码转换
152         TimeData[i] %= 10;     //BCD码转换
153         TimeData[i] += j*16; //BCD码转换
154         DS1302_W_DAT(addr, TimeData[i]); //先写DS1302时钟日历起始地址,再写数据
155         addr += 2;     //时钟日历寄存器地址+2转向下一个寄存器
156     }
157     DS1302_Set_WP(); //开起写保护        
158 }
159 /*=================================================
160 *函数名称:Read_DS1302_Time
161 *函数功能:读取DS1302时钟数据
162 *说明:    读取DS1302时钟数据 返回数据存入时钟日历暂存
163         数组TimeData(数据格式BCD码)
164 *调用:DS1302_Clear_WP();DS1302_R_DAT();DS1302_Set_WP();
165 *输入:    addr:需要读取时钟日历寄存器的起始地址
166 =================================================*/
167 void Read_DS1302_Time(uchar addr)
168 {
169     uchar i;
170     DS1302_Clear_WP();        //清楚些保护
171     for(i = 0; i < 7; i++)    //从DS1302读取7个字节的时钟日历数据
172     {
173         TimeData[i] = DS1302_R_DAT(addr);//先写入要读取数据的寄存器起始地址,再读出数据存入TimeData数组
174         addr += 2;                         //时钟日历寄存器地址+2转向下一个寄存器
175     }
176     DS1302_Set_WP();   //开起写保护
177 } 
178 /*=================================================
179 *函数名称:main
180 *函数功能:主函数 1602液晶显示DS1302数据
181            Date:年-月-日-星期
182            Time:时:分:秒
183 =================================================*/
184 void main()
185 {
186     InitLcd1602();                  //1602初始化
187     Set_DS1302_Time(DS1302_W_ADDR);    //先写入时钟日历寄存器起始地址再设置时钟日历初值
188     LcdShowStr(0,0,"Date:");  //1602显示字符串
189     LcdShowStr(0,1,"Time:");  //1602显示字符串
190     while(1)
191     {
192         Read_DS1302_Time(DS1302_R_ADDR); //先写入时钟日历寄存器起始地址再读出时钟日历写入到TimeData数组中
193         DisplayOneStr (5,0,TimeData[6]); //
194         DisplayOneChar (7,0,'-');         //-
195         DisplayOneStr (8,0,TimeData[4]); //
196         DisplayOneChar (10,0,'-');         //-
197         DisplayOneStr (11,0,TimeData[3]);//
198         DisplayOneChar (13,0,'-');         //-
199         DisplayOneStr (14,0,TimeData[5]);//星期
200 
201         DisplayOneStr (6,1,TimeData[2]); //
202         DisplayOneChar (8,1,':');         //
203         DisplayOneStr (9,1,TimeData[1]); //
204         DisplayOneChar (11,1,':');         //
205         DisplayOneStr (12,1,TimeData[0]);//
206         Delay_Ms(1000);                     //延时1秒
207     }        
208 }

 

posted @ 2018-03-05 22:32  Justice-V  阅读(519)  评论(0)    收藏  举报