|
发表于 2013-1-31 13:11:08
|
显示全部楼层
/************ DS1302实时时钟芯片操作 **************/
//底层驱动函数
/*******************************************************************************
函数名:DS1302_w_bit()
功 能:向DS1302写入一个字节数据/指令(没有RST操作)
参 数:byte --- 欲写入的数据/指令内容
返回值:无
/******************************************************************************/
void DS1302_w_bit(unchar byte)
{
unchar i;
for(i=0;i<8;i++) //8位数据计数
{
PORTB &= (~BIT(0)); //拉低时钟端,准备写入数据
if(byte&0x01) //当前位是否是1
{
PORTB|=BIT(1); //是1,拉高数据端
}
else
{
PORTB &= (~BIT(1)); //不是1而是0,拉低数据端
}
delayus(5); //延时,调整时钟和脉冲宽度
PORTB|=BIT(0); //时钟上升沿(DS1302采样数据)
byte>>=1; //数据右移1位,为送出新数据位做准备
}
}
/*******************************************
函数名:DS1302_r_bit()
功 能:从DS1302读出一个字节数据(没有RST操作)
参 数:无
返回值:byte --- 读出的数据内容
/********************************************/
unchar DS1302_r_bit(void)
{
unchar i,byte=0;
DDRB &= (~BIT(1)); //将数据端口设置为输入
PORTB &= (~BIT(1)); //无上拉电阻
for(i=0;i<8;i++) //8位数据计数
{
byte>>=1; //保存读入的数据位
PORTB|=BIT(0); //时钟上升沿
delayus(5); //延时,调整时钟脉冲宽度
PORTB &= (~BIT(0)); //时钟下降沿,DS1302输出数据位
delayus(5); //等待数据变化
if(PINB&BIT(1)) //当前位是否是高电平
{
byte|=BIT(7); //是高电平就将返回数据的当前位置1
}
else
{
byte &= (~BIT(7)); //是低电平就将返回数据的当前位置0
}
}
DDRB|=BIT(1); //最后将数据端口设置为输出
return byte; //返回读出的数据
}
/*******************************************************************************
函数名:DS1302_write()
功 能:向DS1302的某个地址写入一个字节数据
参 数:addr -- 欲写入的地址
data -- 欲写入的数据
返回值:无
/********************************************/
void DS1302_write(unchar addr,unchar data)
{
PORTB &= (~BIT(2)); //拉低片选端
PORTB &= (~BIT(0)); //拉低时钟端
delayus(5);
PORTB|=BIT(2); //拉高片选端
delayus(5); //调整片选脉冲
DS1302_w_bit(addr); //写入操作命令(地址)
delayus(5);
PORTB &= (~BIT(0)); //拉低时钟端
delayus(5);
DS1302_w_bit(data); //写入数据
PORTB &= (~BIT(0)); //拉低时钟端
delayus(5); //调整片选脉冲
PORTB &= (~BIT(2)); //拉低片选端
}
/*******************************************
函数名:DS1302_read()
功 能:从DS1302的某个地址读出一个字节数据
参 数:addr -- 地址值(寄存器或RAM)
返回值:data -- 读出的数据
/********************************************/
unchar DS1302_read(unchar addr)
{
unchar data;
PORTB &= (~BIT(2)); //拉低片选端
PORTB &= (~BIT(0)); //拉低时钟端
delayus(5);
PORTB|=BIT(2); //拉高片选端
delayus(5); //调整片选脉冲
DS1302_w_bit(addr); //写入操作命令(地址)
delayus(5);
data=DS1302_r_bit(); //读出数据
delayus(5);
PORTB &= (~BIT(0)); //拉低时钟端
PORTB &= (~BIT(2)); //拉低片选端
return data; //返回读出的数据
}
/*******************************************************************************
函数名:DS1302_Init()
功 能:初始化DS1302芯片
参 数:无
返回值:无
/******************************************************************************/
void DS1302_Init()
{
DS1302_write(0x8E,0x00); //控制命令,WP位为0,允许写操作
delayms(5);
DS1302_write(0x8C,0x09); //写入年份09年
delayms(1);
DS1302_write(0x8A,0x06); //写入星期5
delayms(1);
DS1302_write(0x88,0x10); //写入月份10月
delayms(1);
DS1302_write(0x86,0x31); //写入日期31日
delayms(1);
DS1302_write(0x84,0x15); //写入小时15点
delayms(1);
DS1302_write(0x82,0x06); //写入分钟06分
delayms(1);
DS1302_write(0x90,0xA5); //涓流充电
delayms(1);
DS1302_write(0x80,0x00); //写入秒00,开始走时
DS1302_write(0x8E,0x80); //控制命令,WP位为1,允许写操作
}
/*******************************************************************************
函数名:time_get()
功 能:从DS1302芯片里读取时间数据
参 数:无
返回值:无
/******************************************************************************/
void time_get()
{
int a,b; //定义一下,用于数据处理
year = DS1302_read(0x8D); //读取年份数据
xq = DS1302_read(0x8B); //读取星期数据
month = DS1302_read(0x89); //读取月份数据
day = DS1302_read(0x87); //读取日期数据
hour = DS1302_read(0x85); //读取小时数据
min = DS1302_read(0x83); //读取分钟数据
sec = DS1302_read(0x81); //读取秒钟数据
//BCD码转换成十进制数
//年
a = (year&0xF0)>>4; //转换十位
b = year&0x0F; //转换个位
year = a*10+b;
//月
a = (month&0xF0)>>4; //转换十位
b = month&0x0F; //转换个位
month = a*10+b;
//日
a = (day&0xF0)>>4; //转换十位
b = day&0x0F; //转换个位
day = a*10+b;
//时
a = (hour&0xF0)>>4; //转换十位
b = hour&0x0F; //转换个位
hour = a*10+b; //汇总
//分
a = (min&0xF0)>>4; //转换十位
b = min&0x0F; //转换个位
min = a*10+b; //汇总
//秒
a = (sec&0xF0)>>4; //转换十位
b = sec&0x0F; //转换个位
sec = a*10+b; //汇总
} |
|