导航:首页 > 编程语言 > DS1302时间代码的计算

DS1302时间代码的计算

发布时间:2022-09-23 04:04:17

A. 我的DS1302秒大于60请问如何解决啊 下面有代码

显然是芯片问题,也许可以通过合适的外电路设计和软件操作解决,但本质上应换用真货,否则长期可靠性仍无法保证。

B. DS1302芯片如何进行12/24 制显示时间转换的编程(C语言)

修改DS1302芯片的(85h、84h)寄存的BIT7进行12/24小时模式切换,BIT7=1是12小时模式,BIT7=0是24小时模式。

C. 从ds1302中读到的时间是BCD码,那调整ds1302的时间,写进去的是BCD码吗

对的 需要将所写的时间写成bcd码的形式,也就是如果是56那就是0x56h

D. ds1302 写时钟程序 怎么实现掉电后1302继续计时,下次上电后时间和实际时间一样,给个具体的程序写法

ds_rd(0x81); //读取秒
ds_data=ds_data&0x80;
if(ds_data==0x80) //判断是否在运行 没有运行执行
{
ds_write(0x8e,0x00);//关闭写保护
ds_write(0x8c,0x11);//年 年月日什么的专当10进制数看
ds_write(0x88,0x10);//月
ds_write(0x86,0x20);//日
ds_write(0x84,0x01);//时属
ds_write(0x82,0x18);//分
ds_write(0x80,0x00);//秒
ds_write(0x8a,0x05);//星期
ds_write(0x8f,0x80);//打开写保护
}

E. 用12C5A60S2单片机和ds1302做了一个万年历 ,其他的都好,就是一天有35(2*16+3)个小时,求解……急啊

ds1302用的是16进制表示时间的
所以到10点的时候就变成了0x10 在十进制中表示16了 20点的时候0x20变成32小时了
转换方法是
(获取到的时间/16)*10+获取到的时间%16

例如在23点的时候,读出来的数据是0x23 也就是十进制的 35
35/16 = 2
35%16=3
2再乘以10+3就是23点了

F. 有木有大佬帮我解释一下这段ds1302时钟芯片程序是什么意思

在前面的课程中我们已经了解到了不少关于时钟的概念,比如我们用的单片机的主时钟是11.0592M、I2C总线有一条时钟信号线SCL等,这些时钟本质上都是一个某一频率的方波信号。那么除了这些在前面新学到的时钟概念外,还有一个我们早已熟悉的不能再熟悉的时钟概念——年-月-日 时:分:秒,就是我们的钟表和日历给出的时间,它的重要程度我想就不需要多说了吧,在单片机系统里我们把它称作实时时钟,以区别于前面提到的几种方波时钟信号。实时时钟,有时也被称作墙上时钟,很形象的一个名词,对吧,大家知道他们讲的一回事就行了。本章,我们将学习实时时钟的应用,有了它,你的单片机系统就能在漫漫历史长河中找到自己的时间定位啦,可以在指定时间干某件事,或者记录下某事发生的具体时间,等等。除此之外,本章还会学习到C语言的结构体,它也是C语言的精华部分,我们通过本章先来了解它的基础,后面再逐渐达到熟练、灵活运用它,你的编程水平会提高一个档次哦。 15.1 BCD码的学习 在我们日常生产生活中用的最多的数字是十进制数字,而单片机系统的所有数据本质上都是二进制的,所以聪明的前辈们就给我们创造了BCD码。
BCD码(Binary-Coded Decimal)亦称二进码十进制数或二-十进制代码。用4位二进制数来表示1位十进制数中的0~9这10个数字。是一种二进制的数字编码形式,用二进制编码的十进制代码。BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。我们前边讲过十六进制和二进制本质上是一回事,十六进制仅仅是二进制的一种缩写形式而已。而十进制的一位数字,从0到9,最大的数字就是9,再加1就要进位,所以用4位二进制表示十进制,就是从0000到1001,不存在1010、1011、1100、1101、1110、1111这6个数字。BCD码如果到了1001,再加1的话,数字就变成了0001 0000这样的数字了,相当于用了8位的二进制数字表示了2位的十进制数字。关于BCD码更详细的介绍请点击 www.51hei.com 的基础教程栏目里面有很多相关文章.

