当前位置:文档之家› DS1302 时钟芯片 C程序

DS1302 时钟芯片 C程序

/*
程序作者:yuki1406
程序作用:STC89CXX的对DS1302进行读取时间写入时间 没有实现突发模式工作
编写时间:2012年07月16日
结束时间:2012年07月17日
程序版本:V1.0
程序大小:256字节
使用说名:
DS1302内部有31字节静态RAM(随机存储器)
读取地址C1H-FDH写入地址C0H-FCH数值范围0-255
DS1302是SPI总线驱动方式
DS1302控制字
7 6 5 4 3 2 1 0
|-------------------------|
| 1 |RAM|A4|A3|A2|A1|A0|RD|
| |CK | | | | | |WR|
|-------------------------|
控制字最高位必须是逻辑1,如果它为0,则不能把数据写入到DS1302中
位6:如果为0表示存取日历时钟数据,为1表示存取RAM数据
位5至位1(A4-A0):操作单元地址
位0;如果为0表示进行写操作 为1表示读操作

寄存器名称 命令字 取值范围 各位内容
写 读 7 6 5 4 3 2 1 0
秒寄存器 80H 81H 00-59 CH
分寄存器 82H 83H 00-59 0
小时寄存器 84H 85H 01-12或00-23 12/2
日期寄存器 86H 87H 01-28,29,30,31 0
月份寄存器 88H 89H 01-12 0
周寄存器 8AH 8BH 01-07 0
年份寄存器 8CH 8DH 00-99

更新时间:2012年07月17日
更新版本:无
更新日志:
2012年07月17日 文件大小:256字节
2012年07月17日 开始优化代码 将相同的代码写成函数以便调用
2012年07月17日 文件大小:276字节
2012年07月17日 除了突发功能没有编写其他的均已写出
2012年07月16日 开始编写驱动函数
*/
#ifndef __DS_1302_H__
#define __DS_1302_H__
#include //包含单片机寄存器的头文件
#define uchar unsigned char
#define uint unsigned int
/*DS1302秒寄存器地址*/
#define Read_ss 0x81 //读取的秒地址
#define Write_ss 0x80 //写入的秒地址
//////////////////////////////////////////////
#define ds_run 0x7f //允许时钟运行 在秒寄存器最高位 &运算
#define ds_stop 0x80 //停止时钟运行 在秒寄存器最高位
/*DS1302分钟寄存器地址*/
#define Read_mm 0x83 //读取的分地址
#define Write_mm 0x82 //写入的分地址
/*DS1302小时寄存器地址*/
#define Read_H 0x85 //读取的时地址
#define Write_H 0x84 //写入的时地址
//////////////////////////////////////////////
#define ds_way10 0x7f //24小时模式 在时寄存器最高位 &运算
#define ds_way24 0x80 //12小时模式 在时寄存器最高位
//当运行在12小时模式时 时寄存器第五位 为0时表示上午 为1表示下午
/*DS1302日期寄存器地址*/
#define Read_th 0x87 //读取的日地址
#define Write_th 0x86 //写入的日地址
/*DS1302月份寄存器地址*/
#define Read_month 0x89 //读取的月地址
#define Write_month 0x88 //写入的月地址
/*DS1302星期寄存器地址*/
#define Read_week 0x8b //读取的周地址
#define Write_week 0x8a //写入的

周地址
/*DS1302年份寄存器地址*/
#define Read_years 0x8d //读取的年地址
#define Write_years 0x8c //写入的年地址
/*DS1302写保护寄存器地址*/
#define Read_wp 0x8f //读取的写保护地址
#define Write_wp 0x8e //写入的写保护地址
//////////////////////////////////////////////
#define ds_wp_off 0x00 //关写保护功能
#define ds_wp_on 0x80 //开写保护功能
/*DS1302涓流充电寄存器地址*/
#define Read_charging 0x90 //读取的涓流充电寄存器地址
#define Write_charging 0x91 //写入的涓流充电寄存器地址
//////////////////////////////////////////////
#define ds_cr0 0xA5 //一个二极管 电阻2K
#define ds_cr1 0xA6 //一个二极管 电阻4K
#define ds_cr2 0xA7 //一个二极管 电阻8K
#define ds_cr3 0xA9 //两个二极管 电阻2K
#define ds_cr4 0xAA //两个二极管 电阻4K
#define ds_cr5 0xAB //两个二极管 电阻8K
#define ds_cr6 0x5C //初始化电源 不充电
/*DS1302时钟突发寄存器地址*/
//#define rd_clock_burst 0xbf //时钟突发模式寄存器读地址
//#define wr_clock_burst 0xbe //时钟突发模式寄存器写地址
/*DS1302RAM突发寄存器地址*/
//#define rd_ram_burst 0xff //RAM突发模式寄存器读地址
//#define wr_ram_burst 0xfe //RAM突发模式寄存器写地址
//DS1302内部有31字节静态RAM(随机存储器)
//读取地址C1H-FDH写入地址C0H-FCH数值范围0-255
/*DS1302操作的引脚定义*/
sbit ds_sclk=P1^6;//串行时钟,输入,控制数据的输入输出
sbit ds_io =P3^5;//三线接口时的双向数据线
sbit ds_ce =P1^7;//输入信号,在读写数据期间,必须为高。该引脚有两个功能:
//第一,CE开始控制字访问移位寄存器的控制逻辑:其次,CE提供结束单字节或多字节数据传输的方法。

