//38译码器用物行于3个pin脚控制8个数码管轮流选通;
//如果你本意真的就樱盯是两个管同时亮的话,而且要显示不同数,那么两个罩颂哗数码管七段显示必需是独立控制
/**************************//* ds1302实时时钟C程序*/
/*********** 各引脚功能如下:
引脚号名称 功能
①Vcc2 主电源
②、③X1,X2 接32768Hz晶振
④GND地线
⑤RST复位
⑥I/0 数据输入输出
⑦SCLK 串行时钟
⑧Vccl 后备电源
DS1302有关日历、时间的寄存器共有12个,其中有7个寄存器
(读时81h~8Dh,写时80h~8Ch)是存放秒、分,小时、日、
月、年、周数据的,存放的数据格式为BCD码形式 *********/
/*它的内部时间寄存器如下: */
/*读寄存器 写寄存器 BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0 范围
81H80H| CH | 10秒 | 秒 | 00-59 *****
83H82H| | 10分 | 分 | 00-59 *****
85H84H|12/24| 0 |AM/PM(10)| 时| 时 | 1-12/0-23 *****
87H86H | 0 | 0 | 10日 | 日 | 1-31 *****
89H88H | 0 | 0 | 0 | 10月| 月 | 1-12 *****
8BH8AH | 0 | 0 | 0 |0 | 0 | 周日 | 1-7 *****
8DH8CH | 10年 | 年 | 0-99 *****
8FH8EH | WP 0 0 0 0 0 0 0| —— *****
/**********
上表是DS1302内部的7个与时间、日期有关的寄存器图和一个写保护寄存器,
我们要做的就是将初始设置的时间、日期数据写入这几个寄存器,然后再不断地读
取这几个寄存器来获取实时时间和日期。这几个寄存器的说明如下:
1、秒寄存器(81h、80h)的位7定义为时钟暂停标志(CH)。
当初始上电时该位置为1,时钟振荡器停止,DS1302处于低
功耗状态;只有将秒寄存器的该位置改写为0时,时钟才能
开始运行。
2、小时寄存器(85h、84h)的位7用于定义DS1302是运行于
12小时模式还是24小时模式。当为高时,选择12小时模式。
在12小时模式时,位5是 ,当为1时,表示PM。在24小时模式
时,位5是第二个10小时位
3、控制寄存器(8Fh、8Eh)的位7是写保护位(WP),其它7
位均置为0。在任何的对时钟和RAM的写 *** 作之前,WP位必须
为0。当WP位为1时,写保护位防止对任一寄存器的写 *** 作。
也就是说在电路上电的初始态WP是1,这时是不能改写上面任
何一个时间寄存器的,只有首先将WP改写为0,才能进行其它
寄存器的写 *** 作。
Write Read
CLOCK BURST 范围
BFhBEh
RAM BURST
FFhFEh
RAM
C1hC0h 00-FFh
C3hC2h 00-FFh
C5hC4h 00-FFh
. . .
. . .
. . .
FDhFCh 00-FFh
***********/
#include <intrins.h>
#include "stc_new8051.h"
#include "ds1302.h"
sbit IO =P0^2
sbit SCLK=P0^3
sbit RST=P0^1
sbit ACC7=ACC^7
//写一个字节
void Write_One_Byte(uchar addr)
{
uchar i
for(i=0i<8i++)
{
IO=(bit)(addr&0x01)
SCLK=0
SCLK=1
addr>>=1
}
}
//读一个字节
uchar Read_One_Byte()
{
uchar i
// uchar date
// date=0
for(i=0i<8i++)
{
// date|=_crol_((uchar)IO,i)
ACC7=IO
SCLK=1
SCLK=0
ACC>>=1
}
return ACC
}
//读数据
uchar Read_Data(uchar addr)
{
uchar date
RST = 0SCLK=0RST=1
Write_One_Byte(addr)
date = Read_One_Byte()
RST=0
return date
}
//写数据
void Write_Data(uchar addr,uchar date)
{
RST = 0SCLK=0RST=1
Write_One_Byte(addr)
Write_One_Byte(date)
RST=0
}
void Format_DateTime(uchar d,uchar *a) //BCD转10进制
{
a[0]=d>>4
a[1]=d&0x0f
}
/**************
//读当前时间
void Read_Curtime(uchar *Cur_Time)
{
uchar i,addr
addr=0x81
for(i=0i<7i++)
{
*Cur_Time=Read_Data(addr)
addr+=2
Cur_Time++
}
}
//设置初始时间
void Write_Curtime(uchar *Curtime)
{
uchar i,addr
addr=0x80
for(i=0i<7i++)
{
Write_Data(addr,*Curtime)
addr+=2
Curtime++
}
}
********************/
//突发模式读时钟
void Read_BurstClock(uchar *Clock)
{
uchar i
RST=0
SCLK=0
RST=1
Write_One_Byte(0xbf)//时钟突发模式读
for(i=8i>0i--)
{
*Clock=Read_One_Byte()
Clock++
}
SCLK=1
RST=0
}
//突发模式写时钟
void Write_BurstClock(uchar *Clock)
{
uchar i
Write_Data(0x8e,0x00)//wp=0
RST=0
SCLK=0
RST=1
Write_One_Byte(0xbe)//时钟突发模式写
for(i=8i>0i--)
{
Write_One_Byte(*Clock)
Clock++
}
SCLK=1
RST=0
}
/************** 以下是突发ram模式
暂时未用到
//突发模式读寄存器
void Read_BurstRam(uchar *Register)
{
uchar i
RST=0
SCLK=0
RST=1
Write_One_Byte(0xff)//ram突发模式
for(i=31i>0i--)
{
*Register=Read_One_Byte()
Register++
}
SCLK=1
RST=0
}
//突发模式写寄存器
void Write_BurstRam(uchar *Register)
{
uchar i
Write_Data(0x8e,0x00)//wp=0
RST=0
SCLK=0
RST=1
Write_One_Byte(0xfe)
for(i=31i>0i--)
{
Write_One_Byte(*Register)
Register++
}
SCLK=1
RST=0
}
************/
建议庆和你用单片机I/O脚来控制数码管的段选,用74LS138——3线8线译码器来控制位选,这样比较方便一点。单片机I/O口可以随意的敏瞎输出你想要的段码值,译码器可以来确定选哪一位。如果你驱动的是大电流的数码管,可能要在单片机I/O口和数码管之间加个桥差空驱动芯片,如ULN2003等。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)