哈哈,再来一篇。
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]);
}
}
一周热门 更多>