打印

STM32:DS1307读取日期及时间数值为85不会变化,请教大牛

[复制链接]
1198|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
flypoppy|  楼主 | 2020-1-31 11:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位对I2C协议比较懂得朋友帮忙看下时序,如果能解决的,有偿服务亦可,可联系我XYZTZ_COM(微信号)联系我,程序如下 ,使用的是STM32F103C8T6的PB6-SCL PB7-SDA;模拟,外接上拉10K电阻,程序如下:
#define DS1307_SDA_PORT         GPIOB
#define DS1307_SDA_IO           GPIO_Pin_7
#define DS1307_SDA_RCC                                        RCC_APB2Periph_GPIOB

#define DS1307_SCLK_PORT        GPIOB
#define DS1307_SCLK_IO          GPIO_Pin_6
#define DS1307_SCLK_RCC        RCC_APB2Periph_GPIOB

#define DS1307_SDA_ON           GPIO_SetBits(DS1307_SDA_PORT,DS1307_SDA_IO)
#define DS1307_SDA_OFF          GPIO_ResetBits(DS1307_SDA_PORT,DS1307_SDA_IO)

#define DS1307_SCLK_ON          GPIO_SetBits(DS1307_SCLK_PORT,DS1307_SCLK_IO)
#define DS1307_SCLK_OFF         GPIO_ResetBits(DS1307_SCLK_PORT,DS1307_SCLK_IO)

#define READ_DS1307_SDA         GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)

#define DS1307_SDA_IN()  {DS1307_SDA_PORT->CRL&=0X0FFFFFFF;DS1307_SDA_PORT->CRL|=(u32)8<<28;}       
#define DS1307_SDA_OUT() {DS1307_SDA_PORT->CRL&=0X0FFFFFFF;DS1307_SDA_PORT->CRL        |=(u32)3<<28;}


void DS1307_Pin_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//OD
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);  //PB6,PB7¸ß
}



void IC_START(void)
{   
        DS1307_SDA_OUT();
  DS1307_SDA_ON;   
  DS1307_SCLK_ON ;   
  delay_us(4);  
  DS1307_SDA_OFF;   
  delay_us(4);
  DS1307_SCLK_OFF;
}
void IC_STOP(void)
{   
        DS1307_SDA_OUT();
  DS1307_SCLK_OFF;
  DS1307_SDA_OFF;
  delay_us(4);
  DS1307_SCLK_ON;
  DS1307_SDA_ON;   
  delay_us(4);
}

u8 I2C_wait_ack(void)
{
        u8 ucerrtime=0;
        DS1307_SDA_OUT();
                delay_us(5);
        DS1307_SDA_ON;
                delay_us(5);
        DS1307_SDA_IN();
        DS1307_SCLK_ON;
        delay_us(5);
        while(READ_DS1307_SDA)
        {
                ucerrtime++;
                if(ucerrtime>250)
                {
                        IC_STOP();
                        return 1;
                }
        }
        DS1307_SCLK_OFF;
        return 0;
}

void I2C_Ack(void)
{
        DS1307_SCLK_OFF;
DS1307_SDA_OUT();       
        delay_us(20);
DS1307_SDA_OFF;
        delay_us(20);
        DS1307_SCLK_ON;
        delay_us(20);
        DS1307_SCLK_OFF;
}

void I2C_NAck(void)
{
       
        DS1307_SCLK_OFF;
  DS1307_SDA_OUT();       
                delay_us(20);
DS1307_SDA_ON;
        delay_us(20);
        DS1307_SCLK_ON;
        delay_us(20);
        DS1307_SCLK_OFF;
}





void I2C_write_byte(unsigned char dat)
{   
  unsigned char i;   
        DS1307_SDA_OUT();       
    DS1307_SCLK_OFF;   
  for (i=0;i<8;i++)     
  {         
                //delay_us(10);
   if((dat&0x80) >> 7) //ouyang
                //if(dat&0x80)
    {
      DS1307_SDA_ON;
    }
    else
    {
      DS1307_SDA_OFF;
    }  
    dat<<=1;      
  delay_us(20);  
    DS1307_SCLK_ON;      
  delay_us(20);
                 DS1307_SCLK_OFF;
                delay_us(20);
  }
   //DS1307_SCLK_OFF;
  //delay_us(1);
}

