您的位置 首页 新品

单片机·实时时钟DS1302

一、实时时钟DS1302的简介DS1302的在实时显示时间中的应用。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。Vcc2

一、实时时钟DS1302的简介

DS1302的在实时显现时间中的运用。它能够对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功用。
Vcc2:电源
Vcc1:后备电源,断电后能够持续作业
GND:电源地
X1,X2:振动源,外接32.768kHz晶振
RST:片选信号
SCLK:读写操控字节
I/O:串行数据输入输出
2. DS1302的操控字节
bit7:有必要是1,否则不能写入数据 (能够类比LCD1602检测忙闲)
bit6:0,存储时钟数据;1,存储RAM数据
bit1-5:指示操作单元的地址
bit0:0,表明写;1,表明读
操控字节从低位开端输出

写保护 8EH 8FH
下面附一张英文表,感觉比中文的全面一点,便是丑陋
3.数据流(可参照时序)
1)RST=1时,DS1302才可被写入数据,才可被操作;RST=0时,DS1302会停止数据传输,变为高阻状况;
2)SCK上升沿读地址,SCK下降沿读数据;
3)操控字节输入后下一个SCLK时钟的上升沿时,数据被写入DS1302,从低位开端。
操控字节输入后下一个SCLK时钟的下降沿时,数据被读出DS1302,从低位开端。
二、试验
程序1:用DS1302完成时钟计时
main.h
# ifndef _MAIN_H_
# define _MAIN_H_
# include
# include
sbit SCK = P3^5 ;
sbit SDA = P3^4 ;
sbit RST = P1^7 ;
typedef unsigned char uint8 ;
typedef unsigned int uint16 ;
uint8 time[7]={50,59,23,15,8,7,10} ;
# define ds1302_w_addr 0x80
# define ds1302_r_addr 0x81
# endif
main.c
# include “main.h”
void delay(uint16 n)
{
while(n–) ;
}
void reset_ds1302(void)
{
RST = 0 ;
SCK = 0 ;
RST = 1 ;
}
void write_ds1302_byte(uint8 dat)
{
uint8 i ;
for(i=0; i<8; i++)
{
SDA = dat&0x01 ;
dat>>=1 ;
SCK = 1 ;
SCK = 0 ;
}
}
uint8 read_ds1302_byte(void)
{
uint8 i,dat=0 ;
for(i=0; i<8; i++)
{
dat>>=1 ;
if(SDA)
dat |= 0x80 ;
SCK = 1 ; //这儿留意SCK = 1 ,SCK = 0有必要连写,否则会导致输出犯错,不知原因
SCK = 0 ;
}
return dat ;
}
void clear_ds1302_wp(void)
{
reset_ds1302() ;
RST = 1 ;
write_ds1302_byte(0x8E) ;
write_ds1302_byte(0) ;
SDA = 0 ;
RST = 0 ;
}
void set_ds1302_wp(void)
{
reset_ds1302() ;
RST = 1 ;
write_ds1302_byte(0x8E) ;
write_ds1302_byte(0x80) ;
SDA = 0 ;
RST = 0 ;
}
void write_ds1302(uint8 addr, uint8 dat)
{
reset_ds1302() ;
RST = 1 ;
write_ds1302_byte(addr) ;
write_ds1302_byte(dat) ;
SDA = 0 ;
RST = 0 ;
}
uint8 read_ds1302(uint8 addr)
{
uint8 temp=0 ;
reset_ds1302() ;
RST = 1 ;
write_ds1302_byte(addr) ;
temp = read_ds1302_byte() ;
SDA = 0 ;
RST = 0 ;
return temp ;
}
void set_time(uint8 *timedata)
{
uint8 i, tmp ;
for(i=0; i<7; i++)
{
tmp = timedata[i]/10 ; //转为BCD码,这儿留意关于DS1302数据的读取,必
timedata[i] = timedata[i] % 10 ; // 须转换成BCD的格局
timedata[i] = tmp*16 + timedata[i] ;
}
clear_ds1302_wp() ;
tmp = ds1302_w_addr ;
for(i=0; i<7; i++)
{
write_ds1302(tmp,timedata[i]) ;
tmp+=2 ;
}
set_ds1302_wp() ;
}
void read_time(uint8 *timedata)
{
uint8 i, tmp ;
tmp = ds1302_r_addr ; //写地址,读数据
for(i=0; i<7; i++)
{
timedata[i] = read_ds1302(tmp) ;
tmp+=2 ;
}
}
void uart_init()
{
SCON = 0x50 ;
TMOD = 0x21 ; //这儿我本来设置了timer0的方法2,可是无效;
TH1 = 0xFD ; //或许我个人的单片机出了点问题,改成timer1就能够了
TL1 = 0xFD ;
TR1 = 1 ;
}
void UART_send_byte(uint8 byte)
{
SBUF = byte ;
while(!TI) ;
TI = 0 ;
}
void UART_send_dat(uint8 dat)
{
UART_send_byte(dat/16 + 0) ;
UART_send_byte(dat + 0) ;
}
void main(void)
{
uart_init() ;
set_time(&time) ;
while(1)
{
read_time(&time) ; //指针的概念,这儿有必要运用&time,由于指针不能做加法
//能够传输地址*timedata,让timedata【i】去运算
UART_send_dat(time[6]) ;
UART_send_byte(-) ;
UART_send_dat(time[4]) ;
UART_send_byte(-) ;
UART_send_dat(time[3]) ;
UART_send_byte( ) ;
UART_send_dat(time[2]) ;
UART_send_byte(:) ;
UART_send_dat(time[1]) ;
UART_send_byte(:) ;
UART_send_dat(time[0]) ;
UART_send_byte() ;
UART_send_byte() ;
delay(10000) ;
}
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/260624.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部