欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-02 10:12:12
最开始将函数从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