当前位置: 移动技术网 > IT编程>网络>音视频 > DS1307实时时钟RTC读取(STM32)记录

DS1307实时时钟RTC读取(STM32)记录

2020年07月13日  | 移动技术网IT编程  | 我要评论
最开始将函数从51单片机移植过来,如何整都读取出来的数据是65,不是实时时钟数据,查了下手册,发现必须4.5V-5.5V供电才可以,没有办法,跳线解决,但SCL与SDA采用3.3V+10K电阻上拉倒没有问题;读取函数设置如下(PB12 PB13)://初始化IICvoid IIC_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_...

最开始将函数从51单片机移植过来,如何整都读取出来的数据是65,不是实时时钟数据,查了下手册,发现必须4.5V-5.5V供电才可以,没有办法,跳线解决,但SCL与SDA采用3.3V+10K电阻上拉倒没有问题;

读取函数设置如下(PB12 PB13):

//初始化IIC
void IIC_Init(void)
{                         
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );    
       
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13);  
}

 

//IO方向设置;

#define IIC_SDA_PORT    GPIOB
#define IIC_SDA_IO           GPIO_Pin_13
#define IIC_SDA_RCC       RCC_APB2Periph_GPIOB

#define SDA_IN()  {IIC_SDA_PORT->CRH&=0XFF0FFFFF;IIC_SDA_PORT->CRH|=0x00800000;}    
#define SDA_OUT() {IIC_SDA_PORT->CRH&=0XFF0FFFFF;IIC_SDA_PORT->CRH|=0x00300000;}

#define IIC_SCL_PORT    GPIOB
#define IIC_SCL_IO           GPIO_Pin_12
#define IIC_SCL_RCC       RCC_APB2Periph_GPIOB

#define IIC_SCL_PORT    GPIOB
#define IIC_SCL_IO           GPIO_Pin_12
#define IIC_SCL_RCC       RCC_APB2Periph_GPIOB

 

//²úÉúIICÆðʼÐźÅ
void IIC_Start(void)
{
    SDA_OUT();     //sdaÏßÊä³ö
    IIC_SDA=1;            
    IIC_SCL=1;
    delay_us(8);
     IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
    delay_us(8);
    IIC_SCL=0;
}      

void IIC_Stop(void)
{
    SDA_OUT();
    IIC_SCL=0;
    IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
     delay_us(8);
    IIC_SCL=1; 
    IIC_SDA=1;
    delay_us(8);                                   
}


u8 IIC_Wait_Ack(void)
{
    u8 ucErrTime=0;
    SDA_IN();      
    IIC_SDA=1;delay_us(4);       
    IIC_SCL=1;delay_us(4);     
    while(READ_SDA)
    {
        ucErrTime++;
        if(ucErrTime>250)
        {
            IIC_Stop();
            return 1;
        }
    }
    IIC_SCL=0;//ʱÖÓÊä³ö0        
    return 0;  

//²úÉúACKÓ¦´ð
void IIC_Ack(void)
{
    IIC_SCL=0;
    SDA_OUT();
    IIC_SDA=0;
    delay_us(8);
    IIC_SCL=1;
    delay_us(8);
    IIC_SCL=0;
}
//²»²úÉúACKÓ¦´ð            
void IIC_NAck(void)
{
    IIC_SCL=0;
    SDA_OUT();
    IIC_SDA=1;
    delay_us(4);
    IIC_SCL=1;
    delay_us(4);
    IIC_SCL=0;
}                                          
//IIC·¢ËÍÒ»¸ö×Ö½Ú
//·µ»Ø´Ó»úÓÐÎÞÓ¦´ð
//1£¬ÓÐÓ¦´ð
//0£¬ÎÞÓ¦´ð              
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
    SDA_OUT();         
    IIC_SCL=0;//À­µÍʱÖÓ¿ªÊ¼Êý¾Ý´«Êä
    for(t=0;t<8;t++)
    {              
        //IIC_SDA=(txd&0x80)>>7;
        if((txd&0x80)>>7)
            IIC_SDA=1;
        else
            IIC_SDA=0;
        txd<<=1;       
        delay_us(6);   //¶ÔTEA5767ÕâÈý¸öÑÓʱ¶¼ÊDZØÐëµÄ
        IIC_SCL=1;
        delay_us(4); 
        IIC_SCL=0;    
        delay_us(4);
    }     
}         
//¶Á1¸ö×Ö½Ú£¬ack=1ʱ£¬·¢ËÍACK£¬ack=0£¬·¢ËÍnACK   
u8 IIC_Read_Byte(unsigned char ack)
{
    unsigned char i,receive=0;
    SDA_IN();//SDAÉèÖÃΪÊäÈë
    for(i=0;i<8;i++ )
    {
        IIC_SCL=0; 
        delay_us(4);
        IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
        delay_us(2); 
    }                     
    if (!ack)
        IIC_NAck();//·¢ËÍnACK
    else
        IIC_Ack(); //·¢ËÍACK   
    return receive;
}
unsigned char Write1307(unsigned char add,unsigned char dat)//дһ×Ö½Úµ½¶ÔÓ¦µØÖ·È¥
{
  unsigned char temp;
  temp=dat/10; 
  temp<<=4;
  temp=dat%10+temp;
  IIC_Start();
  IIC_Send_Byte(0xD0);     
  IIC_Wait_Ack();
  IIC_Send_Byte(add);   
  IIC_Wait_Ack();    
  IIC_Send_Byte(temp);     
  IIC_Stop();  
  return (0);
}
unsigned char Read1307(unsigned char add)
{
  unsigned char temp;
  unsigned char dat;
  IIC_Start();
  IIC_Send_Byte(0xD0);
  IIC_Wait_Ack();
  IIC_Send_Byte( add);
  IIC_Wait_Ack();
  IIC_Stop(); 
  IIC_Start();
  IIC_Send_Byte(0xD1);
  IIC_Wait_Ack(); 
  dat=IIC_Read_Byte(add); 
  IIC_NAck();
  IIC_Stop();
  temp=dat/16;
  dat=dat%16;
  dat=dat+temp*10;
  return(dat);
}

void NOW_RTC_TIME(void)
{
        second=Read1307(0x00);
        minute=Read1307(0x01);
        hour=Read1307(0x02);
        week=Read1307(0x03);
        date=Read1307(0x04);
        month=Read1307(0x05);
        year=Read1307(0x06);    
}

经过把电压调整至5V之后,问题解决,如果首次使用,还必须读取秒的值看是否是second&0X80,然后设置一次时钟即可;

     Write1307(0x00,0x01); //设置秒
     Write1307(0x01,32);
     Write1307(0x02,0x03);
     Write1307(0x03,0x00);
     Write1307(0x04,0x0B);
     Write1307(0x05,0x04);
     Write1307(0x06,0x14);//设置年

至此OL了,技术使人快乐,分享点滴,共同进步~Q~Q~417179642

本文地址:https://blog.csdn.net/autooy871/article/details/107248039

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网