×
单片机 > 单片机程序设计 > 详情

51单片机的ds1302驱动程序

发布时间:2020-06-05 发布时间:
|
////////////////////////////////////////////////////////////头文件/////////////////////////////////////////////////
/*******************************************************************************
*  标题:  ds1302时钟芯片驱动程序                                                                                                  *
*  文件:  ds1302.h ds1302.c                                                                                                               *
*  日期:  2010-3-12                                                                                                                             *   
*  版本:  1.12(试验通过版)可用51hei单片机开发板                                                  *
*  邮箱:  acsdf139@163.com       qq:526083029                                                                              *
*  网站: 无                                                                                                                                       *
********************************************************************************
*  描述:                                                                                                                                                 *
*         用法:首先在主程序内添加头文件#include"ds1302.c"                                                         *
*      在程序中使用dsgettime(¤ttime)函数获取时钟芯片的时间数据                                     *
*      使用timetostr(¤ttime)函数将时间数据转换液晶字符                                                      *
*      使用datetostr(¤ttime)函数将日期数据转换液晶字符                                                      *            
*       存数据时,直接使用 wr1302(uchar add,uchar dat)即可                                                           *
********************************************************************************
*【版权】自己参照网上,朋友,以及书本资料上写的,所以没有版权                                    *
*【声明】此程序,可用于学习,参考及实际设计中,欢迎转载复制以及建议批评                *
*【技术支持】qq:526083029  小张                                                                                                *
********************************************************************************/
 
#ifndef _DS1302_H_
#define _DS1302_H_
#include
#include
typedef struct __SYSTEMTIME__
{
     unsigned char Second;
     unsigned char Minute;
     unsigned char Hour;
     unsigned char Week;
     unsigned char Day;
     unsigned char Month;
     unsigned char Year;
     unsigned char datestr[11];
     unsigned char timestr[9];
}systime; //定义的时间类型
 
#define uchar unsigned char
#define uint unsigned int
#define am(x) x
#define pm(x) (x+12)               // 转成24小时制
#define dssecond 0x80          //时钟芯片的寄存器位置,存放时间
#define dsminute 0x82
#define dshour  0x84 
#define dsweek  0x8A
#define dsday  0x86
#define dsmonth  0x88
#define dsyear  0x8C 
#define dsbaohu     0x8E
#define on 0x80
#define off 0x00
 
 
extern uchar change(uchar x);
extern uchar bcdtohex(uchar val);
extern void wr1302b(uchar temp);
extern void wr1302(uchar add,uchar dat);
extern uchar re1302b();
extern uchar re1302(uchar address);
extern void dsinit(void);
extern void dsgettime(systime *ds1302);
extern void timetostr(systime *ds1302);
extern void datetostr(systime *ds1302);
 
#endif
 
 
 
 
////////////////////////////////////////////////////////////c程序////////////////////////////////////////////////////
 
#include
#include "ds1302.h"
#include
 
//管角定义
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
sbit dssck=P1^0; 
sbit dssda=P1^1; 
sbit dsrst=P1^2;// DS1302复位
 
 
systime currenttime;      //定义结构体变量不可以在点h文件中定义
uchar flaghour,flagmin,flagsec,flagyear,flagmonth,flagday,flagweek,week_value[2];
/*************************************
函数名:change
函数功能:十进制转换成十六进制
参数:x(十六进制数)
返回:y(十进制数)
备注:无
*************************************/ 
uchar bcdtohex(uchar val)
{
       uchar i;
 
       i = val&0x0f; //按位与,i得到低四位数。
       val >>= 4;    //右移四位,将高四位移到低四位的位置,得到高四位码值。
       val &= 0x0f; //防止移位时高位补进1,只保留高四位码值
       val *= 10;    //高位码值乘以10
       i += val;     //然后与第四位码值相加。
       return i;     //将得到的十进制数返回
}
/*************************************
函数名:wr1302b
函数功能:实时时钟写入一个字节
参数:d
返回:无
备注:配合wr1302使用
*************************************/
void wr1302b(uchar d)
{
    unsigned char i;
    ACC = d;
    for(i=8; i>0; i--)
    {
        dssda = ACC0;            //相当于汇编中的 RRC
        dssck = 1;
        dssck = 0;
        ACC = ACC >> 1;
    }
}
/*************************************
函数名:wr1302
函数功能:向1302中写数据
参数:ucAddr(DS1302地址), ucData(要写的数据)
返回:无
备注:无
*************************************/
 
void wr1302(uchar ucAddr, uchar ucDa)     
{
    dsrst = 0;
    dssck = 0;
    dsrst = 1;
    wr1302b(ucAddr);          // 地址,命令
    wr1302b(ucDa);              // 写1Byte数据
    dssck = 1;
    dsrst = 0;
}
[page]
/*************************************
函数名:re1302b
函数功能:实时时钟读取一字节
参数:无
返回:ACC
备注:配合re1302使用
*************************************/
 
uchar re1302b(void)    
{
    unsigned char i;
    for(i=8; i>0; i--)
    {
        ACC = ACC >>1;                        //相当于汇编中的 RRC
        ACC7 = dssda;
        dssck = 1;
        dssck = 0;
    }
    return(ACC);
}
 