unsigned char I2C_read_byte(void)
{   
  unsigned char i,dat=0;
        DS1307_SDA_IN();
  delay_us(4);
  for (i=0;i<7;i++)     
  {     
    DS1307_SCLK_OFF;      
    delay_us(20);   
                DS1307_SCLK_ON;          
    delay_us(20);
                dat <<= 1;
    if(READ_DS1307_SDA)  
    {
      //dat |= 0x01;
                        dat++;
    }
                delay_us(3);
  }  
//if(!aaa)
//{I2C_NAck();}
//else
//{I2C_Ack();}
        return (dat);  
}


unsigned char Write1307(unsigned char add, unsigned char dat)
{   
  unsigned char temp;   
  temp=dat/10;   
  temp<<=4;   
  temp=dat%10+temp;      
  IC_START();   
  I2C_write_byte(0xD0);
delay_us(10);               
  I2C_wait_ack();       
  I2C_write_byte(add);
delay_us(10);               
  I2C_wait_ack();             
  I2C_write_byte(temp);  
delay_us(10);               
  //I2C_send_ack(1);   
  IC_STOP();  
        //delay_us(10);       
  return (0);
}

unsigned char Read1307(unsigned char add)
{   
  unsigned char temp,dat;   
  IC_START();   
  I2C_write_byte(0xD0);  
delay_us(10);               
        I2C_wait_ack();       
  I2C_write_byte(add);
delay_us(10);          
                I2C_wait_ack();
  IC_STOP();
  delay_us(10);   
  IC_START();   
  I2C_write_byte(0xD1);  
delay_us(10);               
        I2C_wait_ack();
        dat=I2C_read_byte();        
        delay_us(10);       
  I2C_NAck(); //·ÇÓ¦´ð£»
       
  IC_STOP();              
  temp=dat/16;   
  dat=dat%16;   
  dat=dat+temp*10;      
  return (dat);
}

void Read_RTC(void)
{   
  unsigned char i,*p;  
  p=rtc_address;  
  for(i=0;i<7;i++)  
  {   
    read_rtc_code[i]=Read1307(*p);   
    p++;  
  }
}

void Set_RTC(void)
{   
  unsigned char i,*p;  
  p=rtc_address;  
  for(i=0;i<7;i++)  
  {   
    Write1307(*p,set_rtc_code[i]);
    p++;
  }
}

void refresh(void)
{  
  Read_RTC();//刷新时钟
  second=read_rtc_code[0];
  minute=read_rtc_code[1];
  hour=read_rtc_code[2];
  week=read_rtc_code[3];
  date=read_rtc_code[4];
  month=read_rtc_code[5];
  year=read_rtc_code[6];
}

使用特权

评论回复

相关帖子

沙发
dirtwillfly| | 2020-1-31 22:01 | 只看该作者
但看程序看不出有什么问题的。建议用逻辑分析仪观察一下时序

使用特权

评论回复
板凳
dirtwillfly| | 2020-1-31 22:02 | 只看该作者
但看程序看不出有什么问题的。建议用逻辑分析仪观察一下时序

使用特权

评论回复
地板
yanhaijian| | 2020-2-3 15:38 | 只看该作者
本身可能是芯片BUG,但是程序可以规避这个BUG。

使用特权

评论回复
5
正常,这是芯片自我停止的设计,你读出这个数字后就可以认为是没有使用过的芯片,你初始化写入一个符合规则的合理值就可以运行起来了

使用特权

评论回复
6
xcvista| | 2020-2-4 14:13 | 只看该作者
既然你用的是 STM32F103C8,为何不取消掉片外 DS1307,直接改用片内 RTC 单元?RTC 晶振和纽扣电池直接接到 STM32 上,这样用起来更方便。STM32F1 的 RTC 没有日历功能,但可以支持 UNIX 时间戳,而开源的 UNIX 时间戳和日历互转的代码满天飞。

使用特权

评论回复
7
QQ877789857| | 2020-2-6 11:07 | 只看该作者
是美信品牌的DS1307 ?

使用特权

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

本版积分规则

3

主题

25

帖子

0

粉丝