【时钟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 }
时钟DS1302
 1 #include "LCD1602.h"
 2 
 3 
 4 void Read_Busy()           //忙检测函数,判断bit7是0,允许执行;1禁止
 5 {
 6     unsigned char sta;      //
 7     LCD1602_DB = 0xff;
 8     LCD1602_RS = 0;
 9     LCD1602_RW = 1;
10     do
11     {
12         LCD1602_EN = 1;
13         sta = LCD1602_DB;
14         LCD1602_EN = 0;    //使能,用完就拉低,释放总线
15     }while(sta & 0x80);
16 }
17 
18 void Lcd1602_Write_Cmd(unsigned char cmd)     //写命令
19 {
20     Read_Busy();
21     LCD1602_RS = 0;
22     LCD1602_RW = 0;
23     LCD1602_DB = cmd;
24     LCD1602_EN = 1;
25     LCD1602_EN = 0;    
26 }
27 
28 void Lcd1602_Write_Data(unsigned char dat)   //写数据
29 {
30       Read_Busy();
31       LCD1602_RS = 1;
32       LCD1602_RW = 0;
33       LCD1602_DB = dat;
34       LCD1602_EN = 1;
35       LCD1602_EN = 0;
36 }
37 
38 void LcdSetCursor(unsigned char x,unsigned char y)  //坐标显示
39 {
40     unsigned char addr;
41     if(y == 0)
42         addr = 0x00 + x;
43     else
44         addr = 0x40 + x;
45     
46     Lcd1602_Write_Cmd(addr|0x80);
47 }
48 //*************************显示一个字节数据
49 void DisplayOneChar (uchar X,uchar Y,uchar DData)
50 {
51  if(Y) X|=0X40;   //Y=1显示第二行,Y=0显示第一行
52  X|=0X80;
53  Lcd1602_Write_Cmd(X); //X用来选择哪一位
54  Lcd1602_Write_Data(DData); //DData用来写数据
55 }
56 
57 //显示一个字节字符
58 void DisplayOneStr (uchar X,uchar Y,uchar DData)
59 {
60     DisplayOneChar (X++,Y,DData/16 + '0');
61     DisplayOneChar (X,Y,DData%16 + '0');
62 }
63 void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str)     //显示字符串
64 {
65     LcdSetCursor(x,y);      //当前字符的坐标
66     while(*str != '\0')
67     {
68         Lcd1602_Write_Data(*str++);
69     }
70 }
71 
72 void InitLcd1602()              //1602初始化
73 {
74     Lcd1602_Write_Cmd(0x38);    //打开,5*8,8位数据
75     Lcd1602_Write_Cmd(0x0c);
76     Lcd1602_Write_Cmd(0x06);
77     Lcd1602_Write_Cmd(0x01);    //清屏   
78 }
LCD1602
 1 #ifndef __LCD_H_
 2 #define __LCD_H_
 3 
 4 /**********************************
 5 包含头文件
 6 **********************************/
 7 #include <reg52.h>
 8 
 9 typedef unsigned char INT8U;
10 typedef unsigned char uchar;
11 typedef unsigned char uint8;
12 
13 typedef unsigned int INT16U;
14 typedef unsigned int uint;
15 
16 /**********************************
17 PIN口定义
18 **********************************/
19 #define LCD1602_DB  P0      //data bus 数据总线
20 sbit LCD1602_RS = P3^5;
21 sbit LCD1602_RW = P3^6;
22 sbit LCD1602_EN = P3^4;     
23 
24 /**********************************
25 函数声明
26 **********************************/
27 void Read_Busy();           //忙检测函数,判断bit7是0,允许执行;1禁止
28 void Lcd1602_Write_Cmd(unsigned char cmd);     //写命令
29 void Lcd1602_Write_Data(unsigned char dat);   //写数据
30 void LcdSetCursor(unsigned char x,unsigned char y);  //坐标显示
31 void DisplayOneChar (uchar X,uchar Y,uchar DData); // 写一个字节
32 //显示一个字节字符
33 void DisplayOneStr (uchar X,uchar Y,uchar DData);
34 void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str);     //显示字符串
35 void InitLcd1602();              //1602初始化
36                       
37 
38 #endif
LCD1602.h

 

posted @ 2018-04-24 22:59  Justice-V  阅读(109)  评论(0)    收藏  举报