打印

C语言 ds1302 程序

[复制链接]
1320|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
沙发
13392526687| | 2013-10-26 21:41 | 只看该作者
对DS1302的操作最容易出错的就是它的读写时序,如附件中所示。
当对DS1302写数据时,前面的命令与后面紧跟的数据无差别,均是上升沿有效;
当读数据时,前面的命令是上升沿有效,紧跟的DS1302返回的数据是下降沿有效,并且是紧跟写数据的那个时序开始,这点要特别注意,下面是我写的DS1302的读取与设置,是我一直在用的,希望能帮到你。
#include <regx52.h>
#include <intrins.h>

#define DS1302_SCLK P3_4 //1302的SCLK端口
#define DS1302_IO   P3_5 //1302的IO端口
#define DS1302_CE   P3_6 //1302的CE端口

/*1302各寄存器写入与读取命令*********/
#define DS1302_WRITE_SEC 0x80
#define DS1302_READ_SEC 0x81
#define DS1302_WRITE_MIN 0x82
#define DS1302_READ_MIN 0x83
#define DS1302_WRITE_HOUR 0x84
#define DS1302_READ_HOUR 0x85
#define DS1302_WRITE_DAY 0x86
#define DS1302_READ_DAY 0x87
#define DS1302_WRITE_MONTH 0x88
#define DS1302_READ_MONTH 0x89
#define DS1302_WRITE_WEEK 0x8a
#define DS1302_READ_WEEK 0x8b
#define DS1302_WRITE_YEAR 0x8c
#define DS1302_READ_YEAR 0x8d
#define DS1302_WRITE_CONTROL 0x8e
#define DS1302_READ_CONTROL 0x8f

/*DS1302相关函数********************************/
void DS1302_Init();//DS1302初始化
void DS1302_TimeGet();//获取DS1302中的时间
void DS1302_TimeSet();//设置DS1302中的时间
void DS1302_Write(unsigned char dat);//项1302写数据
void DS1302_WriteDatToPos(unsigned char pos,unsigned char dat);//向地址pos写数据dat
unsigned char DS1302_Read();//读1302数据
unsigned char DS1302_ReadDatFromPos(unsigned char pos);//读取pos地址的数据

unsigned char YEAR,MONTH,DAY,HOUR,MIN,SEC,WEEK;//全部变量,用于存储时间信息

void main(){
        DS1302_Init();
        while(1){
                DS1302_TimeGet();
        }
}

void delay(unsigned int i){
        for( ;i>0;i--);
}

