STM32F407驱动DS1302,读出的数据一直为FF,请问如何处理,谢谢

2019-07-20 19:23发布

1.电路

1.jpg

2.ds1302.h
[mw_shl_code=c,true]extern uint8_t read[];
       

#define ds1302clk GPIO_Pin_0
#define ds1302dat GPIO_Pin_1
#define ds1302rst GPIO_Pin_2   
/* 变量 ----------------------------------------------------------------------*/
/* 函数声明 ------------------------------------------------------------------*/
/* 函数定义 ------------------------------------------------------------------*/

void DS1302_Init(void);
void write_1302byte(uint8_t dat);//写一个字节的数据sck上升沿写数据
void write_1302(uint8_t add,uint8_t dat);//向指定寄存器写入一个字节的数据
u8   read_1302(uint8_t add);//读数据
//void ds1302_init(uint8_t *write,uint8_t *time);//初始化1302
//void ds1302_data(uint8_t *read);//处理数据并通过串口打印

int DS1302_SetTime(pContext ctx);
int DS1302_GetTime(pContext ctx);[/mw_shl_code]

3.ds1302.c
[mw_shl_code=c,true]uint8_t read[]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//读秒、分、时、日、月、周、年的寄存器地址
uint8_t write[]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//写秒、分、时、日、月、周、年的寄存器地址
/*CLK RST配置为输出*/
/*DAT 配置为开漏模式,此模式下能够实现真正的双向IO口*/
//CLK PC0
//DAT PC1
//RST PC2
void DS1302_Init(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);//使能GPIOC时钟
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;//25MHz
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
        GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
        GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//开漏输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;//25MHz
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
        GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化       
}

void write_1302byte(uint8_t dat)//写一个字节的数据sck上升沿写数据
{
        uint8_t i=0;
        GPIO_ResetBits(GPIOC,ds1302clk);
        //ds1302clk=0;
    delay_us(2);//延时大约2us
        for(i=0;i<8;i++)
        {
                GPIO_ResetBits(GPIOC,ds1302clk);
                //ds1302clk=0;
                if(dat&0x01)
                GPIO_SetBits(GPIOC,ds1302dat);
                else
                GPIO_ResetBits(GPIOC,ds1302dat);
                //ds1302dat=(dat&0x01);
                delay_us(2);
                GPIO_SetBits(GPIOC,ds1302clk);
                //ds1302clk=1;
                dat>>=1;
                delay_us(1);
        }       
}

uint8_t read_1302(uint8_t add)//读数据
{
        uint8_t i=0,dat1=0x00;
        GPIO_ResetBits(GPIOC,ds1302rst);
        GPIO_ResetBits(GPIOC,ds1302clk);
        //ds1302rst=0;
        //ds1302clk=0;
        delay_us(3);//略微延时2us
        GPIO_SetBits(GPIOC,ds1302rst);
        //ds1302rst=1;
        delay_us(3);//时间要大约3us
        write_1302byte(add);//先写寄存器的地址
        for(i=0;i<8;i++)
        {
                GPIO_SetBits(GPIOC,ds1302clk);
                //ds1302clk=1;
                dat1>>=1;
                GPIO_ResetBits(GPIOC,ds1302clk);
                //ds1302clk=0;//拉低时钟线,以便于数据的读入
                if(GPIO_ReadInputDataBit(GPIOC,ds1302dat)==1)//数据线此时为高电平
                {dat1=dat1|0x80;}
        }
        delay_us(1);
        GPIO_ResetBits(GPIOC,ds1302rst);
        //ds1302rst=0;
        return dat1;
}

void write_1302(uint8_t add,uint8_t dat)//向指定寄存器写入一个字节的数据
{
        GPIO_ResetBits(GPIOC,ds1302rst);
        GPIO_ResetBits(GPIOC,ds1302clk);
        //ds1302rst=0;
        //ds1302clk=0;
        delay_us(1);//略微延时
        GPIO_SetBits(GPIOC,ds1302rst);
        //ds1302rst=1;
        delay_us(2);//时间大约2us
        write_1302byte(add);
        write_1302byte(dat);
        GPIO_ResetBits(GPIOC,ds1302rst);
        GPIO_ResetBits(GPIOC,ds1302clk);
        //ds1302clk=0;
        //ds1302rst=0;
        delay_us(1);
}





int DS1302_SetTime(pContext ctx)
{
        uint8_t i=0;
        u8 time_buff[7];
        //uint8_t time_buff[7]={0,57,19,16,2,2,16};
       
        time_buff[0] = WTDecimalToBCD(ctx->datetime.tm_sec);     //秒
        time_buff[1] = WTDecimalToBCD(ctx->datetime.tm_min);     //分
        time_buff[2] = WTDecimalToBCD(ctx->datetime.tm_hour);    //时
        time_buff[3] = WTDecimalToBCD(ctx->datetime.tm_mday);    //日
        time_buff[4] = WTDecimalToBCD(ctx->datetime.tm_mon);     //月
        time_buff[5] = ctx->datetime.tm_wday;    //周
        time_buff[6] = WTDecimalToBCD(ctx->datetime.tm_year-2000);//年
       
        write_1302(0x8e,0x00);//去除写保护
        for(i=0;i<7;i++)//进行对时
        {
                write_1302(write,time_buff);
        }
        write_1302(0x8e,0x80);//加写保护       
        return 0;
}

int DS1302_GetTime(pContext ctx)
{
        u8 i;
        u8 time_buff[7];//秒分时日月周年
       
        for(i=0;i<7;i++)
        {
                time_buff=read_1302(read);
        }//读数据已经完成       
       
//        ctx->datetime.tm_sec  = BCDtoDec(time_buff+0 , 1);  //秒        //BCD转10
//        ctx->datetime.tm_min  = BCDtoDec(time_buff+1 , 1);  //分        //BCD转10
//        ctx->datetime.tm_hour = BCDtoDec(time_buff+2 , 1);  //时        //BCD转10
//        ctx->datetime.tm_mday = BCDtoDec(time_buff+3 , 1);  //日        //BCD转10
//        ctx->datetime.tm_mon  = BCDtoDec(time_buff+4 , 1);  //月        //BCD转10
//        ctx->datetime.tm_wday = BCDtoDec(time_buff+5 , 1);  //周        //BCD转10
//        ctx->datetime.tm_year = (BCDtoDec(time_buff+6 , 1)+2000);  //年        //BCD转10
//        if(ctx->datetime.tm_sec >=60) ctx->datetime.tm_sec = 0;
       
        if(time_buff[0] >=60) time_buff[0] = 0;
        ctx->datetime.tm_sec  = time_buff[0];
        ctx->datetime.tm_min  = time_buff[1];
        ctx->datetime.tm_hour = time_buff[2];
        ctx->datetime.tm_mday = time_buff[3];
        ctx->datetime.tm_mon  = time_buff[4];
        ctx->datetime.tm_wday = time_buff[5];
        ctx->datetime.tm_year = time_buff[6]+2000;
        return 0;
}





[/mw_shl_code]


4.main.c
初始化时调用DS1302_SetTime(ctx);//设置时钟的函数
之后每秒调用DS1302_GetTime(&context);//读取时钟

读到的结果是:DS1302的每个寄存器都是FF,请问问题出在哪里,谢谢各位!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。