DS1302疑问,急!!!

2020-01-30 14:03发布

写了一个DS1302数字钟的程序,目前还没有全部写完,只是把秒读出来显示到数码管,可就是显示不出来,一直都显示85不动,请求高手指点,不胜感激!
另外,不知道DS1302初始化的过程,以及写保护的使用,请指教!!!
/*******************************************************************************************************
源代码
*******************************************************************************************************/
#include<reg52.h>
#include"DS1302.H"
#define uchar unsigned char
#define uint unsigned int
sbit DULA=P2^6;/*段选使能*/
sbit WELA=P2^7;/*位选使能*/

uchar Second;
uchar Minute;
uchar Hour;
uchar Week;
uchar Day;
uchar Month;
uchar Year;
uchar H,L;/*设置临时变量的高位和地位*/
uchar code NUM_DU[10]={0x3f,0x06,0x5b,0x4f,
                                              0x66,0x6d,0x7d,0x07,
                                              0x7f,0x6f};
uchar code NUM_WE[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
void DISP_led(uint,uint);
/****************************************************
                                主函数
****************************************************/
void main()
{
        DS1302_SET_time(0x30,0x30,0x02,0x01,0x10,0x04,0x09);/*09-10-1-2-30-30,周四*/
        while(1)
        {
        Second=DS1302_READ(0x81);/*读秒*/
        H=Second/10;/*取秒的高位*/
        L=Second%10;/*取秒的低位*/
        DISP_led(4,H);
        DISP_led(5,L);/*数码管显示秒的高位低位*/
        }
}
/****************************************************
                                数码管显示函数
****************************************************/

void DISP_led(uint W,uint D) /*数码管显示函数*/
{                                          
        WELA=1;/*位锁存关*/
        P0=NUM_WE[W];/*送数据*/
        WELA=0;/*位锁存开,锁存数据*/
        P0=0Xff;/*P0口清零*/
        DULA=1;/*段锁存关*/
        P0=NUM_DU[D];/*送数据*/
        DULA=0;/*段锁存开,锁存数据*/
        DELAY(10);
        P0=0Xff;/*P0口清零*/
}


/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DS1302的头文件
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#ifndef DS1302_H
#define DS1302_H
#define uchar unsigned char
#define uint unsigned int
sbit  DS1302_SCLK = P1^7;              /*实时时钟时钟线引脚*/
sbit  DS1302_IO  = P1^6;              /*实时时钟数据线引脚*/
sbit  DS1302_RST = P1^5;              /*实时时钟复位线引脚*/
void DS1302_WRITE_byte(uchar);        /*向1302写一字节数据*/
uchar DS1302_READ_byte(void);         /*从1302读一字节数据*/
void DS1302_WRITE(uchar,uchar);    /*向1302特定地址写一字节数据*/
uchar DS1302_READ(uchar);         /*从1302特定地址读一字节数据*/
void DS1302_SET_time(uchar,uchar,uchar,uchar,uchar,uchar,uchar);     /*设置1302时间*/
//uchar DS1302_READ_time(uchar);        /*从1302读取时间*/
void DELAY(uint);                     /*延时函数*/
//void INIT_DS1302(void);                                 /*DS1302初始化函数*/
/*************************************************
                        向1302写一个字节数据D
*************************************************/
void DS1302_WRITE_byte(uchar D)
{
        uchar temp;
        uint i;
        DS1302_RST=1;
        for(i=8;i>0;i--)/*连续写入一个字节*/
        {
                //DS1302_SCLK=0;
                temp=(D&0x01);/*取D的最低位*/
                DS1302_IO=(bit)temp;/*把D的最低位赋给IO口*/
                D>>=1;/*将D的次低位变为最低位*/
                DS1302_SCLK=1;/*人为制造一个上升沿,将最低位写入*/
                DS1302_SCLK=0;
        }
        DS1302_RST=0;
}
/*************************************************
                        从1302读一个字节数据
*************************************************/
uchar DS1302_READ_byte(void)
{
        uchar temp=0x00;
        uchar temp_H,temp_L;
        uint i;
        DS1302_RST=1;
        for(i=8;i>0;i--)/*连续读一个字节*/
        {
                //DS1302_SCLK=1;
                if(DS1302_IO)/*判断IO口是否为1*/
                        temp|=0x80;/*是,则取IO口的1到temp最高位*/
                temp>>=1;/*将temp最高位变为次高位,并逐次右移至最低位*/
                DS1302_SCLK=1;/*人为制造一个下降沿,读取数据*/
                //DS1302_SCLK=1;
                DS1302_SCLK=0;
        }
        DS1302_RST=0;
        temp_H=temp/16;/*将temp由十六进制转换为十进制数据*/
        temp_L=temp%16;
        temp=temp_H*10+temp_L;
        return(temp);/*返回temp*/       
}
/*************************************************
                        向1302特定寄存器写一个字节数据
*************************************************/
void DS1302_WRITE(uchar add,uchar date)
{
        DS1302_WRITE_byte(0x8e);
        DS1302_WRITE_byte(0x00);/*取消写保护*/
        DS1302_WRITE_byte(add);
        DS1302_WRITE_byte(date);
}
/*************************************************
                        从1302特定寄存器读一个字节数据
*************************************************/
uchar DS1302_READ(uchar add)
{
        uchar DATE;
        DS1302_WRITE_byte(add);
        DATE=DS1302_READ_byte();
        return(DATE);
}
/*************************************************
                                        1ms延时函数
*************************************************/
void DELAY(uint Tms)
{
        uint i,j;
        for(i=0;i<=Tms;i++)
        {
                for(j=0;j<=123;j++);
        }
}
/*************************************************
                                1302时间设置函数
*************************************************/
void DS1302_SET_time(uchar SEC,uchar MIN,uchar HOU,uchar DAT,uchar MON,uchar WEE,uchar YEA)
{
        DS1302_WRITE(0x80,SEC);/*设置秒*/
        DS1302_WRITE(0x82,MIN);/*设置分*/
        DS1302_WRITE(0x84,HOU);/*设置小时*/
        DS1302_WRITE(0x86,DAT);/*设置日*/
        DS1302_WRITE(0x88,MON);/*设置月*/
        DS1302_WRITE(0x8a,WEE);/*设置星期*/
        DS1302_WRITE(0x8c,YEA);/*设置年号*/
}

#endif
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
16条回答
zhangtian207
1楼-- · 2020-01-31 09:43
我也上来说两句啊,不知道对不对哦,
先把temp备份,temp1=temp;
              temp_l=temp1&0x0f;
              然后通过查表
              disp_number_l=disp_data[temp_l];//
              temp1=temp;
              temp_h=temp1&0xf0;
              disp_number_h=disp_data[temp_h];
               ////uchar disp_data[]为全局变量
mikeseaver
2楼-- · 2020-01-31 10:12
我也写了个程序,当连续读8字节是正常,
读单个字节时不正常,有时能读到有时读不到这是什么原因啊?
请懂的人指点一下
guozhi
3楼-- · 2020-01-31 13:11
 精彩回答 2  元偷偷看……
fuconghua2422
4楼-- · 2020-01-31 19:00
参照DS1302原始数据手册写出来的啊,做成头文件。我测试过我的数据转换功能和数码管显示功能,都正常。问题应该出在时序上面。
magician
5楼-- · 2020-02-01 00:58
时钟不能高于2MHz,5V时;1MHz,3.3V时。不过用io模拟,应该不至于太快。
还有,用到的DS1302_IO P1这个,要初始化为输入使能。用的哪个mcu?
可以用示波器抓一下DS1302_IO上,是否有中间电平的台阶,或者说有竞争。
magician
6楼-- · 2020-02-01 01:40
还有,你的DS1302_SCLK变化的太快,如果是51用于24M,那么DS1302_SCLK高电平的时间就只有1个指令周期,大约0.5us,500ns。
可以看看手册,CLK High Time tCH VCC = 5V (Note 6) 250 ns;2V 1000ns。要是3.3V,500ns有些临界,可以加个nop试试。
或者降低频率到12M.

一周热门 更多>