BCD码的应用还是非常广泛的,比如我们这节课要学的实时时钟,日期时间在时钟芯片中的存储格式就是BCD码,当我们需要把它记录的时间转换成可以直观显示的ASCII码时(比如在液晶上显示),就可以省去一步由二进制的整型数到ASCII的转换过程,而直接取出表示十进制1位数字的4个二进制位然后再加上0x30就可组成一个ASCII码字节了,这样就会方便的多,在后面的实际例程中将看到这个简单的转换。
15.2 SPI时序初步认识 UART、I2C和SPI是单片机通信中最常用的三种通信协议。前边我们已经学了UART和I2C通信协议,这节课我们来学习剩下的SPI通信协议。SPI是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口。SPI是一种高速的、全双工、同步通信总线,标准的SPI也仅仅使用4个引脚,常用于单片机和EEPROM、FLASH、实时时钟、数字信号处理器等器件的通信。SPI通信原理比I2C要简单,它主要是主从方式通信,这种模式通常只有一个主机和一个或者多个从机,标准的SPI是4根线,分别是SSEL(片选,也写作SCS)、SCLK(时钟,也写作SCK)、MOSI(主机输出从机输入Master Output/Slave Input)和MISO(主机输入从机输出Master Input/Slave Output)。
SSEL:从设备片选使能信号。如果从设备是低电平使能的话,当拉低这个引脚后,从设备就会被选中,主机和这个被选中的从机进行通信。
SCLK:时钟信号,由主机产生,和I2C通信的SCL有点类似。
MOSI:主机给从机发送指令或者数据的通道。
MISO:主机读取从机的状态或者数据的通道。
在某些情况下,我们也可以用3根线的SPI或者2根线的SPI进行通信。比如主机只给从机发送命令,从机不需要回复数据的时候,那MISO就可以不要;而在主机只读取从机的数据,不需要给从机发送指令的时候,那MOSI可以不要;当一个主机一个从机的时候,从机的片选有时可以固定为有效电平而一直处于使能状态,那么SSEL可以不要;此时如果再加上主机只给从机发送数据,那么SSEL和MISO都可以不要;如果主机只读取从机送来的数据,SSEL和MOSI都可以不要。 3线和2线的SPI大家要知道怎么回事,实际使用也是有应用的,但是当我们提及SPI的时候,一般都是指标准SPI,都是指4根线的这种形式。
SPI通信的主机也是我们的单片机,在读写数据时序的过程中,有四种模式,要了解这四种模式,首先我们得学习一下2个名词。
CPOL:Clock Polarity,就是时钟的极性。
时钟的极性是什么概念呢?通信的整个过程分为空闲时刻和通信时刻,SCLK在数据发送之前和之后的空闲状态是高电平那么CPOL=1,如果空闲状态SCLK是低电平,那么CPOL=0。
CPHA:Clock Phase,就是时钟的相位。
主机和从机要交换数据,就牵涉到一个问题,即主机在什么时刻输出数据到MOSI上而从机在什么时刻采样这个数据,或者从机在什么时刻输出数据到MISO上而主机什么时刻采样这个数据。同步通信的一个特点就是所有数据的变化和采样都是伴随着时钟沿进行的,也就是说数据总是在时钟的边沿附近变化或被采样。而一个时钟周期必定包含了一个上升沿和一个下降沿,这是周期的定义所决定的,只是这两个沿的先后并无规定。又因为数据从产生的时刻到它的稳定是需要一定时间的,那么,如果主机在上升沿输出数据到MOSI上,从机就只能在下降沿去采样这个数据了。反之如果一方在下降沿输出数据,那么另一方就必须在上升沿采样这个数据。
CPHA=1,就表示数据的输出是在一个时钟周期的第一个沿上,至于这个沿是上升沿还是下降沿,这要是CPOL的值而定,CPOL=1那就是下降沿,反之就是上升沿。那么数据的采样自然就是在第二个沿上了。
CPHA=0,就表示数据的采样是在一个时钟周期的第一个沿上,同样它是什么沿由CPOL决定。那么数据的输出自然就在第二个沿上了。仔细想一下,这里会有一个问题:就是当一帧数据开始传输第一bit时,在第一个时钟沿上就采样该数据了,那么它是在什么时候输出来的呢?有两种情况:一是SSEL使能的边沿,二是上一帧数据的最后一个时钟沿,有时两种情况还会同时生效。
我们以CPOL=1/CPHA=1为例,把时序图画出来给大家看一下,如图15-1所示,。