void DS1302_Init(){
        unsigned char secs,mins,hours,year,month,day,week;
/*获取当前DS1302中存储的时间及状态信息*********/
        secs = DS1302_ReadDatFromPos(DS1302_READ_SEC);
        mins = DS1302_ReadDatFromPos(DS1302_READ_MIN);
        hours = DS1302_ReadDatFromPos(DS1302_READ_HOUR);
        year = DS1302_ReadDatFromPos(DS1302_READ_YEAR);
        month = DS1302_ReadDatFromPos(DS1302_READ_MONTH);
        day = DS1302_ReadDatFromPos(DS1302_READ_DAY);
        week = DS1302_ReadDatFromPos(DS1302_READ_WEEK);
        mins = (mins>>4)*10 + (mins&0x0F);
        hours = (hours>>4)*10 + (hours&0x0F);
        year = (year>>4)*10 + (year&0x0F);
        month = (month>>4)*10 + (month&0x0F);
        day = (day>>4)*10 + (day&0x0F);
/*若判断DS1302处于未初始化状态或者时间信息存在问题,则初始化之*/
        if((0x80&secs) || (mins>59) || (hours>23) || (year>99) ||\
                 (month>12) || (0==month) || (day>31) || (0==day) || (week>7) || (0==week)){
                         
                DS1302_WriteDatToPos(DS1302_WRITE_CONTROL,0x00);//关闭写保护
                DS1302_WriteDatToPos(DS1302_WRITE_SEC,0x55);
                DS1302_WriteDatToPos(DS1302_WRITE_MIN,0x55);
                DS1302_WriteDatToPos(DS1302_WRITE_HOUR,0x00);
                DS1302_WriteDatToPos(DS1302_WRITE_DAY,0x01);
                DS1302_WriteDatToPos(DS1302_WRITE_MONTH,0x01);
                DS1302_WriteDatToPos(DS1302_WRITE_WEEK,0x02);
                DS1302_WriteDatToPos(DS1302_WRITE_YEAR,0x13);
                DS1302_WriteDatToPos(DS1302_WRITE_CONTROL,0x80);//开启写保护
        }
}
void DS1302_TimeGet(){//获取DS1302中的时间
        unsigned char i,tmp;
        code unsigned char readCmd[]={DS1302_READ_SEC,DS1302_READ_MIN,DS1302_READ_HOUR,\
                                  DS1302_READ_DAY,DS1302_READ_MONTH,DS1302_READ_WEEK,DS1302_READ_YEAR};
        code unsigned char *timePoint[]={&SEC,&MIN,&HOUR,&DAY,&MONTH,&WEEK,&YEAR};
        for(i=0; i<7; i++){
                tmp = DS1302_ReadDatFromPos(readCmd[i]);
                tmp = (tmp>>4)*10 + (tmp&0x0F);
                *timePoint[i]=tmp;
        }

}
void DS1302_TimeSet(){//设置DS1302中的时间
        unsigned char i,tmp;
        code unsigned char writeCmd[]={DS1302_WRITE_SEC,DS1302_WRITE_MIN,DS1302_WRITE_HOUR,\
                                  DS1302_WRITE_DAY,DS1302_WRITE_MONTH,DS1302_WRITE_WEEK,DS1302_WRITE_YEAR};
        code unsigned char *timePoint[]={&SEC,&MIN,&HOUR,&DAY,&MONTH,&WEEK,&YEAR};
        DS1302_WriteDatToPos(DS1302_WRITE_CONTROL,0x00);//关闭写保护
        for(i=0; i<7; i++){
                tmp = *timePoint[i];
                tmp = ((tmp/10)<<4)|(tmp%10);
                DS1302_WriteDatToPos(writeCmd[i],tmp);
        }
        DS1302_WriteDatToPos(DS1302_WRITE_CONTROL,0x80);//开启写保护

}
void DS1302_Write(unsigned char dat){//向1302写数据
        unsigned char i;
        DS1302_SCLK = 0;
        delay(2);
        for(i=0; i<8; i++){
                DS1302_IO = dat&0x01;
                delay(1);
                DS1302_SCLK = 1;
                delay(1);
                DS1302_SCLK = 0;
                dat >>= 1;
        }       
}
void DS1302_WriteDatToPos(unsigned char pos,unsigned char dat){//向地址pos写数据dat
        DS1302_CE = 0;
        DS1302_SCLK = 0;
        DS1302_CE = 1;
        delay(2);
        DS1302_Write(pos);
        DS1302_Write(dat);
        DS1302_SCLK = 1;
        DS1302_CE = 0;
        delay(1);
        DS1302_SCLK = 0;
        DS1302_IO = 0;
}
unsigned char DS1302_Read(){//读1302数据
        unsigned char i,dat;
        delay(2);
        for(i=0; i<8; i++){
                dat >>= 1;
                if(1 == DS1302_IO){
                        dat |= 0x80;
                }
                DS1302_SCLK = 1;
                delay(1);
                DS1302_SCLK = 0;
                delay(1);
        }
        return dat;
}
unsigned char DS1302_ReadDatFromPos(unsigned char pos){//读取pos地址的数据
        unsigned char dat;
        DS1302_CE = 0;
        DS1302_SCLK = 0;
        DS1302_CE = 1;
        DS1302_Write(pos);
        dat = DS1302_Read();
        DS1302_SCLK = 1;
        DS1302_CE = 0;
        delay(1);
        DS1302_SCLK = 0;
        DS1302_IO = 0;
        return dat;
}

ds1302时序.jpg (73.25 KB )

ds1302时序.jpg

使用特权

评论回复
板凳
lirunze| | 2013-10-26 21:56 | 只看该作者
这个很常用的啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

1

帖子

1

粉丝