宇宙第一美 2024-03-24 16:32 采纳率: 100%
浏览 3
已结题

ds13020时间错误

使用STM32+DS1302获取时间,但是最后显示的时间是35-17-37 18:68:86这是怎么回事呀,请问该怎么解决呢?


uint8_t  Write_Addr_Buffer[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//????
uint8_t  Read_Addr_Buffer[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//????
uint8_t DS1302_Time_Buffer[7]={0x24,0x34,0x12,0x24,0x11,0x7,0x23};

 

#define DS1302_CLK_PORT                    GPIOB
#define DS1302_CLK_CLK                    RCC_APB2Periph_GPIOB
#define DS1302_CLK_PIN                    GPIO_Pin_8
 
#define DS1302_DAT_PORT                    GPIOB
#define DS1302_DAT_CLK                    RCC_APB2Periph_GPIOB
#define DS1302_DAT_PIN                    GPIO_Pin_9
 
#define DS1302_RST_PORT                    GPIOB
#define DS1302_RST_CLK                    RCC_APB2Periph_GPIOB
#define DS1302_RST_PIN                    GPIO_Pin_7
 
// Pin0-7??CRL??? Pin8-15??CRH??? ????????
#define DS1302_DAT_OutPut_Mode()    {DS1302_DAT_PORT->CRL &= 0xFFFFFFFF;DS1302_DAT_PORT->CRL |= 0x30000000;}
#define DS1302_DAT_InPut_Mode()        {DS1302_DAT_PORT->CRL &= 0xFFFFFFFF;DS1302_DAT_PORT->CRL |= 0x80000000;}
 
//DS1302??????
#define DS1302_DAT_IN()          GPIO_ReadInputDataBit(DS1302_DAT_PORT, DS1302_DAT_PIN)
#define DS1302_CLK_0                 DS1302_CLK_PORT->BSRR = (uint32_t)DS1302_CLK_PIN<<16 // 0
#define DS1302_CLK_1          DS1302_CLK_PORT->BSRR = (uint32_t)DS1302_CLK_PIN // 1
#define DS1302_DAT_0                 DS1302_DAT_PORT->BSRR = (uint32_t)DS1302_DAT_PIN<<16 // 0
#define DS1302_DAT_1                DS1302_DAT_PORT->BSRR = (uint32_t)DS1302_DAT_PIN // 1
#define DS1302_RST_0                 DS1302_RST_PORT->BSRR = (uint32_t)DS1302_RST_PIN<<16 // 0
#define DS1302_RST_1                 DS1302_RST_PORT->BSRR = (uint32_t)DS1302_RST_PIN // 1
 
//DS1302????
#define DS1302_SEC_ADDR           0x80        //ÃëÊý¾ÝµØÖ·
#define DS1302_MIN_ADDR           0x82        //?????
#define DS1302_HOUR_ADDR          0x84        //?????
#define DS1302_DAY_ADDR           0x86        //?????
#define DS1302_MONTH_ADDR         0x88        //?????
#define DS1302_WEEK_ADDR          0x8a        //??????
#define DS1302_YEAR_ADDR          0x8c        //?????
#define DS1302_CONTROL_ADDR       0x8e        //¿ØÖƹ¦ÄܵØÖ·
#define DS1302_CHARGER_ADDR       0x90         //³äµç¹¦ÄܵØÖ·             
#define DS1302_CLKBURST_ADDR      0xbe
 
//?DS1302???????
void DS1302_IO_OUT(void) //ÍÆÍìÊä³ö
{
   GPIO_InitTypeDef GPIO_InitStructure;                       //??????IO????
    
    RCC_APB2PeriphClockCmd(DS1302_DAT_CLK ,ENABLE);    //??PB????
    
    GPIO_InitStructure.GPIO_Pin =  DS1302_DAT_PIN;                 //????PB4
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;              //????,????????
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//?????
    GPIO_Init(DS1302_DAT_PORT, &GPIO_InitStructure);                       //??PB4
}

 void DS1302_GPIO_Init(void) 
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(DS1302_CLK_CLK | DS1302_RST_CLK, ENABLE);
    
    GPIO_InitStructure.GPIO_Pin=DS1302_CLK_PIN;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(DS1302_CLK_PORT,&GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin=DS1302_RST_PIN;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(DS1302_RST_PORT,&GPIO_InitStructure);

    DS1302_IO_OUT();
    
}

void DS1302_IO_IN(void)      //ÉÏÀ­ÊäÈë
{
     GPIO_InitTypeDef GPIO_InitStructure;                       //??????IO????
    
    RCC_APB2PeriphClockCmd(DS1302_DAT_CLK ,ENABLE);    //??PB????
    
    GPIO_InitStructure.GPIO_Pin =  DS1302_DAT_PIN;                 //????PB4
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;              //????,????????
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//?????
    GPIO_Init(DS1302_DAT_PORT, &GPIO_InitStructure);   
}

 void DS1302_WriteByte(uint8_t addr,uint8_t data) //ϽµÑØдÈë
{
    uint8_t i;
    //LED2=!LED2;
    DS1302_RST_0; //?????? !!!?????
    delay_us(20);
    DS1302_CLK_0; //??????SCLK????
    DS1302_RST_1;    //ʹÄÜDS1302    
    addr = addr & 0xFE; 
    for(i=0;i<8;i++) //ÏÈдaddr
    {
        
        if (addr&0x01) 
            DS1302_DAT_1;
        else 
            DS1302_DAT_0;
        addr=addr>>1;
        DS1302_CLK_1; //ÉÏÉýÑضÁÈ¡Êý¾Ý
        delay_us(20);
        DS1302_CLK_0;
        delay_us(20);
    }    
    for (i=0;i<8;i++) //ºóдdata
    {
        if(data&0x01)
            DS1302_DAT_1;
        else 
            DS1302_DAT_0;
        data = data >> 1;
        DS1302_CLK_1;    //?????????
        delay_us(20);
        DS1302_CLK_0;
        delay_us(20);
    }
    DS1302_CLK_1;    // ???????????? ,??????
    delay_us(20);
    delay_us(20);
    DS1302_RST_0;    //??DS1302??
    delay_us(20);
}
 
//?DS1302???????
uint8_t DS1302_ReadByte(uint8_t addr)  //ÉÏÉýÑضÁ³ö
{
    uint8_t i,dat,dat1;    
    DS1302_RST_0; //?????
    delay_us(20);
    DS1302_CLK_0; //??SCLK????,??????SCLK???
    DS1302_RST_1; //??DS1302??
    addr = addr | 0x01; 
    for(i=0;i<8;i++) 
    {
        if (addr&0x01) //Èç¹û×îµÍλΪ1
            DS1302_DAT_1;
        else 
            DS1302_DAT_0;
        addr = addr >> 1;//±íʾÓÒÒÆһλ
        DS1302_CLK_1; //???
        delay_us(20);
        DS1302_CLK_0;
        delay_us(20);
    }    
    //?DS1302????:temp
    //DS1302_DAT_InPut_Mode();
     DS1302_IO_IN();
    for(i=0;i<8;i++)
    {
        dat1=DS1302_DAT_IN();
        dat=(dat>>1)|(dat1<<7); //dat1ÓÒÒÆÆß룬dat×óÒÆһλ£¬È»ºó»òÔËËã
        DS1302_CLK_1;
        delay_us(20);
        DS1302_CLK_0;
        delay_us(20);
    }    
    DS1302_CLK_1;  //???????????
    delay_us(20);
    DS1302_IO_OUT();
    delay_us(20);
    DS1302_RST_0;    //??DS1302??
    delay_us(20);
    DS1302_DAT_0;
    return dat;
}

void DS1302_Read_Time()
{
   uint8_t i;
    for(i=0;i<7;i++)
    {
      DS1302_Time_Buffer[i]=DS1302_ReadByte(Read_Addr_Buffer[i]);//????
    }
    //??  ????????
    DS1302_Time_Buffer[0] &= 0x7f; //×î¸ßλÖÃ0
}

 void DS1302_SetTime() //uint8_t *writeTime
{
    uint8_t i;
    DS1302_WriteByte(0x8e,0x00);//???  wp = 0
    for(i=0;i<7;i++)  //???
        {
          DS1302_WriteByte(Write_Addr_Buffer[i],DS1302_Time_Buffer[i]); //???????
            //LED2=!LED2;
        }
      DS1302_WriteByte(0x8e,0x80);//???  wp = 1
}

void GetTime(DS1302TimeStruct *timeData)
{
    timeData->year=DS1302_Time_Buffer[6]; //????
    timeData->month=DS1302_Time_Buffer[4];  //????
    timeData->day=DS1302_Time_Buffer[3];   //????
    timeData->hour=DS1302_Time_Buffer[2];   //????
    timeData->minute=DS1302_Time_Buffer[1]; //????
    timeData->second=DS1302_Time_Buffer[0]; //????
    timeData->week=DS1302_Time_Buffer[5];  
}

  • 写回答

3条回答 默认 最新

  • 码农阿豪@新空间代码工作室 Java领域优质创作者 2024-03-24 16:32
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    这个问题出现的原因可能是DS1302传感器返回的时间数据格式不正确。需要对获取到的时间数据进行转换。 以下是解决方法: 1.确定时间数据格式 DS1302传感器返回的时间数据格式为BCD码,即以4位二进制形式分别表示一个十进制数的十位和个位。例如:0x35表示十进制数35,即3*10+5=35。 2.将BCD码转换为十进制数 在读取时间数据之后,利用以下代码将BCD码转换为十进制数:
    uint8_t bcd_to_decimal(uint8_t bcd) {
      uint8_t decimal = ((bcd>>4) * 10) + (bcd & 0x0f);
      return decimal;
    }
    

    3.显示正确的时间 在读取时间之后,将得到的BCD码转换为十进制数,并将小时、分钟和秒数依次显示出来。以下是示例代码:

    //读取时间
    for(int i=0; i<7; i++) {
      DS1302_Write(Read_Addr_Buffer[i]);
      DS1302_DAT_InPut_Mode();
      for(int j=0; j<8; j++) {
        DS1302_CLK_0;
        delay_us(2);
        Time_Buffer[i] |= ((uint8_t)DS1302_DAT_IN()) << j;
        DS1302_CLK_1;
        delay_us(2);
      }
      DS1302_DAT_OutPut_Mode();
    }
    //转换BCD码为十进制数
    uint8_t second = bcd_to_decimal(Time_Buffer[0] & 0x7f); //&0x7f是因为第7位是开/关闹钟的标志位,不需要转换
    uint8_t minute = bcd_to_decimal(Time_Buffer[1]);
    uint8_t hour = bcd_to_decimal(Time_Buffer[2] & 0x3f); //&0x3f是因为第6位是12/24小时制的标志位,不需要转换
    //显示时间
    printf("%02d:%02d:%02d", hour, minute, second);
    

    注意:这里假设了时钟已经正常工作,如果时钟出现故障,那么需要优先解决。另外,以上代码只是示例,具体实现需要根据硬件和软件环境进行相应的修改。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 4月1日
  • 已采纳回答 3月24日
  • 创建了问题 3月24日

悬赏问题

  • ¥20 高德地图聚合图层MarkerCluster聚合多个点,但是ClusterData只有其中部分数据,原因应该是有经纬度重合的地方点,现在我想让ClusterData显示所有点的信息,如何实现?
  • ¥100 求Web版SPC控制图程序包调式
  • ¥20 指导如何跑通以下两个Github代码
  • ¥15 大家知道这个后备文件怎么删吗,为啥这些文件我只看到一份,没有后备呀
  • ¥15 C++为什么这个代码没报错运行不出来啊
  • ¥15 一道ban了很多东西的pyjail题
  • ¥15 关于#r语言#的问题:如何将生成的四幅图排在一起,且对变量的赋值进行更改,让组合的图漂亮、美观@(相关搜索:森林图)
  • ¥15 C++识别堆叠物体异常
  • ¥15 微软硬件驱动认证账号申请
  • ¥15 GPT写作提示指令词