G. 麻烦老师们大侠们注释一下下面这段51c语言,ds1302时间读取代码。越详细越好,感激不尽啊~

你是在学习吗? 这段代码很简单啊,看不懂证明你还差得很远。基础很重要,要会二进制数学,要有一定的英语基础,能看懂芯片手册,要会C语言,如果会汇编就更好了。
大概给你说一下吧,上半段是读时分秒的,从寄存器读出来以后,根据寄存器的定义进行了处理,把每个数字都分成了两部分存储,下半段类似,是读年月日的。
和0x70相与并右移,意思是只要第6、5、4位,和0x0f相与,意思是只要第3、2、1、0位。
看不到Time数组的定义和用法,所以这里只能猜,与操作和右移操作是为了将数字在什么地方显示出来,比如数码管之类的。

H. 谁有ds1302 oled液晶显示时间的程序代码。谢谢了

我给你一份,我之前写过的程序。
/*
* LCD1602 时钟
*
* author:
* date:2011.2.22
*/
#include "main.h"
#include "ds1302.h"
#include "LCD1602.h"

sbit delua = P2^6;
sbit welua = P2^7;

uint8 Time[7]={55,59,11,22,2,2,11};//秒分时日月周年10-08-15 11:59:55
uint8 T_tmp[7];
uint8 Num, T_n=0;

void delay(uint16 n)
{
while (n--);
}

/*
* 初始化系统定时器
*/
void systimer_init(void)
{
TMOD &= 0x0F;
TMOD |= 0x10;
TH1 = 0xDC; // 定时10ms
TL1 = 0x00;
TR1 = 0;
ET1 = 0;
EA = 1;
}

/*
* 判断键值
*/
/*
uint8 scan_key(void)
{
uint8 val=0;

KeyOut1 = 0;
KeyOut2 = 1;
KeyOut3 = 1;
KeyOut4 = 1;
if(KeyIn4 == 0)
{
delay(KEY_DELAY);
if (KeyIn4 == 0)
{
val = K_ADD;
}
}
while((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));

KeyOut1 = 1;
KeyOut2 = 0;
KeyOut3 = 1;
KeyOut4 = 1;
if(KeyIn4 == 0)
{
delay(KEY_DELAY);
if(KeyIn4 == 0)
val = K_LEFT;
}
while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));

KeyOut1 = 1;
KeyOut2 = 1;
KeyOut3 = 0;
KeyOut4 = 1;
if (KeyIn4 == 0)
{
delay(KEY_DELAY);
if (KeyIn4 == 0)
val = K_SUB;
}
while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));

KeyOut1 = 1;
KeyOut2 = 1;
KeyOut3 = 1;
KeyOut4 = 0;
if (KeyIn2 == 0)
{
delay(KEY_DELAY);
if (KeyIn2 == 0)
val = K_SET;
}
if (KeyIn3 == 0)
{
delay(KEY_DELAY);
if (KeyIn3 == 0)
val = K_ENTER;
}
if (KeyIn4 == 0)
{
delay(KEY_DELAY);
if (KeyIn4 == 0)
val = K_RIGHT;
}
while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));

return val;
}
*/
/*
* 启动clock数字闪烁
*/
void start_flash(void)
{
T_n = 0;

switch (Num)
{
case 0: w_data(6, Time[0]); break;
case 1: w_data(3, Time[1]); break;
case 2: w_data(0, Time[2]); break;
default: break;
}

TH1 = 0xDC; // 定时10ms
TL1 = 0x00;
TR1 = 1;
ET1 = 1;
}

/*
* 停止clock数字闪烁
*/
void stop_flash(void)
{
ET1 = 0;
TR1 = 0;
switch (Num)
{
case 0: w_data(6, Time[0]); break;
case 1: w_data(3, Time[1]); break;
case 2: w_data(0, Time[2]); break;
default: break;
}
}

/*
* 更新LCD时间
*/
void refresh_clock(void)
{
if (Time[0] != T_tmp[0]) // 更新秒
{
T_tmp[0] = Time[0];
w_data(6, Time[0]);
}

if (Time[1] != T_tmp[1]) // 更新分
{
T_tmp[1] = Time[1];
w_data(3, Time[1]);
}

if (Time[2] != T_tmp[2]) // 更新时
{
T_tmp[2] = Time[2];
w_data(0, Time[2]);
}
}