/*************************************
函数名:re1302
函数功能:读数据
参数:ucAddr(地址)
返回:ucData(数据)
备注:无
*************************************/
uchar re1302(uchar ucAddr) //读取DS1302某地址的数据
{
    unsigned char ucData;
    dsrst = 0;
    dssck = 0;
    dsrst = 1;
    wr1302b(ucAddr|0x01);        // 地址,命令
    ucData = re1302b();         // 读1Byte数据
    dssck = 1;
    dsrst = 0;
    return(ucData);
}
/*************************************
函数名:dsinit
函数功能:时钟初始化
参数:无
返回:无
备注:无
*************************************/
void dsinit(void) //时钟初始化可以不填
{
 
              wr1302(dsbaohu,off);
              wr1302(dsyear,0x09);
              wr1302(dsmonth,0x11);
              wr1302(dsday,0x02);
              wr1302(dsweek,0x01);
              wr1302(dshour,0x23);
              wr1302(dsminute,0x57);
              wr1302(dssecond,0x55);
              wr1302(dsbaohu,on);
 
}
/*************************************
函数名:dsgettime
函数功能:获取时间到时间型指针
参数:systime *ds1302(时间型数据指针)
返回:无
备注:无
*************************************/
 
void dsgettime(systime *ds1302) //获取时钟芯片的时钟数据到自定义的结构型数组
{
       unsigned char ReadValue;
       ReadValue = re1302(dssecond);
       ds1302->Second = bcdtohex(ReadValue);
       ReadValue = re1302(dsminute);
       ds1302->Minute = bcdtohex(ReadValue);
       ReadValue = re1302(dshour);
       ds1302->Hour = bcdtohex(ReadValue);
       ReadValue = re1302(dsday);
       ds1302->Day = bcdtohex(ReadValue); 
       ReadValue = re1302(dsweek);
       ds1302->Week = bcdtohex(ReadValue);
       ReadValue = re1302(dsmonth);
       ds1302->Month =bcdtohex(ReadValue);
       ReadValue = re1302(dsyear);
       ds1302->Year = bcdtohex(ReadValue);
}
 
/*************************************
函数名:timetostr
函数功能:将时间转换液晶显示字符放入数组timestr[]
参数:systime *ds1302(时间型数据指针)
返回:无
备注:无
*************************************/
void timetostr(systime *ds1302) 
{ if(flaghour<2)
   {
        ds1302->timestr[0] = ds1302->Hour/10 + '0';
        ds1302->timestr[1] = ds1302->Hour%10 + '0';
       }
        else
          {
             ds1302->timestr[0] = ' ';
             ds1302->timestr[1] = ' ';
              }
       ds1302->timestr[2] = ':';
    if(flagmin<2)
       {
        ds1302->timestr[3] = ds1302->Minute/10 + '0';
        ds1302->timestr[4] = ds1302->Minute%10 + '0';
       }
        else
           {
             ds1302->timestr[3] = ' ';
             ds1302->timestr[4] = ' ';
        }
       ds1302->timestr[5] = ':';
    if(flagsec<2)
    {
        ds1302->timestr[6] = ds1302->Second/10 + '0';
        ds1302->timestr[7] = ds1302->Second%10 + '0';
    }
      else
      {
        ds1302->timestr[6] = ' ';
            ds1302->timestr[7] = ' ';
      }
       ds1302->timestr[8] = '';
}
 
/*************************************
函数名:datetostr
函数功能:将日期转换液晶显示字符放入数组datestr[]
参数:systime *ds1302(时间型数据指针)
返回:无
备注:无
*************************************/
 
void datetostr(systime *ds1302)    //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]
{   if(flagyear<2)                 //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22
    {                              
        ds1302->datestr[0] = '2';
        ds1302->datestr[1] = '0';   
        ds1302->datestr[2] = ds1302->Year/10 + '0';
        ds1302->datestr[3] = ds1302->Year%10 + '0';
       }
        else
           {
             ds1302->datestr[0] = ' ';
             ds1302->datestr[1] = ' ';           
             ds1302->datestr[2] = ' ';
             ds1302->datestr[3] = ' ';
              }
       ds1302->datestr[4] = '/';
       if(flagmonth<2)
       {
        ds1302->datestr[5] = ds1302->Month/10 + '0';
        ds1302->datestr[6] = ds1302->Month%10 + '0';
       }
        else
        {
           ds1302->datestr[5] = ' ';
           ds1302->datestr[6] = ' ';
        }
       ds1302->datestr[7] = '/';
       if(flagday<2)
       {
        ds1302->datestr[8] = ds1302->Day/10 + '0';
        ds1302->datestr[9] = ds1302->Day%10 + '0';
       }
        else
        {
           ds1302->datestr[8] = ' ';
           ds1302->datestr[9] = ' ';    
        }
       if(flagweek<2)
       {
        week_value[0] = ds1302->Week%10 + '0'; 
     //星期的数据另外放到 week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示
       }
        else
        {
           week_value[0] = ' ';
        }
        week_value[1] = '';
 
       ds1302->datestr[10] = ''; //字符串末尾加 '' ,判断结束字符
}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
浅谈AVR中定时器几种工作模式