DS1302时钟芯片 读写 程序 实验通过 特发上来和大家分享

2020-02-04 09:22发布

哈哈,再来一篇。

DS1302 时钟芯片读写程序, 以前看到一个视屏教程 改写的。 觉得不错,自己就总结了一下。  大家可以,试着写成一个C  H 文件,方便以后调用哦。

芯片 STC89C52 12M

/*---------------------------------------------------------
* 文 件 名:DS1302 实时时钟
* 芯    片:STC89c52
* 晶    振:12MHz
* 创 建 者:小强
* 创建日期:2011.12.8
* 修 改 者:
* 修改日期:
* 联系作者:lyg407@126.com   QQ:516380635

* 功能描述:

PS:根据天狼星教学视屏改编,霖锋老师讲的很好.
-------------------------------------------------------------*/
#include<reg51.h>
#include<intrins.h>
#include"uart.h"  //加载串口 头文件

#define uchar unsigned char
#define uint unsigned int

sbit sclk = P1^6;  //DS1302串行时钟
sbit   io = P3^5;  //DS1302数据
sbit  rst = P1^7;  //控制端      1为读写  0为禁止操作

//实际显示的时间
uchar dis_time[8];

//开始设定时间
uchar time_data[7]={11,4,12,8,17,42,01};//year week month date,hour,minute,second
//要写入的地址
uchar write_addr[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};//要写入的年星期。。。地址
//要读的地址
uchar read_addr[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};//要读得年月日地址,把最后一位变成1就为读

//函数声明
void ds1302_write_byte(uchar dat); //DS1302单字节写入 有参数输入
void ds1302_write(uchar addr,uchar dat); //ds1302连续写入地址 数据
uchar ds1302_read(addr);  //DS1302读寄存器,有参数 要读得寄存器地址
void ds1302_set_rtc(); //1302设置时间
void ds1302_read_rtc();//1302读取时间
void ds1302_read_dispose();//1302时间读回来处理




//
void ds1302_write_byte(uchar dat)
{
        uchar i;
        for(i=0;i<8;i++)   //串行bit写入
        {
                sclk=0;
                io=dat&0x01; //先写最低位,与0x01
                dat=dat>>1;  //数据左移一位
                sclk=1;           //时钟拉高
        }       
}

void ds1302_write(uchar addr,uchar dat)
{
        rst=0;_nop_();//延时一会
        sclk=0;_nop_();
        rst=1;_nop_(); //拉高准备写入
        ds1302_write_byte(addr); //first write address
        ds1302_write_byte(dat);
        rst=0;_nop_();        //置低,写保护
        io=1;  
        sclk=1;                //释放总线
}
//读取1302数据
uchar ds1302_read(addr)
{
        uchar i,value;
        rst=0; _nop_();
        sclk=0;_nop_();       
        rst=1; _nop_();
        ds1302_write_byte(addr); //write address
        for(i=0;i<8;i++)        //循环读取8位
        {
                value=value>>1; //first high bit clear
                //首先把第一位清零,下面开始用来读取,首次读取位最低位,then,循环左移
                //最后读取的为数据最高位
                sclk=0;
                if(io)         //数据口为高
                        value=value|0x80;  //那就把当前位置1  或运算。
                sclk=1;               
        }
        rst=0;_nop_();
        sclk=0;_nop_();
        sclk=1;
        io=1;   //释放bus
        return value; //返回数据
}
//1302设置时间
void ds1302_set_rtc() //设置1302数据
{
        uchar i,j;
        for(i=0;i<7;i++)        //首先数据转换为BCD码。也就是16变10进制
        {
                j=time_data/10;  //数据分解十位
                time_data=time_data%10; //数据个位
                time_data=j*16+time_data;//十位乘以16加上个位,数组数据就为10进制        
        }
        ds1302_write(0x8e,0x00); //去除写保护 准备写入数据
        for(i=0;i<7;i++)
        {
                ds1302_write(write_addr,time_data);               
        }
        ds1302_write(0x8e,0x80); //设置时间完成 加上写保护       
}
//1302读取时间
void ds1302_read_rtc()        //1302读取时间
{
        uchar i;
        for(i=0;i<7;i++)
        {
                time_data=ds1302_read(read_addr); //读取时间
                //此刻读回来的数据为BCD码,还应转换为16进制
                //把数据除以16商为十位,余数为个位
                //20=0x14  20/16 商1 余4  0x14
        }               
}
//1302时间读回来处理
void ds1302_read_dispose()        //1302时间读回来处理
{
        dis_time[0]=time_data[6]%16^0x30;  //BCD换算成16进制         秒钟个位
        dis_time[1]=time_data[6]/16^0x30;  //BCD换算成16进制         秒钟十位

        dis_time[2]=time_data[5]%16^0x30;  //BCD换算成16进制         分钟个位
        dis_time[3]=time_data[5]/16^0x30;  //BCD换算成16进制         分钟十位

        dis_time[4]=time_data[4]%16^0x30;  //BCD换算成16进制         分钟个位
        dis_time[5]=time_data[4]/16^0x30;  //BCD换算成16进制         分钟十位               
}
void main()
{
        Init_Uart1();        // 串口1 使用定时器1 波特率发生器 2
        ds1302_set_rtc();
        while(1)
        {
                ds1302_read_rtc();
                ds1302_read_dispose();        //1302时间读回来处理

                UART1_Send_Byte(dis_time[5]);
                UART1_Send_Byte(dis_time[4]);
                UART1_Send_Byte(':');
                UART1_Send_Byte(dis_time[3]);
                UART1_Send_Byte(dis_time[2]);
                UART1_Send_Byte(':');
                UART1_Send_Byte(dis_time[1]);
                UART1_Send_Byte(dis_time[0]);
        }       
}
0条回答

一周热门 更多>