/*
* 时钟设置
*/

void set_clock(void)
{
uint8 k_val, flag=0;

Num = 0;

while (1)
{
// k_val = scan_key();

if (k_val == 0)
{
if (flag == 0)
{
start_flash();
flag = 1;
}
continue;
}

flag = 0;
stop_flash();

if (k_val == K_ENTER)
{
set_time(Time);
break;
}

switch (k_val)
{
case K_ADD:
if (Num == 2)
{
if (Time[Num] >= 23)
Time[Num] = 0;
else
Time[Num]++;
}
else
{
if (Time[Num] >= 59)
Time[Num] = 0;
else
Time[Num]++;
}
break;
case K_SUB:
if (Num == 2)
{
if (Time[Num] == 0)
Time[Num] = 23;
else
Time[Num]--;
}
else
{
if (Time[Num] == 0)
Time[Num] = 59;
else
Time[Num]--;
}
break;
case K_LEFT:
if (Num >= 2)
Num = 0;
else
Num++;
break;
case K_RIGHT:
if (Num == 0)
Num = 2;
else
Num--;
break;
default: break;
}

refresh_clock();
}
}

main()
{
uint8 k_val;

delua = 0;
welua = 0;
systimer_init();
LCD1602_init();
set_time(Time); //初始时间设定

w_string(0, " : : ");
w_data(0, Time[2]); // 时
w_data(3, Time[1]); // 分
w_data(6, Time[0]); // 秒

while (1)
{
read_time(Time);
refresh_clock();
// k_val = scan_key();
if (k_val == K_SET)
set_clock();
}

}

void time1_isr() interrupt 3
{
ET1 = 0;
TH1 = 0xDC; // 定时10ms
TL1 = 0x00;

T_n++;
if (T_n == 50) // 0.5s
{
switch (Num)
{
case 0: clear_data(6); break;
case 1: clear_data(3); break;
case 2: clear_data(0); break;
default: break;
}
}
else if (T_n >= 100) // 1s
{
T_n = 0;
switch (Num)
{
case 0: w_data(6, Time[0]); break;
case 1: w_data(3, Time[1]); break;
case 2: w_data(0, Time[2]); break;
default: break;
}
}

ET1 = 1;
}

/*
* LCD1602显示
*
*/

#include "main.h"
#include "LCD1602.h"

/**
* 等待繁忙标志
*/
/*
void wait(void)
{
P0 = 0xFF;

do
{
RS = 0;
RW = 1;
EN = 0;
EN = 1;
}while (BUSY == 1);
EN = 0;
}
*/

void Delay_1ms(unsigned int Time)
{
unsigned int x, y;
for(x = Time; x > 0; x--)
for(y = 120; y > 0; y--);
}

/**
* 写数据
*/
void w_dat(uint8 dat)
{

RS = 1;
P0 = dat;
Delay_1ms(5);
EN = 1;
Delay_1ms(5);
EN = 0;
}

/**
* 写命令
*/
void w_cmd(uint8 cmd)
{
RS = 0;
P0 = cmd;
Delay_1ms(5);
EN = 1;
Delay_1ms(5);
EN = 0;
}

/**
* 发送字符串到LCD
*/
void w_string(uint8 addr_start, uint8 *p)
{
w_cmd(addr_start | 0x80);
while (*p != '\0')
{
w_dat(*p++);
}
}

/**
* 发送数字到LCD(00~99)
*/
void w_data(uint8 addr_start, uint8 dat)
{
w_cmd(addr_start | 0x80);
w_dat(dat%100/10 + '0');
w_dat(dat%10 + '0');
}

/**
* 显示两位空白
*/

void clear_data(uint8 addr_start)
{
w_cmd(addr_start | 0x80);
w_dat(' ');
w_dat(' ');
}

/**
* 初始化1602
*/
void LCD1602_init(void)
{
w_cmd(0x38); // 16*2显示,5*7点阵,8位数据接口
w_cmd(0x0C); // 显示器开、光标开、光标允许闪烁
w_cmd(0x06); // 文字不动,光标自动右移
w_cmd(0x01); // 清屏
}

