DS1302时钟芯片在STM32F0中的完整应用代码

                                 DS1302在STM32F0中的应用

DS1302在STM32F0中的应用

/**********************第一:首先对端口进行配置****************/
//DS1302时钟端口定义
void GPIO_Configuration(void) 
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    //SCLK
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_ResetBits(GPIOB, GPIO_Pin_12);

    //RST
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_ResetBits(GPIOA, GPIO_Pin_0);

    /*IO:PB2配置为开漏模式,此模式下能够实现真正的双向IO口*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_ResetBits(GPIOB, GPIO_Pin_2);
    
}

uint8_t read_1302(uint8_t add);
void ds1302_data(uint8_t *read);
void write_1302byte(uint8_t dat) ;
void write_1302(uint8_t add,uint8_t dat);
void ds1302_init(uint8_t *write,uint8_t *time);

uint8_t read[] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//读秒、分、时、日、月、周、年的寄存器地址 
uint8_t write[] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//写秒、分、时、日、月、周、年的寄存器地址

void main(char src[]) 
{
   
   /**********************第二:把一个十进制时间戳转换成常规格式的时间****************/

	 char myTime[11] = "1516766898";//存放十进制时间戳
   time_t t;  
   struct tm *p;
   t=atoi(myTime);
   //time(&t);
   p=gmtime(&t);   
   
   uint8_t Second=0,Min=0,Hour=0,Day=0,Month=0,Weekday=0,Year=0,Year_end=0;
   
   Second = (uint8_t)(p->tm_sec);
   Min = (uint8_t)(p->tm_min);
   Hour = (uint8_t)(p->tm_hour+8);
   Day = (uint8_t)(p->tm_mday);
   Month = (uint8_t)(1+p->tm_mon);
   Weekday = (uint8_t)(p->tm_wday);
   //Year = (uint8_t)(1900+p->tm_year);
   
   int unitPlace,tenPlace;
   unitPlace = (1900+p->tm_year)/1%10;   //获取年的个位
   tenPlace  = (1900+p->tm_year)/10%10;  //获取年的十位
   
   Year_end = (uint8_t)(tenPlace*10 + unitPlace);
   
   uint8_t start_time[] = {Second,Min,Hour,Day,Month,Weekday,Year_end};
   ACCLOG("Second = %d\nMin = %d\nHour = %d\nDay = %d\nMonth = %d\nWeekday = %d\nYear_end = %d\n",Second,Min,Hour,Day,Month,Weekday,Year_end);
   
   /**********************第三:ds1302_init()函数:用常规格式的时间初始化DS1302***/
   ds1302_init(write,start_time);
   
   /**********************第四:ds1302_data()函数*******************************
               (1)把时间写入DS1302
               (2)读出DS1302里的时间
              (3)把读出的时间转换成十进制时间戳
              (4)把这个十进制时间戳转换成字符串存入一个字符数组里
   ******************************************************************/                             
   ds1302_data(read);  
   
}

/**********************************DS1302时钟子函数如下*****************************************/

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


//向DS1302指定寄存器写入一个字节的数据
void write_1302(uint8_t add,uint8_t dat)                            
{  
    GPIO_ResetBits(GPIOA,GPIO_Pin_0); //只有在rst为高电平的时候才能进行数据传输  
    GPIO_ResetBits(GPIOB,GPIO_Pin_12); //只有clk为低电平的时候,rst才能被置为高电平  
    //ds1302rst=0;  
    //ds1302clk=0;  
    delay_us(1);                     //略微延时  
    GPIO_SetBits(GPIOA,GPIO_Pin_0);   //clk = 0之后,这里将rst拉高,准备传送数据  
    //ds1302rst=1;  
    delay_us(2);                     //时间大约2us  
    write_1302byte(add);             //先发地址  
    write_1302byte(dat);             //然后发数据  
    GPIO_ResetBits(GPIOA,GPIO_Pin_0); //这里释放总线  
    GPIO_ResetBits(GPIOB,GPIO_Pin_12); //拉低clk,以备下一次数据发送  
    //ds1302clk=0;  
    //ds1302rst=0;  
    delay_us(5);  
  
} 

//从DS1302指定寄存器读数据
uint8_t read_1302(uint8_t add)                     
{  
    uint8_t i=0;  
    uint8_t Return_dat=0x00;  
    GPIO_ResetBits(GPIOA,GPIO_Pin_0);            //ds1302rst=0;  
    GPIO_ResetBits(GPIOB,GPIO_Pin_12);           //ds1302clk=0;  
    delay_us(3);                                 //略微延时2us  
    GPIO_SetBits(GPIOA,GPIO_Pin_0);             //ds1302rst=1;  
    delay_us(3);                                //时间要大约3us  
    write_1302byte(add);                       //先写寄存器的地址  
    for(i=0;i<8;i++)  
    {  
        GPIO_SetBits(GPIOB,GPIO_Pin_12);       //ds1302clk=1; 
        delay_us(5);
        Return_dat >>= 1;  
        delay_us(5);
        GPIO_ResetBits(GPIOB,GPIO_Pin_12);     //ds1302clk=0;//拉低时钟线,以便于数据的读入  
        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2)==1)    //数据线此时为高电平  
        {Return_dat = Return_dat|0x80;}  
    }  
      delay_us(1);  
      GPIO_ResetBits(GPIOA,GPIO_Pin_0);        //ds1302rst=0;释放总线  
      return Return_dat;  
}

