51学习库(8)--DS1302时钟模块

学过51单片机的回过头来都会觉得51还是比较简单的,在此我将贴出在我的学习过程中,把对各种外设所进行的操作,封装成函数库的形式,以供新手学习。

注:使用的单片机是stc12c5a60s2,该系列单片机属于加强51,在运行速度上是普通51的8-12倍,有关时序的操作需要加以注意。
注2:使用说明:

void main()
{
    InitLCD();     //初始化lcd
    InitDS1302();   //在测试断开电源,电池供电的功能时,注释该行    
    while(1)           //进入死循环,防止看门狗复位
    {   
        GetDS1302();   //提取时间参数 
        //时间参数已提取,此处可以使用显示模块对结果进行显示   
    }
}

申明:本系列全部例程通过单片机开发板,实验亲测有效!

/*  DS1302  */
sbit DS1302_SCLK =P1^0;  //时钟
sbit DS1302_IO   =P1^1;  //数据输入输出
sbit DS1302_RST  =P1^2;  //复位/片选线

struct S_TIME
{                   
    uchar SEC;          //00~59
    uchar MIN;          //00~59
    uchar HR;           //00-23
    uchar DATE;         //00-31
    uchar MONTH;        //01-12
    uchar DAY;          //01-07
    uchar YEAR;         //00-99
}TIME={0x00,0x00,0x12,0x09,0x05,0x02,0x17};//初始化时间参数

uchar dtime[7][2]={     
                     {0x20,0x20},   //秒 十位和个位
                     {0x20,0x20},   //分 十位和个位
                     {0x20,0x20},   //时 十位和个位
                     {0x20,0x20},   //日 十位和个位
                     {0x20,0x20},   //月 十位和个位
                     {0x20,0x20},   //周 十位和个位
                     {0x20,0x20}    //年 十位和个位
                    };