/*
* DS1302 突发方式,连读,连写
*
*/

#include "main.h"
#include "ds1302.h"

/**
* 写一个字节
*/
void write_ds1302_byte(uint8 dat)
{
uint8 i;

for (i=0;i<8;i++)
{
SDA = dat & 0x01;
SCK = 1;
dat >>= 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 = 0;
}

return dat;
}

void reset_ds1302(void)
{
RST = 0;
SCK = 0;
RST = 1;
}

/**
* 清除写保护
*/
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 set_time(uint8 *timedata)
{
uint8 i, tmp;

for (i=0; i<7; i++) // 转化为BCD格式
{
tmp = timedata[i] / 10;
timedata[i] = timedata[i] % 10;
timedata[i] = timedata[i] + tmp*16;
}

clear_ds1302_WP(); //清除写保护

reset_ds1302(); //初始化端
RST = 1; //使能拉高
write_ds1302_byte(DS1302_W_ADDR); //时钟突发寄存器写寄存器
for (i=0; i<7; i++)
{
write_ds1302_byte(timedata[i]);
delay(10);
}
write_ds1302_byte(0);
SDA = 0;
RST = 0;

set_ds1302_WP(); //设置写保护
}

/**
* 读时钟数据
*/
void read_time(uint8 *timedata)
{
uint8 i, tmp;

clear_ds1302_WP();

reset_ds1302();
RST = 1;
write_ds1302_byte(DS1302_R_ADDR);
for (i=0; i<7; i++)
{
timedata[i] = read_ds1302_byte();
delay(10);
}
SDA = 0;
RST = 0;

set_ds1302_WP();

for (i=0; i<7; i++) // 转化为正常格式
{
tmp = timedata[i] / 16;
timedata[i] = timedata[i] % 16;
timedata[i] = timedata[i] + tmp*10;
}
}

I. 利用字符型LCD1602和时钟芯片DS1302,显示年月日星期时分秒信息。求解啊。求解。大家多多帮忙啊。。