//标准时间转换成时间戳
long GetTick(char *str_time)  
{  
    struct tm stm;  
    int iY, iM, iD, iH, iMin, iS;  
  
    memset(&stm,0,sizeof(stm)); 
    
    iY = atoi(str_time);  
    iM = atoi(str_time+5);  
    iD = atoi(str_time+8);  
    iH = atoi(str_time+11);  
    iMin = atoi(str_time+14);  
    iS = atoi(str_time+17);
    
    stm.tm_year=iY-1900;  
    stm.tm_mon=iM-1;  
    stm.tm_mday=iD;  
    stm.tm_hour=iH-8;//注意时区转换  
    stm.tm_min=iMin;  
    stm.tm_sec=iS;  
  
    return mktime(&stm);  
}

//my_itoa
void my_itoa(long i, char *string)  
{  
    int power = 0, j = 0;  
  
    j = i;  
    for (power = 1; j>10; j /= 10)  
        power *= 10;  
  
    for (; power>0; power /= 10)  
    {  
        *string++ = '0' + i / power;  
        i %= power;  
    }  
    *string = '\0';  
    printf("%s\n", string);  
}  

//处理数据
void ds1302_data(uint8_t *read)                                               
{  
    uint8_t i=0,g[7],time[7];  
//  static uint8_t s = 1;  
    for(i=0;i<7;i++)  
    {  
        time[i]=read_1302(read[i]);                          //读数据已经完成  
    }  
    for(i=0;i<7;i++)  
    {  
        g[i]=time[i]%16;                                      //秒个位数据:BCD转十进制  
        time[i]=time[i]/16;                                   //秒十位数据  
    }    
    
   ACCLOG("20%d%d年%d%d月%d%d日%d%d:%d%d:%d%d 星期%d\r\n",time[6],g[6],time[4],g[4],time[3],g[3],time[2],g[2],time[1],g[1],time[0],g[0],g[5]);  
          
    char str_time[14];

    str_time[0] = '2';
    str_time[1] = '0';
    //N2Char():整数转字符串
    str_time[2] = N2Char((int)(time[6]));
    str_time[3] = N2Char((int)g[6]);
    str_time[4] = 32;                    
    str_time[5] = N2Char((int)time[4]);                        
    str_time[6] = N2Char((int)g[4]);                    
    str_time[7] = 32;                         
    str_time[8] = N2Char((int)time[3]);                     
    str_time[9] = N2Char((int)g[3]);                       
    str_time[10] = 32;                   
    str_time[11] = N2Char((int)time[2]);                       
    str_time[12] = N2Char((int)g[2]);                    
    str_time[13] = 32;                         
    str_time[14] = N2Char((int)time[1]);
    str_time[15] = N2Char((int)g[1]);
    str_time[16] = 32; 
    str_time[17] = N2Char((int)time[0]);
    str_time[18] = N2Char((int)g[0]);
   
    long ConfigureCodeTime = GetTick(str_time);  //ConfigureCodeTime中放的是时间戳
    ACCLOG("ConfigureCodeTime is:%ld\n",ConfigureCodeTime); 
    //itoa(ConfigureCodeTime, myTime, 10); //所用stdlib.h库中没有itoa函数,只能自己写
    my_itoa(ConfigureCodeTime,myTime);     //再把ConfigureCodeTime保存的时间戳赋给myTime数组         
       
}

 
//初始化1302
void ds1302_init(uint8_t *write,uint8_t *time)                
{  
    uint8_t i=0,j=0;  
    write_1302(0x8e,0x00);                  //关闭写保护  
    for(i=0;i<7;i++)                        //十进制转BCD码  
    {  
        j=time[i]%10;                       //个位数部分  
        time[i]=(time[i]/10)*16+j;    
    }  
    for(i=0;i<7;i++)                        //进行对时  
    {  
        write_1302(write[i],time[i]);      //在对应寄存器上写入对应的十六进制数据  
    }  
    write_1302(0x8e,0x80);                 //打开写保护  
} 
//整数转字符串
char N2Char(long n)  
{  
    int i;   
    //char flag = 'a'; 
    char c;  
    if ((i=n/10)!=0)  
        N2Char(i);  
    c = n%10 + '0';  
    printf("%c", c);  
    //return flag;
    return c;
    
}

 

 

 

 

 

 

你可能感兴趣的:(项目)