/******************************************************************** 
//函数名称: DS1302_WByte
//函数功能: 往DS1302 写入 1 Byte 数据
//输入值:   ndata: 寄存器的数据或地址
//返回值:   无
***********************************************************************/
void DS1302_WByte(uchar ndata) 
{  
    uchar i;
    for(i=8; i>0; i--)                   //循环8次写入8位数据
    {
        DS1302_IO = (bit)(ndata&0x01);     //取最低位数据,从0位至7位依次传送
        DS1302_SCLK = 1;                   //给一个脉冲,将数据写入1302                 
        _nop_();
        DS1302_SCLK = 0;                   
        ndata>>=1;                         //即ndata = ndata >> 1; 
    } 
}
/******************************************************************** 
//函数名称: DS1302_RByte 
//函数功能: 从DS1302读取 1 Byte数据
//输入值:   无
//返回值:   ndata:读取的数据
***********************************************************************/
uchar DS1302_RByte(void) 
{ 
    uchar i;
    uchar ndata=0;
    for(i=8;i>0;i--)                 //循环8次读出8位数据 
    {
        DS1302_IO=1;                   //初始化数据IO
        ndata>>=1;                  //即ndata = ndata >> 1; 
        if(DS1302_IO) ndata|=0x80;     //从数据口读取1位数据
        DS1302_SCLK = 1;               //给一个脉冲
        _nop_();
        DS1302_SCLK = 0;                     
    }
    return (ndata);                //返回结果
}
/******************************************************************** 
//函数名称: DS1302_Wdata 
//函数功能: 往DS1302某地址写入某数据
//输入值:   nAddr: DS1302地址, ndata: 要写的数据
//返回值:   无
***********************************************************************/
void DS1302_Wdata(uchar nAddr, uchar ndata)
{
    DS1302_RST=0;              
    DS1302_SCLK=0;
    DS1302_RST=1;
    DS1302_WByte(nAddr);       // 写1Byte地址
    DS1302_WByte(ndata);       // 写1Byte数据 
    DS1302_SCLK=1;
    DS1302_RST=0;
} 
/******************************************************************** 
//函数名称: DS1302_Rdata 
//函数功能: 从DS1302某地址读取数据
//输入值:   nAddr: DS1302地址
//返回值:   ndata: 读取的数据
***********************************************************************/
uchar DS1302_Rdata(uchar nAddr)
{
    uchar ndata;
    DS1302_RST=0;
    DS1302_SCLK=0;
    DS1302_RST=1;
    DS1302_WByte(nAddr);       /* 地址,命令 */
    ndata = DS1302_RByte();    /* 读1Byte数据 */
    DS1302_SCLK=1;
    DS1302_RST=0;
    return(ndata);
}
/******************************************************************** 
//函数名称: InitDS1302
//函数功能: DS1302初始时间设定
//输入值:   无
//返回值:   无
***********************************************************************/
void InitDS1302(void)
{
    DS1302_Wdata(0x8e,0x00); //控制命令,WP=0,写操作
    DS1302_Wdata(0x90,0xa5);  
    /*
    地址0x90为充电寄存器,可以对充电电流进行限制,写入
    内容高4位固定为1010(其他组合均不能充电),低4
    位的首2位是选择内部降压二极管的个数的,01代表在
    充电回路串入1个二极管,10代表串入2个;最后2位可
    设定串入的电阻的数值:01为2k欧,10为4k欧,11为8k欧。
    */
    DS1302_Wdata(0x80,TIME.SEC);  //秒
    DS1302_Wdata(0x82,TIME.MIN);  //分
    DS1302_Wdata(0x84,TIME.HR);   //时
    DS1302_Wdata(0x86,TIME.DATE); //日
    DS1302_Wdata(0x88,TIME.MONTH);//月
    DS1302_Wdata(0x8a,TIME.DAY);  //星期
    DS1302_Wdata(0x8c,TIME.YEAR); //年

    DS1302_Wdata(0x8e,0x80); //控制命令,WP=1,写保护
}
/******************************************************************** 
//函数名称: GetDS1302
//函数功能: DS1302当前时间读取
//输入值:   无
//返回值:   无
***********************************************************************/
void GetDS1302(void)
{
    TIME.SEC    = DS1302_Rdata(0x81);    //从DS1302读取秒数据
    dtime[0][0]=(TIME.SEC>>4)+0x30;      //十位
    dtime[0][1]=(TIME.SEC&0x0F)+0x30;    //个位   

    TIME.MIN    = DS1302_Rdata(0x83);    //从DS1302读取分数据
    dtime[1][0]=(TIME.MIN>>4)+0x30;      //十位  
    dtime[1][1]=(TIME.MIN&0x0F)+0x30;    //个位

    TIME.HR     = DS1302_Rdata(0x85);    //从DS1302读取时数据
    dtime[2][0]=(TIME.HR>>4)+0x30;       //十位  
    dtime[2][1]=(TIME.HR&0x0F)+0x30;     //个位

    TIME.DATE   = DS1302_Rdata(0x87);    //从DS1302读取日数据
    dtime[3][0]=(TIME.DATE>>4)+0x30;     //十位  
    dtime[3][1]=(TIME.DATE&0x0F)+0x30;   //个位

    TIME.MONTH  = DS1302_Rdata(0x89);    //从DS1302读取月数据
    dtime[4][0]=(TIME.MONTH>>4)+0x30;    //十位  
    dtime[4][1]=(TIME.MONTH&0x0F)+0x30;  //个位

    TIME.DAY    = DS1302_Rdata(0x8b);    //从DS1302读取星期数据
    dtime[5][0]=(TIME.DAY>>4)+0x30;      //十位  
    dtime[5][1]=(TIME.DAY&0x0F)+0x30;    //个位

    TIME.YEAR   = DS1302_Rdata(0x8d);    //从DS1302读取年数据
    dtime[6][0]=(TIME.YEAR>>4)+0x30;     //十位  
    dtime[6][1]=(TIME.YEAR&0x0F)+0x30;   //个位
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值