#include"DS1302.h"
#include <at89x52.h>
/*DS1302
寄存器命令字(读,写)取值范围各位内容(7~0)
读写
秒80H81H00~59CH(7)10SEC(6~4)SEC(3~0)
分82H83H00~590(7)10MIN(6~4)MIN(3~0)
时84H85H 00~12 00~2412/24(7)0(6)10/AP(5~4) HR(3~0)
日86H87H01~28,29,39,310(7),0(6),10DATE(5~4)DATE(3~0)
月88H89H01~120(7),0(6),0(5),10M(4),MONTH(3~0)
星期8AH8BH01~070(7),0(6),0(5),0(4),DAY(3~0)
年8CH8DH01~9919YEAE(7~4)YEAR(3~0)
写保护8EH8FHWP(7),0(6),0(5),0(4),0(3~0)
慢充电90H91HTCS(7),TCS(6),TCS(5),TCS(4),DS(3),DS(2),RS(1),RS(0)
时钟突发BEHBFH//读写秒,分,时,日,月,周,年,写保护,8字节一个
RAM突发FEHFFH//读写31B的RAM,可以不以8字节为单位
CH时钟开关,0开1关
12/241先12小时,2选24小时,12小时下,位5为AM/PM选择位,此位1表PM,24小时下,位5是第二个小时位(20~23)
WP写保护位,0,允许,1,禁止
TCS1010才允许充电
DS二极管选择位 01 一个10两个00,11禁止
RS选择连接在VCC1,VCC2之间的电阻,00禁止01 2K104K118K
*/
uchar DateTime[8]={0x05,0x02,0x04,0x13,0x06,0x02,0x99,0x00};
//分别为 秒,分,时,日,月,周,年,写保护
//uchar DateTime[8]={0x05,0x03,0x04,0x
/*
函数名称:DS1302写入命令函数
功能描述:将命令写入DS1302
全局变量:无
参数说明:Command为要写入的命令
返回说明:
版本:1.0
说明:
*/
void WriteCommand(uchar Command)
{
uchar i;
RST=0;CLK=0;RST=1;
for(i=8;i>0;i--)//发送命令字
{
CLK=0;
DP=Command&0x01;//取一位送数据口
CLK=1;//产生一个上升沿
Command>>=1;
}
}
/*
函数名称:DS1302写入数据函数
功能描述:将数据写入DS1302
全局变量:无
参数说明:SendDat为要写入的命令
返回说明:
版本:1.0
说明:
*/
void WriteData(uchar SendDat)
{
uchar i;
for(i=8;i>0;i--)//发送数值
{
CLK=0;
DP=SendDat&0x01;
CLK=1;
SendDat>>=1;
}
}
/*
函数名称:DS1302读取数据函数
功能描述:从DS1302读取数据
全局变量:无
参数说明:
返回说明:返回读取的一个字节数据
版本:1.0
说明:
*/
uchar ReadData(void)
{
uchar i,RecDat=0;
for(i=0;i<8;i++)//读入数值
{
CLK=1;CLK=0;//产生一个下降沿
if(DP)RecDat|=0x01<<i;//读入数据
}
return RecDat;
}
/*
函数名称:DS1302向某地址单字写函数
功能描述:向某地址写入数据
全局变量:无
参数说明:Command为地址变量,SendDat为所送的数据
返回说明:
版本:1.0
说明:
*/
void WriteByte(uchar Command,uchar SendDat)
{
WriteCommand(Command);
WriteCommand(SendDat);
RST=0;
}
/*
函数名称:DS1302单字节读取某地址数据函数
功能描述:读取某一地址的数据
全局变量:无
参数说明:Command为地址变量
返回说明:返回读取的指定地址数据
版本:1.0
说明:
*/
uchar ReadByte(uchar Command)//读字节子程序,入口参数,命令字
{
uchar RecDat=0;
WriteCommand(Command);
RecDat=ReadData();
RST=0;
return RecDat;
}
/*
读写保护操作,不能在多字节写模式下写入
SendByte(0x8EH,0x80)//向8EH地址写入0x80H数据,实现禁止写入操作
SendByte(0x8EH,0x00)//向8EH地址写入0x00H数据,实现允许写入操作
*/
//允许时钟启动,CH变为0
void OscCtrl(bit CtrlDat)//振荡起动和停止控制,入口参数1起动或0停止
{
if(CtrlDat)WriteByte(0x80,0x00);
elseWriteByte(0x80,0x80);
}
/*
//单字节传送
SendByte(0x80H,0x85);//启动时钟,秒为5
SendByte(0x81H);//读取时间中的秒数据
SendByte(0x82H,0x06);//写入分钟数据为6
SendByte(0x83H);//读取分钟数据
*/
/*
函数名称:DS1302连续写入数据函数
功能描述:
全局变量:无
参数说明:Command为命令,p发送的数据,longth为字节数据
返回说明:
版本:1.0
说明:当写入时间数据时,长度必须为8才可以,当写入RAM数据时数据长度为0~31
*/
void DS1302_BustWrite(uchar Command,uchar longth,uchar *p)
{
uchar i;
WriteCommand(Command);
for(i=longth;i>0;i--)
{
WriteData(*p);
p++;
}
RST=0;
}
/*
函数名称:DS1302连续读数据函数
功能描述:
全局变量:无
参数说明:Command为命令,longth为读取的数据长度,p读出后写入的数组指针
返回说明:
版本:1.0
说明:当读取RAM数据的时候数据长度为0~31
*/
void DS1302_BustReadByte(uchar Command,uchar longth,uchar *p)
{
uchar i;
WriteCommand(Command);
for(i=longth;i>0;i--)
{
//*p=0;
*p=ReadData();
p++;
}
RST=0;
}

J. 利用单片机DS1302芯片编制数字时钟程序:能计算2100之前的秒,分,时,日,星期,月和年的能力,能进行闰