/*程序中需要用到的函数*/
void ds1302_init(); //ds1302初始化函数
void ds1302_write(uchar ds_address,write_data);//ds1302芯片写入函数ds_address写入地址,write_data写入数据
uchar ds1302_read(uchar ds_address); //DS1302读取函数 ds_address是读取的地址
void ds1302_rwcom(uchar ds_variables); //DS1302读写操作的公用函数 ds_variables操作的变量(为了减少空间把相同的代码写成的函数)
uchar ds1302_rd(); //DS1302字节读取公函数
uchar bcd_Hex(uchar BCD_numerical); //BCD转16进制数 BCD_numerical需要转码的BCD
uchar Decimal_bcd(uchar Decimal_numerical); //10进制数转BCD Decimal_numerical需要转码的10进制数

/*以下是程序的编写*/
/*
程序名称ds1302_init()
程序作用:初始化DS1302
判断时钟是否运行
没有运行则写入初始时间 以及是否充电
运行则跳过
*/
void ds1302_init() //ds1302初始化函数
{ uchar ds1302_data; //定义临时变量
ds1302_data=ds1302_read(R

ead_ss);//读取秒寄存器并赋值到变量中
ds1302_data=ds1302_data&ds_wp_on;//获得运行标志
if(ds_wp_on==ds1302_data) //判断运行标志为 没有运行
{
ds1302_write(Write_wp ,ds_wp_off ); //写关闭写保护
ds1302_write(Write_ss ,Decimal_bcd(40));//写入时间秒
ds1302_write(Write_mm ,Decimal_bcd(35));//写入时间分
ds1302_write(Write_H ,Decimal_bcd(21));//写入时间时
ds1302_write(Write_th ,Decimal_bcd(19));//写入时间日
ds1302_write(Write_month ,Decimal_bcd( 7));//写入时间月
ds1302_write(Write_week ,Decimal_bcd( 4));//写入时间周
ds1302_write(Write_years ,Decimal_bcd(12));//写入时间年
ds1302_write(Write_charging,ds_cr6 ); //写入是否涓流充电 不充电
ds1302_write(Write_wp ,ds_wp_on ); //写启动写保护
}
}
/*ds1302芯片写入函数ds_address写入地址,write_data写入数据 */
void ds1302_write(uchar ds_address,write_data)//ds1302芯片写入函数address写入地址,write_data写入数据
{
ds_ce =0; //拉低以便形成上升沿
ds_sclk=0; //拉低时钟信号线
ds_ce =1; //打开 允许通信
ds1302_rwcom(ds_address);//调用DS1302读写操作的公用函数 写入地址
ds1302_rwcom(write_data);//调用DS1302读写操作的公用函数 写入数据
ds_ce =0; //拉低 通讯结束
}
/*DS1302读取函数 address是读取的地址*/
uchar ds1302_read(uchar ds_address)//DS1302读取函数 address是读取的地址
{
uchar read_data;
ds_ce =0; //拉低以便形成上升沿
ds_sclk=0; //拉低时钟信号线
ds_ce =1; //打开 允许通信
ds1302_rwcom(ds_address);//调用DS1302读写操作的公用函数 写入地址
read_data=ds1302_rd(); //调用读取函数 读取数据
ds_ce =0; //拉低 通讯结束
return(read_data); //把数据返回去
}

/*DS1302读写操作的公用函数 variables操作的变量 由读写函数调用*/
void ds1302_rwcom(uchar ds_variables)
{
uchar ds_num; //定义一个8位变量 用来做循环8次移位
for(ds_num=0;ds_num<8;ds_num++)
{ //循环8次 写入变量
ds_io=ds_variables&0x01; //IO口赋值
ds_sclk=1; //拉高时钟信号线
ds_sclk=0; //拉低时钟信号线锁存数据
ds_variables=ds_variables>>1; //地址移位
}
}
/*DS1302字节读取函数 由读函数调用*/
uchar ds1302_rd()
{
uchar ds_num,read_data;
for(ds_num=0;ds_num<8;ds_num++)
{ //循环8次 读取数据
read_data=read_data>>1; //数据移位
if(1==ds_io) //判断IO口为高
read_data=read_data|0x80;//为高则数据最高位赋值1
ds_sclk=1; //拉高时钟信号线
ds_sclk=0; //拉低时钟信号线锁存数据
}
return(read_data); //把数据返回去
}
/*BC

D转16进制数 BCD_numerical需要转码的BCD*/
uchar bcd_Hex(uchar BCD_numerical) //BCD转16进制数 BCD_numerical需要转码的BCD
{
return(((BCD_numerical&0x0f)+((BCD_numerical&0x70)>>4)*10));
//进制转换
//返回(((BCD码数值取低四位数)+((BCD码数值取高三位)右移4位)*10));
}
/*10进制数转BCD Decimal_numerical需要转码的10进制数*/
uchar Decimal_bcd(uchar Decimal_numerical) //10进制数转BCD Decimal_numerical需要转码的10进制数
{uchar ds_variables; //临时计算用变量 无符号字符型数值范围0-255
if(Decimal_numerical>=10) //判断10进制数超过或等于数值10
{return((Decimal_numerical-(ds_variables=(Decimal_numerical/10))*10)+(Decimal_numerical/10*16));}
//进制转换
//返回(10进制变量-(临时变量=(10进制变量/10))*10)+(10进制变量/10*16));
else //不超过数值10
{return(Decimal_numerical);} //直接输出
}

相关主题
文本预览
相关文档 最新文档