打印

ds1302时钟问题

[复制链接]
3538|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ycf0027|  楼主 | 2008-9-8 06:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请教各位大虾:我在调试一个时钟程序,是ds1302;现在遇到的问题是:我设置到少时间再读出时还是多少时间,也就是时钟没有走动;芯片是刚买的.一直不知道是那里出问题了.请各位帮帮忙.程序如下:
/*********************************************************************/
/* 实时时钟模块 时钟芯片型号:DS1302 */ 
/*/
/*********************************************************************/
#include <reg52.h>
//#include <instring.h>
#define uchar unsigned char 
#define uint unsigned int
sbit CLK = P0^4; /*实时时钟时钟线引脚 */
sbit IO = P0^5; /*实时时钟数据线引脚 */
sbit RST = P0^6; /*实时时钟复位线引脚 */
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
sbit p20=P2^0;
sbit p21=P2^1;
sbit p22=P2^2;
sbit p23=P2^3;
sbit p24=P2^4;
sbit p25=P2^5;
sbit p26=P2^6;
sbit p27=P2^7;
//----------------------------------------
uchar coding[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar set_time[7]={0x00,0x50,0x08,0x02,0x04,0x05,0x08};


/******************************************************************** 
*
* 名称: write_byte
* 说明: 
* 功能: 往DS1302写入1Byte数据
* 调用:
* 输入: ucDa 写入的数据 
* 返回值: 无
***********************************************************************/
void write_byte(uchar ucDa) 

uchar i;
ACC = ucDa;
for(i=8; i>0; i--)
{
IO = ACC0; /*相当于汇编中的 RRC */
CLK = 1;
CLK = 0;
ACC = ACC >> 1; 

}
/******************************************************************** 
*
* 名称: uchar read_byte
* 说明: 
* 功能: 从DS1302读取1Byte数据
* 调用: 
* 输入: 
* 返回值: ACC
***********************************************************************/
uchar read_byte(void) 

uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; /*相当于汇编中的 RRC */
ACC7 = IO;
CLK = 1;
CLK = 0;

return(ACC); 
}
/******************************************************************** 
*
* 名称: write_data
* 说明: 先写地址,后写命令/数据
* 功能: 往DS1302写入数据
* 调用: write_byte() 
* 输入: ucAddr: DS1302地址, ucDa: 要写的数据
* 返回值: 无
***********************************************************************/
void write_data(uchar ucAddr, uchar ucDa)
{
RST = 0;
CLK = 0;
RST = 1;
write_byte(ucAddr); /* 地址,命令 */
write_byte(ucDa); /* 写1Byte数据*/
CLK = 1;
RST =0;

/******************************************************************** 
*
* 名称: read_data
* 说明: 先写地址,后读命令/数据
* 功能: 读取DS1302某地址的数据
* 调用: write_byte() , read_byte()
* 输入: ucAddr: DS1302地址
* 返回值: ucDa :读取的数据
***********************************************************************/
uchar read_data(uchar ucAddr)
{
uchar ucDa;
RST = 0;
CLK = 0;
RST = 1;
write_byte(ucAddr); /* 地址,命令 */
ucDa = read_byte(); /* 读1Byte数据 */
CLK = 1;
RST =0;
return(ucDa);
}
/******************************************************************** 
*
* 名称: write_data_bytes
* 说明: 先写地址,后写数据(时钟多字节方式)
* 功能: 往DS1302写入时钟数据(多字节方式)
* 调用: write_byte() 
* 输入: pSecDa: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 控制
* 8Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 1B
* 返回值: 无
***********************************************************************/
void write_data_bytes(uchar *pSecDa)
{
uchar i;
write_data(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
RST = 0;
CLK = 0;
RST = 1;
write_byte(0xbe); /* 0xbe:时钟多字节写命令 */
for (i=8;i>0;i--) /*8Byte = 7Byte 时钟数据 1Byte 控制*/
{
write_byte(*pSecDa);/* 写1Byte数据*/
pSecDa++;
}
CLK = 1;
RST =0;

/******************************************************************** 
*
* 名称: read_data_bytes
* 说明: 先写地址,后读命令/数据(时钟多字节方式)
* 功能: 读取DS1302时钟数据
* 调用: write_byte() , read_byte()
* 输入: pSecDa: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
* 返回值: ucDa :读取的数据
***********************************************************************/
void read_data_bytes(uchar *pSecDa)
{
uchar i;
RST = 0;
CLK = 0;
RST = 1;
write_byte(0xbf); /* 0xbf:时钟多字节读命令 */
for (i=8; i>0; i--) 
{
*pSecDa = read_byte(); /* 读1Byte数据 */
pSecDa++ ;
}
CLK = 1;
RST =0;
}
/******************************************************************** 
*
* 名称: write_rom_bytes
* 说明: 先写地址,后写数据(寄存器多字节方式)
* 功能: 往DS1302寄存器数写入数据(多字节方式)
* 调用: write_byte() 
* 输入: pReDa: 寄存器数据地址
* 返回值: 无
***********************************************************************/
void write_rom_bytes(uchar *pReDa)
{
uchar i;
write_data(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
RST = 0;
CLK = 0;
RST = 1;
write_byte(0xfe); /* 0xfe:ROM多字节写命令 */
for (i=31;i>0;i--) /*31Byte 寄存器数据 */
{
write_byte(*pReDa); /* 写1Byte数据*/
pReDa++ ;
}
CLK = 1;
RST =0;

/******************************************************************** 
*
* 名称: read_rom_bytes
* 说明: 先写地址,后读命令/数据(寄存器多字节方式)
* 功能: 读取DS1302寄存器数据
* 调用: write_byte() , read_byte()
* 输入: pReDa: 寄存器数据地址
* 返回值: 无
***********************************************************************/
void read_rom_bytes(uchar *pReDa)
{
uchar i;
RST = 0;
CLK = 0;
RST = 1;
write_byte(0xff); /* 0xff:ROM多字节读命令 */
for (i=31; i>0; i--) /*31Byte 寄存器数据 */
{
*pReDa = read_byte(); /* 读1Byte数据 */
pReDa++ ;
}
CLK = 1;
RST =0;
}
/******************************************************************** 
*
* 名称: v_Set1302
* 说明: 
* 功能: 设置初始时间
* 调用: write_data() 
* 输入: pSecDa: 初始时间地址。初始时间格式为: 秒 分 时 日 月 星期 年 
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
* 返回值: 无
***********************************************************************/
void v_Set1302(uchar *pSecDa) 
{
uchar i;
uchar ucAddr = 0x80; 
write_data(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
for(i =7;i>0;i--)

write_data(ucAddr,*pSecDa); /* 秒 分 时 日 月 星期 年 */ 
pSecDa++;
ucAddr+=2;
}
write_data(0x8e,0x80); /* 控制命令,WP=1,写保护?*/
}
/******************************************************************** 
*
* 名称: v_Get1302
* 说明: 
* 功能: 读取DS1302当前时间
* 调用: read_data() 
* 输入: ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年 
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
* 返回值: 无
***********************************************************************/
void v_Get1302(uchar ucCurtime[]) 
{
uchar i;
uchar ucAddr = 0x81;
for (i=0;i<7;i++)
{
ucCurtime = read_data(ucAddr);/*格式为: 秒 分 时 日 月 
星期 年 */
ucAddr+=2;
}
}

void delay()
{uint i,j;
   for(i=0;i<1000;i++)    
     {
     for(j=0;j<40;j++){}
     } 
   }

//   延时总时间=cnt*16+24us-----------------------------------
void delay1(unsigned int cnt)
{
 for(;cnt>0;cnt--);
}
//----------------------------------------------------------

void main()
{
    uchar get_time[7];
    v_Set1302(set_time);
    write_data(0x8e,0x0);

    v_Get1302(get_time); 
    do{
    p20=0;
    P1=coding[get_time][1]&0x0f];
    delay1(312);
    p20=1;
    p21=0;
    P1=coding[(get_time][1]>>4)&0x0f];
    delay1(312);
    p21=1;
    }while(1);
}

相关帖子

沙发
原野之狼| | 2008-9-8 09:22 | 只看该作者

说两句

如果你读取的时间来自于DS1302,而不是来自于程序的缓冲,那么问题多半是DS1302的时间没有走,拿示波器看看11.0592K晶振起振了没有,还有就是市场上的假芯片比较多,如果觉得程序和电路没问题,那么最好换一批次芯片试试,我曾经遇到过连换四片芯片都不能工作。后来从旧板子拆了一片来试就可以了,然后换了一批芯片,以后就再也没在DS1302上出过问题了。

使用特权

评论回复
板凳
ycf0027|  楼主 | 2008-9-9 05:48 | 只看该作者

求救

主cpu肯定起振了,硬件电路也应该没有问题;大虾说的"如果你读取的时间来自于DS1302,而不是来自于程序的缓冲,那么问题多半是DS1302的时间没有走",不知道怎么确定我读取的是来自程序缓存???

使用特权

评论回复
地板
原野之狼| | 2008-9-9 13:51 | 只看该作者

不好意思说错了。。

是32.768K晶振。。

“如果你读取的时间来自于DS1302,而不是来自于程序的缓冲,那么问题多半是DS1302的时间没有走”
也就是说你的程序当中用于处理时间的变量的值是怎么修改的?

初始化 v_time;//2008年9月9日13点47分30秒
用v_time初始化1302;

IF(读取1302 OK)
{
   存入 v_time;
}
else
{
   啥也不做;
}

如果程序进入IF分支,那么可以肯定你的时间不走多半是由于1302的时间没有走。
如果程序进入ELSE分支,那么v_time并没有改变。这个时候就要注意了,不是时间不走,而是1302出了问题。。

使用特权

评论回复
5
ycf0027|  楼主 | 2008-9-9 22:09 | 只看该作者

ds1302时钟问题

今天我用示波器观察了一下32.768khz晶振,我不知道到底算不算振荡了;情况是这样的:当我用在实验板上通电后,用示波器观察晶振的一个管脚,输出32.8khz的频率信号,可找个频率信号维持时间很短,然后频率就在不停的变化,变得很小,有时到几赫兹,弄不明白这个是什么意思?我想这个和时间不走应该有很大的关系吧?可晶振为啥会出现这种情况,我没有查找到原因,希望大虾帮帮忙.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

19

帖子

0

粉丝