我也是用ds1302芯片来做电子钟的
#include<reg51.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int
sbit sda=P1^0;
sbit clk=P1^1;
sbit rst=P1^2;
sbit rs=P2^0;
sbit rw=P2^1;
sbit en=P2^2;
sbit k1=P3^4; //选择
sbit k2=P3^5; //加
sbit k3=P3^6; //减
sbit k4=P3^7; //确定
uchar tcount=0;
uchar monthsdays[]={0,31,0,31,30,31,30,31,31,30,31,30,31}; //一年中每月的天数
uchar *week[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"}; //每一周
uchar lcd_dsy_buffer1[]={"DATA 00-00-00"}; //lcd 显示
uchar lcd_dsy_buffer2[]={"TIME 00:00:00"};
uchar datetime[7]; //所读取的日期时间
char adjust_index=-1; //当前调节的时间对象
uchar change_flag[]="-MHDM-Y"; //调节分、时、日、月 、年
void delayms(uint x)
{
uchar i;
while(x--)
for(i=0;i<120;i++);
}

// 向ds1302写入一个字节
void write_a_byte_to_ds1302(uchar x)
{
uchar i;
for(i=0;i<8;i++)
{
sda=x&1;
clk=1;
clk=0;
x>>=1;
}
}

//向ds1302读取一个字节
uchar get_a_byte_from_ds1302()
{
uchar i,b,t;
for(i=0;i<8;i++)
{
b>>=1;
t=sda;
b|=t<<7;
clk=1;
clk=0;
}
return b/16*10+b%16;
}

//从ds1302 指定位置读数据
uchar read_data(uchar addr)
{
uchar dat;
rst=0;
clk=0;
rst=1;
write_a_byte_to_ds1302(addr);
dat=get_a_byte_from_ds1302();
clk=1;
rst=0;
return dat;
}

//向第三302某地址写入数据
void write_ds1302(uchar adder,uchar dat)
{
clk=0;
rst=1;
write_a_byte_to_ds1302(adder);
write_a_byte_to_ds1302(dat);
clk=0;
rst=0;
}

//设置时间
void set_ds1302()
{
uchar i;
write_ds1302(0x8e,0x00);
for(i=1;i<7;i++) //写入分、时、日、月、年、
{
write_ds1302(0x80+2*i,(datetime[i]/10<<4)|(datetime[i]%10));
}
write_ds1302(0x8e,0x80);
}

//读取当前日期时间
void gettime()
{
uchar i;
for(i=0;i<7;i++)
{
datetime[i]=read_data(0x81+2*i);
}
}

//读lcd状态
uchar read_lcd_state()
{
uchar state;
rs=0;
rw=1;
en=1;
delayms(1);
state=P0;
en=0;
delayms(1);
return state ;

}

//忙等待
void lcd_busy_wait()
{
while ((read_lcd_state()&0x80)==0x80);
delayms(5);
}

//向lcd写数据
void write_lcd_data(uchar dat)
{
lcd_busy_wait();
rs=1;
rw=0;
en=0;
P0=dat;
en=1;
delayms(1);
en=0;

}

//写lcd指令
void write_lcd_command(uchar cmd)
{
lcd_busy_wait();
rs=0;
rw=0;
en=0;
P0=cmd;
en=1;
delayms(1);
en=0;
}

//lcd初始化
void init_lcd()
{
write_lcd_command(0x38);delayms(1);
write_lcd_command(0x01);delayms(1);
write_lcd_command(0x06);delayms(1);
write_lcd_command(0x0c);delayms(1);
}

//设置液晶显示位置
void set_lcd_pos(uchar p)
{
write_lcd_command(p|0x80);
}

//在lcd上显示字符
void display_lcd_string(uchar p,uchar *s)
{
uchar i;
set_lcd_pos(p);
for(i=0;i<16;i++)
{
write_lcd_data(s[i]);
delayms(1);
}
}

//日期和时间转为数字字符
void format_datetime (uchar d, uchar *a)
{
a[0]=d/10+'0';
a[1]=d%10+'0';

}

//判断是否为闰年
uchar isleapyear(uint y)
{
return (y%4==0&&y%100!=0)||(y%400==0);
}

void refreshweekday()
{
uint i,d,w=5;
for(i=2000;i<2000+ datetime[6];i++)
{
d=isleapyear(i) ? 366:365;
w=(w+d) % 7;
}
d=0;
for(i=1;i<datetime[4];i++)
d+=monthsdays[i];
d+=datetime[3];
datetime[5]=(w+d)%7+1;
}
//年、月、日、时、分
void datetime_adjust(char x)
{
switch (adjust_index)
{
case 6: //年 00-99
if (x==1 && datetime[6]<99) datetime[6]++;
if(x==-1 && datetime[6]>0) datetime[6]--;
monthsdays[2]=isleapyear(2000+datetime[6])?29:28; //2月份天数

if(datetime[3]>monthsdays[datetime[4]])
datetime[3]=monthsdays[datetime[4]];
refreshweekday(); //刷新星期
break;
case 4: //月01-12
if((x==1) && (datetime[4]<12)) datetime[4]++;
if((x==-1) && (datetime[4]>1)) datetime[4]--;
monthsdays[2]=isleapyear(2000+datetime[6])? 29:28; //2月份天数

if(datetime[3]>monthsdays[datetime[4]])
datetime[3]=monthsdays[datetime[4]];
refreshweekday(); //刷新星期
break;
case 3: //日00-28/29/30/31
monthsdays[2]=isleapyear(2000+datetime[6])? 29:28; //2月份天数
if((1==x)&&(datetime[3]<monthsdays[datetime[4]])) datetime[3]++;
if((-1==x)&&(datetime[3]>0)) datetime[3]--;
refreshweekday(); //刷新星期
break;
case 2: //时
if (x==1&&datetime[2]<23) datetime[2]++;
if(x==-1&&datetime[2]>0) datetime[2]--;
break;
case 1: //分
if((x==1) && (datetime[1]<59)) datetime[1]++;
if((x==-1) && (datetime[1]>0)) datetime[1]--;
break;
default:break;
}
}
//定时器0每秒刷新lcd显示
void T0_INT() interrupt 1
{
TH0=-50000/256;
TL0=-50000%256;
if(++tcount!=2) return;
tcount=0;
//按指定格式生成待显示的日期时间串
format_datetime(datetime[6],lcd_dsy_buffer1+5);
format_datetime(datetime[4],lcd_dsy_buffer1+8);
format_datetime(datetime[3],lcd_dsy_buffer1+11);
//星期
strcpy(lcd_dsy_buffer1+13,week[datetime[5]-1]);
//时分秒
format_datetime(datetime[2],lcd_dsy_buffer2+5);
format_datetime(datetime[1],lcd_dsy_buffer2+8);
format_datetime(datetime[0],lcd_dsy_buffer2+11);

//显示年月日、星期、时分秒
display_lcd_string(0x00,lcd_dsy_buffer1);
display_lcd_string(0x40,lcd_dsy_buffer2);
}
//键盘中断
void EX_INT0() interrupt 0
{
if(k1==0)
{
while(k1==0) ;
if(adjust_index==-1||adjust_index==1) adjust_index=7;
adjust_index--;
if(adjust_index==5) adjust_index=4; //跳过对星期的调节
lcd_dsy_buffer2[13]='[';
lcd_dsy_buffer2[14]=change_flag[adjust_index];
lcd_dsy_buffer2[15]=']';
}
else if(k2==0)
{
while(k2==0);
datetime_adjust(1);

}
else if(k3==0)
{
while(k3==0) ;
datetime_adjust(-1);

}
else if(k4==0)
{
while(k4==0) ;
set_ds1302();
lcd_dsy_buffer2[13] = "";
lcd_dsy_buffer2[14] = "";
lcd_dsy_buffer2[15] = "";
adjust_index=-1; //时间继续正常显示

}
}
//主程序
void main()
{
init_lcd();
IE=0x83; //允许INTO,T0中断
IP=0x01;
IT0=0x01;
TMOD=0x01;
TH0=-50000/256;
TL0=-50000%256;
TR0=1;
while(1)
{
if(adjust_index==-1)
gettime();
}
}
我的这个是有做成实物的,成功了

阅读全文

与DS1302时间代码的计算相关的资料

热点内容
删除一个文件夹找不到了 浏览:654
电脑桌面文件管理哪个软件好 浏览:188
苹果数据线头歪了 浏览:135
ghostwin764位系统镜像文件 浏览:443
传感器视频教程下载 浏览:95
flash源文件贺卡下载 浏览:434
如何提高网络扶贫的效果 浏览:654
飞车软件文件夹叫什么 浏览:242
刷ec用什么编程器 浏览:765
方菱数控u盘文件格式 浏览:260
编程为什么输出两个变量 浏览:490
卫星大锅2017用升级吗 浏览:113
玉米win10系统下载 浏览:134
fgo技能升级减cd吗 浏览:129
什么记账app免费好用 浏览:441
网络检测可以检测到什么 浏览:504
sip协议教程 浏览:832
编程哪里可以接项目 浏览:119
孤岛惊魂win10 浏览:246
网络HRV是什么意思 浏览:918

友情链接