用51,c语言,用138译码器,直接用数码管进行秒表计时,不需要用定时器

用51,c语言,用138译码器,直接用数码管进行秒表计时,不需要用定时器,第1张

//你一共就两个管是不要用38译码器的,

//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等。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12543196.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存