zoukankan      html  css  js  c++  java
  • DS1302的STM32F103c8t6驱动程序(附代码亲测可用)

    2020-09-27  15:27:37

      使用的DS1302模块:

      

       

      DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。工作电压宽达2.5~5.5V。采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后背电源进行涓细电流充电的能力。DS1302的外部引脚分配如下图所示。DS1302用于数据记录,特别是对某些具有特殊意义的数据点的记录上,能实现数据与出现该数据的时间同时记录,因此广泛应用于测量系统中。

     

      DS1302的一条指令一个字节8位,其中第七位(即最高位)是固定1,这一位如果是0的话,那写进去是无效的。第六位是选择RAM还是CLOCK的,我前边说过,我们这里主要讲CLOCK时钟的使用,它的RAM功能我们不用,所以如果选择CLOCK功能,第六位是0,如果要用RAM,那第六位就是1。从第五到第一位,决定了寄存器的5位地址,而第零位是读写位,如果要写,这一位就是0,如果要读,这一位就是1,如图15-9所示。
            DS1302时钟的寄存器,其中8个和时钟有关的,5位地址分别是00000一直到00111这8个地址,还有一个寄存器的地址是01000,这是涓流充电所用的寄存器,我们这里不讲。在DS1302的数据手册里的地址,直接把第七位、第六位和第零位值给出来了,所以指令就成了80H、81H那些了,最低位是1,那么表示读,最低位是0表示写,如图15-10所示。
            寄存器一:最高位CH是一个时钟停止标志位。如果我们的时钟电路有备用电源部分,上电后,我们要先检测一下这一位,如果这一位是0,那说明我们的时钟在系统掉电后,由于备用电源的供给,时钟是持续正常运行的;如果这一位是1,那么说明我们的时钟在系统掉电后,时钟部分不工作了。若我们的Vcc1悬空或者是电池没电了,当我们下次重新上电时,读取这一位,那这一位就是1,我们可以通过这一位判断时钟在单片机系统掉电后是否持续运行。剩下的7位高3位是秒的十位,低4位是秒的个位,这里注意再提一次,DS1302内部是BCD码,而秒的十位最大是5,所以3个二进制位就够了。
            寄存器二:bit7没意义,剩下的7位高3位是分钟的十位,低4位是分钟的个位。
            寄存器三:bit7是1的话代表是12小时制,是0的话代表是24小时制,bit6固定是0,bit5在12小时制下0代表的是上午,1代表的是下午,在24小时制下和bit4一起代表了小时的十位,低4位代表的是小时的个位。
            寄存器四:高2位固定是0,bit5和bit4是日期的十位,低4位是日期的个位。
            寄存器五:高3位固定是0,bit4是月的十位,低4位是月的个位。
            寄存器六:高5位固定是0,低3位代表了星期。
            寄存器七:高4位代表了年的十位,低4位代表了年的个位。这里特别注意,这里的00到99年指的是2000年到2099年。
           寄存器八:bit7是一个保护位,如果这一位是1,那么是禁止给任何其他的寄存器或者那31个字节的RAM写数据的。因此在写数据之前,这一位必须先写成0。

    可用代码:

    DS1302.c:

      1 #include"DS1302.h"
      2 
      3  /*****************************************
      4  * 函数名:void DS1302_GPIOInit(void)
      5  * 描述  :    DS1302 GPIO配置
      6  * 输入  :
      7  * 输出  :无
      8  * 调用  :
      9         CLK---PB5,
     10         IO--->PB6,
     11         RES--->PB7,
     12  *************************************/
     13 void DS1302_GPIOInit(void)
     14 {
     15   GPIO_InitTypeDef GPIO_InitStructre;
     16   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);            /*open GPIO  clock*/
     17   GPIO_InitStructre.GPIO_Pin= GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
     18   GPIO_InitStructre.GPIO_Speed=GPIO_Speed_50MHz;
     19   GPIO_InitStructre.GPIO_Mode=GPIO_Mode_Out_PP;
     20   GPIO_Init(DS1302_PORT, &GPIO_InitStructre);
     21 }
     22  /*****************************************
     23  * 函数名:void DS1302_IO_GPIO(void)
     24  * 描述  :    DS1302 之 IO GPIO 输入输出配置
     25  * 输入  :FLAG标志位
     26  * 输出  :无
     27 * 调用  :OUT:表示输出,IN:表示输入
     28           FLAG:
     29  *************************************/
     30 void DS1302_IO_GPIO(uchar FLAG)
     31 {
     32   GPIO_InitTypeDef GPIO_InitStructre;
     33   //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);            /*open GPIO  clock*/
     34     /**********配置数据IO端口 输出 **********/
     35     if(FLAG==0x01)
     36   {
     37     GPIO_InitStructre.GPIO_Pin= GPIO_Pin_6;//配置IO_GPIO
     38   GPIO_InitStructre.GPIO_Speed=GPIO_Speed_50MHz;
     39   GPIO_InitStructre.GPIO_Mode=GPIO_Mode_Out_PP;
     40   GPIO_Init(DS1302_PORT, &GPIO_InitStructre);
     41   }
     42     /**********配置数据IO端口 输入**********/
     43     else if(FLAG==0x00)
     44   {
     45      GPIO_InitStructre.GPIO_Pin= GPIO_Pin_6;//配置IO_GPIO
     46    GPIO_InitStructre.GPIO_Speed=GPIO_Speed_50MHz;
     47    GPIO_InitStructre.GPIO_Mode=GPIO_Mode_IPU;  //配置上拉输入 
     48    GPIO_Init(DS1302_PORT, &GPIO_InitStructre);
     49    }
     50 }
     51   /*****************************************
     52  * 函数名:void DS1302_delay(u8 dd)
     53  * 描述  :简单延时
     54  * 输入  :
     55  * 输出  :无
     56  * 调用  :
     57  *************************************/
     58 void DS1302_delay(u8 dd)
     59 {
     60     u8 i;
     61     for(;dd>0;dd--)
     62   for(i=110;i>0;i--);
     63 }
     64 
     65   /*****************************************
     66  * 函数名:void DS1302_Write(uchar add,uchar dat)
     67  * 描述  :DS1302写指令和数据
     68 *  输入  :add:发送地址,dat:所在数据
     69  * 输出  :无
     70  * 调用  :
     71  *************************************/
     72  void DS1302_Write(uchar add,uchar dat)
     73  {
     74  uchar i,temp1,temp2;
     75  temp1=add;
     76  temp2=dat;
     77  RES_Set_1;//RET=1;    
     78 //发送地址     
     79 for(i=0;i<8;i++)
     80  {
     81         if(temp1&0x01)
     82          {IO_Set_1;  }     //IO=1;      
     83         else
     84         { IO_Reset_0;}   //�IO=0;     
     85         temp1=temp1>>1;
     86         CLK_Set_1;            //CLK=1;
     87         DS1302_delay(2);    
     88         CLK_Reset_0;    //CLK=0;
     89   }
     90 
     91 //发送数据
     92 for(i=0;i<8;i++)
     93     {
     94         /*IO=(temp2>>i)&0x01;这一句代替下面屏蔽的内容  */
     95         if(temp2&0x01)
     96          {IO_Set_1;  }     //IO=1;  
     97         else 
     98          { IO_Reset_0;}    //�IO=0;
     99             temp2=temp2>>1;
    100             CLK_Set_1;            //CLK=1;
    101             DS1302_delay(2);    
    102             CLK_Reset_0;    //CLK=0;
    103     } 
    104 RES_Reset_0;// RET=0;
    105  }
    106  
    107  
    108  
    109 
    110 /*****************************************
    111  * 函数名:uchar DS1302_Read(uchar add)
    112  * 描述  :DS1302读数据
    113  *  输入  :add:发送所在地址
    114  * 输出  :
    115  * 调用  :
    116  *************************************/
    117 uchar DS1302_Read(uchar add)
    118 {
    119   uchar i,suf,temp,mm,nn,value;
    120    temp=add;
    121    RES_Set_1;//RET=1;  
    122     //写地址
    123   for(i=0;i<8;i++)
    124       {
    125        if(temp&0x01)
    126        {IO_Set_1;  }     //IO=1; 
    127       else
    128          { IO_Reset_0;}    //IO=0;
    129       temp=temp>>1;
    130         CLK_Set_1;            //CLK=1;
    131         DS1302_delay(2);    
    132         CLK_Reset_0;    //CLK=0;  
    133       }
    134  //读数据
    135         
    136 DS1302_IO_GPIO(IN);//配置IO为输入        
    137   for(i=0;i<8;i++)
    138     { 
    139      suf=suf>>1;//读数据变量
    140      if(IO_Read)    //IO=1
    141      {
    142          suf=suf|0x80; 
    143      }
    144      else     //IO=0
    145      {
    146      suf=suf&0x7f;  
    147      }
    148      
    149         CLK_Set_1;            //CLK=1;
    150         DS1302_delay(2);    
    151         CLK_Reset_0;    //CLK=0;  
    152     }
    153     RES_Reset_0;    // RET=0;
    154     
    155 DS1302_IO_GPIO(OUT);//配置IO为输出,恢复正常状态        
    156 //数据处理转化十进制    
    157 mm=suf/16;
    158 nn=suf%16;
    159 value=mm*10+nn;
    160 return value;        
    161 }
    162 /*****************************************
    163  * 函数名:void DS1302_SetTime(uchar *ad)
    164  * 描述  :DS1302 写入设置时间
    165  *  输入  :add:发送所在地址
    166  * 输出  :
    167  * 调用  :
    168  *************************************/
    169 void DS1302_SetTime(uchar *ad)    
    170   {     
    171    DS1302_Write(0x8e,0x00);   //WP=0 允许数据写入DS1302
    172 /**********以下对时分秒的初始化*************/
    173         DS1302_Write(ds1302_sec_addr,ad[5]);  //
    174         DS1302_Write(ds1302_min_addr,ad[4]);   //
    175         DS1302_Write(ds1302_hour_addr,ad[3]);   //
    176       /**********以下对年月日的初始化*************/
    177      DS1302_Write(ds1302_day_addr,ad[2]);
    178    DS1302_Write(ds1302_month_addr,ad[1]);
    179       DS1302_Write(ds1302_year_addr,ad[0]);     
    180         
    181      DS1302_Write(0x8e,0x80);   //0x8e控制字节地址,bit7=WP WP=1 禁止数据写入DS1302
    182   }
    183     
    184     
    185 /*****************************************
    186  * 函数名: void DS1302_OFF(void)
    187  * 描述  :DS1302时间禁止走时
    188  *  输入  :
    189  * 输出  :
    190  * 调用  :
    191  *************************************/    
    192   void DS1302_OFF(void)
    193   {
    194    uchar temp;
    195    temp=DS1302_Read(0x81);//读取表地址时间
    196    DS1302_Write(0x8e,0x00);//WP=0 允许数据写入DS1302
    197    temp=temp|(1<<7);
    198    DS1302_Write(0x80,temp);//WP=1 禁止数据写入DS1302
    199   
    200   }
    201 /*****************************************
    202  * 函数名: void DS1302_ON(void)
    203  * 描述  :DS1302时间开始运行,走时
    204  *  输入  :
    205  * 输出  :
    206  * 调用  :
    207  *************************************/    
    208   void DS1302_ON(void)
    209   {
    210    uchar temp;
    211    temp=DS1302_Read(0x81);
    212    DS1302_Write(0x8e,0x00);//WP=0 允许数据写入DS1302
    213    temp=temp|(0<<7);
    214    DS1302_Write(0x80,temp);//WP=0 允许数据写入DS1302
    215   
    216   }
    217  
    218  
    219  
    220  
    221  
    222 
    223  /*****************************************
    224  * 函数名:void DS1302_init(uchar *time)
    225  * 描述  :    DS1302初始化
    226  * 输入  :无
    227  * 输出  :无
    228 * 调用  :
    229  *************************************/
    230 void DS1302_init(uchar *time)
    231 {
    232     DS1302_GPIOInit();//GPIO初始化配置
    233     DS1302_delay(2);
    234   RES_Reset_0; //RET=0;
    235   CLK_Reset_0;// CLK=0;
    236     //下面是对DS1302启动电池,不掉电   设置时间
    237     DS1302_Write(0x8e,0x00);//WP=0 允许数据写入DS1302
    238     DS1302_Write(0x90,0xA7);//充电(1个二极管+8K电阻)
    239     DS1302_Write(0x8E,0X80);//开启保护 WP=1
    240     if(DS1302_Read(0X81)&0X80)//查询DS302时钟是否启动,如果时钟停止走动:启动时钟+初始化时钟
    241     { 
    242         DS1302_SetTime(time);//设置设置初始时钟
    243     }
    244     //否则跳过
    245     
    246 }
    247  /*****************************************
    248  * 函数名:void DS1302_Readtime(void)
    249  * 描述  :    DS1302时间读出
    250  * 输入  :无
    251  * 输出  :无
    252 * 调用  :
    253  *************************************/
    254 void DS1302_Readtime(void)
    255 {
    256     label2[0]=DS1302_Read( 0x8D)/10;      //年:十位
    257     label2[1]=DS1302_Read( 0x8D)%10;      //年:个位
    258     label2[2]='/';
    259     label2[3]=DS1302_Read( 0x89)/10;     //月 :
    260     label2[4]=DS1302_Read( 0x89)%10;     //月 :
    261     label2[5]='/';
    262     label2[6]=DS1302_Read( 0x87)/10;     //
    263     label2[7]=DS1302_Read( 0x87)%10;     //
    264     label2[8]=DS1302_Read( 0x85)/10;     //
    265     label2[9]=DS1302_Read( 0x85)%10;     //
    266     label2[10]=':';    
    267     label2[11]=DS1302_Read( 0x83)/10;     //读分
    268     label2[12]=DS1302_Read( 0x83)%10;     //读分
    269     label2[13]=':';
    270     label2[14]=DS1302_Read( 0x81)/10;     //读秒 
    271     label2[15]=DS1302_Read( 0x81)%10;     //读秒 
    272 }
    View Code

    DS1302.h:

     1 #ifndef __DS1302_H__
     2 #define __DS1302_H__
     3 #include <stm32f10x.h>
     4 #define uchar unsigned char
     5 #define uint unsigned int
     6 /***DS1302时钟芯片****************************/
     7 //CLK--->PB5
     8 //IO---->PB6
     9 //RES--->PB7
    10 /****************************/
    11 
    12 #define OUT   0x01
    13 #define IN    0x00
    14 extern uchar label2[16];//时间存放数组
    15 //extern uchar Settime[6]={0x17,0x04,0x18,0x16,0x57,0x30}; //设置时间函数
    16 #define DS1302_PORT   GPIOB
    17 
    18 #define CLK_Reset_0  GPIOB->BRR=GPIO_Pin_5    
    19 #define CLK_Set_1    GPIOB->BSRR=GPIO_Pin_5   
    20 
    21 #define IO_Reset_0   GPIOB->BRR=GPIO_Pin_6    
    22 #define IO_Set_1     GPIOB->BSRR=GPIO_Pin_6 
    23 
    24 #define RES_Reset_0  GPIOB->BRR=GPIO_Pin_7   
    25 #define RES_Set_1    GPIOB->BSRR=GPIO_Pin_7
    26 
    27 #define IO_Read   GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6) 
    28 /*************************/
    29 #define Time_24_Hour    0x00    //24小时制
    30 #define Time_Start     0x00    //开始走时
    31 //DS1302寄存器操作指令定义时间地址
    32 #define ds1302_sec_addr   0x80       //
    33 #define ds1302_min_addr   0x82       //
    34 #define ds1302_hour_addr  0x84       //
    35 #define ds1302_day_addr   0x86       //
    36 #define ds1302_month_addr 0x88       //
    37 #define ds1302_year_addr  0x8c       //
    38 /********************/
    39 void DS1302_GPIOInit(void);
    40 void DS1302_IO_GPIO(uchar FLAG);//配置IO的方向
    41 void DS1302_delay(u8 dd);
    42 void DS1302_Write(uchar add,uchar dat);
    43 uchar DS1302_Read(uchar add);
    44 void DS1302_SetTime(uchar *ad);
    45 void DS1302_OFF(void);
    46 void DS1302_ON(void);
    47 void DS1302_init(uchar *time);
    48 void DS1302_Readtime(void);
    49 
    50 
    51 
    52 #endif
    View Code

     main.c:

     1 #include "stm32f10x.h"
     2 #include "led.h"
     3 #include "key.h" 
     4 #include "usart1.h"
     5 #include "delay.h"
     6 #include "DS1302.h"  
     7 
     8 #define AHB_INPUT 72
     9 
    10 unsigned char uart1_buf[11]={0}; 
    11 volatile u32 time; // ms 计时变量
    12 
    13 u16    t=0,mode=0,flag=0;    
    14 u8 label2[16]; //时间存放数组显示格式  
    15 u8 Settime[6]={0x20,0x09,0x16,0x20,0x59,0x50};  // 初始时间设置: 年 月 日  时 分 秒
    16 
    17 int main(void)
    18 {      
    19     int tt = 0;
    20 
    21     SystemInit();    // 配置系统时钟为72M 
    22     delay_init();
    23     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);            //配置完中断向量表以后才能初始化其他东西
    24     uart_init(9600);     
    25 
    26     TIM2_NVIC_Configuration();                                                     // TIM2 定时配置 
    27     TIM2_Configuration();     
    28     START_TIME;                                                                                     // TIM2 开始计时     
    29     
    30     DS1302_init(Settime);                                                                //时间初始化
    31   DS1302_SetTime(Settime);                                                        //设置初始时间
    32     
    33 
    34     while(1)                    
    35   {        
    36         tt++;
    37         if(tt>=3200000)
    38         {
    39                 tt = 0;
    40             DS1302_Readtime();
    41         printf("%lld,",num);
    42                 printf("20");
    43                 printf("%d",label2[0]);                
    44                 printf("%d",label2[1]);                
    45                 printf("%c",label2[2]);                
    46                 printf("%d",label2[3]);                
    47                 printf("%d",label2[4]);                
    48                 printf("%c",label2[5]);                
    49                 printf("%d",label2[6]);                
    50                 printf("%d, ",label2[7]);    
    51 
    52                 printf("%d",label2[8]);                            
    53                 printf("%d",label2[9]);                
    54                 printf("%c",label2[10]);    
    55                 printf("%d",label2[11]);                
    56                 printf("%d",label2[12]);                
    57                 printf("%c",label2[13]);                
    58                 printf("%d",label2[14]);                
    59                 printf("%d, ",label2[15]);                
    60                 printf("%.2f, %.2f ",PM25,PM10);
    61                 printf("%c",0x0d);
    62                 printf("%c",0x0a);
    63         }
    64 
    65   }
    66 }
    View Code

    参考:

    【转】stm32驱动DS1302芯片

    STM32之DS1302时钟模块程序(稳定并且有详细代码注释)

    实时时钟DS1302详细介绍

  • 相关阅读:
    gerrit 修改前一次提交的方法(转载)
    数据结构实验之图论六:村村通公路 【克鲁斯卡尔算法】
    数据结构实验之图论五:从起始点到目标点的最短步数(BFS)
    数据结构实验之图论四:迷宫探索【dfs 求路径】
    Java 【打印俄文的英文字母】
    【留给自己的独白,长大了】
    Java 【 ArrayList应用 】 (SDUT 4069 C~K的班级)
    你的勇气去哪里了
    Java的 「 “ 结构体 ”」 与 「 “ 自定义排序 ” 」
    Java 中的 SimpleDateFormat 【 parse 和 format 】【转换时间格式】
  • 原文地址:https://www.cnblogs.com/CCWangsj/p/13739845.html
Copyright © 2011-2022 走看看