51单片机之时钟芯片DS1302的使用

2020-01-27 11:50发布

#include"reg52.h"
#define uint unsigned int
#define uchar unsigned char
uchar second,minute,hour,day,month,week,year;
sbit wr=P2^5;
sbit rs=P2^6;
sbit lcde=P2^7;

sbit ds1302=P3^4;
sbit rst=P3^5;
sbit sclk=P3^6;

uchar code table1[]="   11-04-19";
uchar code table2[]=" 23:59:50 week:7";
void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}

void write_com(uchar com)                   //写命令
{
        rs=0;
        lcde=0;
        P0=com;
        delay(2);
        lcde=1;
        delay(2);
        lcde=0;               
}

void write_dat(uchar dat)                          //写数据
{
        rs=1;
        lcde=0;
        P0=dat;
        delay(2);
        lcde=1;
        delay(2);
        lcde=0;               
}

void init1602()
{
        uchar num;
        wr=0;
        write_com(0x38); //显示模式设置
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);//清屏
        write_com(0x80);
        for(num=0;num<11;num++)
        {
                write_dat(table1[num]);
                delay(1);       
        }
        write_com(0x80+0x40);
        for(num=0;num<16;num++)
        {
                write_dat(table2[num]);
                delay(1);
        }               
}

void write1302(uchar dat)
{
        uchar i;
        for(i=0;i<8;i++)
        {
                sclk=0;
                ds1302=dat&0x01;           //当SCLK为0时把数据放在数据口
                delay(1);
                sclk=1;                                   //SCLK为高电平时把数据写进去
                delay(1);
                dat>>=1;
        }

}

uchar read1302()
{
        uchar i,dat;
        for(i=0;i<8;i++)
        {
                dat>>=1;
                sclk=1;                               
                delay(1);
                sclk=0;
                if(ds1302==1)          //当SCLK在下降沿的时候把数据读走
                dat=dat|0x80;
                delay(1);
                               
        }

        return dat;
}

void writeset1302(uchar cmd,uchar dat)                         //一次写两个字节,一个为控制字节,另一个为数据。注意写数据时必须打开写保护寄存器
{
        sclk=0;                                                                                   //开始比RST先为低电平
    rst=0;
        rst=1;
        delay(1);
        write1302(cmd);
        write1302((dat/10)<<4|(dat%10));                   //将10进制转化为压缩的BCD码,传输时为BCD码
        sclk=0;               
        rst=0;
}

uchar readset1302(uchar cmd)
{
        uchar dat,datH,datL,temp;
        rst=0;
        rst=1;
        sclk=0;
        delay(1);
        write1302(cmd);
        dat=read1302();
        sclk=0;         
        rst=0;
        datH=dat/16;                           //将压缩的BCD码转换为十进制书相当于左移4位
        datL=dat%16;                           //
        temp=datH*10+datL;                   //
        return (temp);
}

void init1302()
{
                writeset1302(0x8e,0x00);        ///将写保护寄存器打开允许写操作
                writeset1302(0x80,50);        ///写秒和开启时钟
                writeset1302(0x82,59);        ///分
                writeset1302(0x84,23);                ///        时
                writeset1302(0x86,19);                 ///  日
                writeset1302(0x88,4);                 ///月
                writeset1302(0x8a,7);                 ///  周
                writeset1302(0x8c,11);                ///           年
                writeset1302(0x90,0xa5);      ///打开充电功能,选择2K电阻方式充电
                writeset1302(0x8e,0x80);     ///写保护寄存器,写入保护指?

}

void display1602(uchar dat)
{
        uchar shi,ge;
        shi=dat/10;
        ge=dat%10;
        write_dat(0x30+shi);
        write_dat(0x30+ge);
}

void time()                                         //显示日期和时期
{
        second=readset1302(0x81);
        write_com(0x80+0x40+7);
        display1602(second);

        minute=readset1302(0x83);
        write_com(0x80+0x40+4);
        display1602(minute);

        hour=readset1302(0x85);
        write_com(0x80+0x40+1);
        display1602(hour);

        day=readset1302(0x87);
        write_com(0x80+9);
        display1602(day);

        month=readset1302(0x89);
        write_com(0x80+6);
        display1602(month);

        week=readset1302(0x8b)*10;
        write_com(0x80+0x40+15);
        display1602(week);

        year=readset1302(0x8d);
        write_com(0x80+3);
        display1602(year);       
}
void main()
{
        init1602();
//        init1302();
        while(1)
        {
                time();               
                       
        }

}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
bbxyliyang08
1楼-- · 2020-01-28 06:53
程序有问题啊,writeset1302(0x8e,0x80);   你这个函数是实现10进制数转化BCD码?
lklhzu
2楼-- · 2020-01-28 08:32
本帖最后由 lklhzu 于 2012-11-13 09:56 编辑
bbxyliyang08 发表于 2012-11-11 11:47
程序有问题啊,writeset1302(0x8e,0x80);   你这个函数是实现10进制数转化BCD码?


这个是加写保护,写保护加上后就禁止写入了。但是他这个writeset1302()函数里面已经将十进制转换为BCD码了,所以
writeset1302(0x8e,0x00);        ///将写保护寄存器打开允许写操作
writeset1302(0x90,0xa5);      ///打开充电功能,选择2K电阻方式充电
writeset1302(0x8e,0x80);     ///写保护寄存器,写入保护指?
这几个命令应该都失效了吧!
bbxyliyang08
3楼-- · 2020-01-28 12:39
你这个使时钟怎么不搞调时功能?writeset1302(uchar cmd,uchar dat) 不是将dat 10进制转化为压缩的BCD码,传输时为BCD码
而你0x80是十六进制啊?
zjsdlt2013
4楼-- · 2020-01-28 18:20
显示正常,但时间为什么不跑啊?哪里有问题了?

一周热门 更多>