单片机电子时钟课程设计报告总结(基于单片机的数字时钟设计实训

http://www.itjxue.com  2023-02-02 22:45  来源:未知  点击次数: 

单片机89c51的电子时钟课程设计

#include reg52.h

#includestddef.h

#define uchar unsigned char

#define uint unsigned int

#define LCD1602_FLAG

#define LCD1602_PORT P0

sbit lcd1602_rs=P2^0;

sbit lcd1602_e=P2^2;

sbit lcd1602_rw=P2^1;

sbit lcd1602_busy=P0^7;

sbit key_ch=P3^5;

sbit key_add=P3^6;

sbit key_minus=P3^7;

uchar i,sec,min,h,date,month,flag;

uint year;

uchar *chgstr[7]={" ?","sec","min","hour","date","min","year"};

uchar j,k,m,n,o,p;

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71};

uchar timestr[10],datestr[10];

void init();

void delay(uint);

void time_display();

void date_display();

void control();

void time();

/*

************************************

* 函数名称:lcd1602_CheckBusy()

* 函数功能:状态查询

************************************

*/

void lcd1602_CheckBusy()

{

do

{

lcd1602_busy=1;

lcd1602_rs=0;

lcd1602_rw=1;

lcd1602_e=0;

lcd1602_e=1;

}

while(lcd1602_busy);

}

/*

***************************************

* 函数名称: lcd1602_WriteCmd()

* 函数功能:写命令

* 入口参数:命令字

* 出口参数:无

***************************************

*/

void lcd1602_WriteCmd(const uchar cmd)

{

lcd1602_CheckBusy();

lcd1602_rs=0;

lcd1602_rw=0;

lcd1602_e=1;

LCD1602_PORT=cmd;

lcd1602_e=0;

}

/*

*******************************************

* 函数名称:lcd1602_WriteData()

* 函数功能:写数据

* 入口参数:c--待写数据

* 出口参数:无

*********************************************

*/

void lcd1602_WriteData(const uchar c)

{

lcd1602_CheckBusy();

lcd1602_rs=1;

lcd1602_rw=0;

lcd1602_e=1;

LCD1602_PORT=c;

lcd1602_e=0;

}

/*

***********************************************

* 函数名称:lcd1602_Init()

* 函数功能:初始化LCD

* 入口参数:无

* 出口参数:无

***********************************************

*/

void lcd1602_Init()

{

lcd1602_WriteCmd(0x38); //显示模式为8位2行5*7点阵

lcd1602_WriteCmd(0x0c); //display enable,flag enable,flash enable,

lcd1602_WriteCmd(0x06); //flag move to right,screen don't move

lcd1602_WriteCmd(0x01); //clear screen

}

/*

************************************************

* 函数名称:lcd1602_Display()

* 函数功能: 字符显示

* 入口参数:ptr--字符或字符串指针

* 出口参数:无

* 说 ? ?明:用户可通过以下方式来调用:

* ? ? ? ? ? 1)lcd1602_Display("Hello,world!");

* ? ? ? ? ? 2) INT8U 存储类型 txt[]="要显示的字符串";

* ? ? ? ? ? ? ?或者 INT8U 存储类型 txt[]={'t','x','t',..,'\0'};

* ? ? ? ? ? ? ?INT8U *ptr;

* ? ? ? ? ? ? ?ptr=txt;

* ? ? ? ? ? ? ?lcd1602_Display(ptr);

* ? ? ? ? ? ? ?或 lcd1602_Display(txt);

* ? ? ? ? ? ? ?或 lcd1602_Display(txt);

************************************************

*/

void lcd1602_Display(const uchar *ptr,uchar line,uchar xaddr)

{

uchar data i=0;

uchar *data q;

q=ptr;

switch(line)

{

case 0:

lcd1602_WriteCmd(0x80+xaddr);

while(q!=NULL (*q!='\0') i16)

{

lcd1602_WriteData(*q);

q++;

i++;

}

break;

case 1:

lcd1602_WriteCmd(0xc0+xaddr);

while(q!=NULL (*q!='\0') i16)

{

lcd1602_WriteData(*q);

q++;

i++;

}

break;

}

}

void main()

{

lcd1602_Init();

init();

while(1)

{

time_display();

date_display();

control();

}

}

void init()

{

i=0;

sec=0;

min=30;

h=7;

date=17;

month=10;

year=2017;

flag=0;

EA=1;

ET0=1;

TMOD=0x01;

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

TR0=1;

}

void delay(uint z)

{

uint x,y;

for(x=z;x0;x--)

for(y=110;y0;y--);

}

void time_display()

{

timestr[7]=0x30+sec%10;

timestr[6]=0x30+sec/10;

timestr[5]=':';

timestr[4]=0x30+min%10;

timestr[3]=0x30+min/10;

timestr[2]=':';

timestr[1]=0x30+h%10;

timestr[0]=0x30+h/10;

timestr[8]=0;

lcd1602_Display(timestr,1,3);

}

void date_display()

{

datestr[9]=0x30+date%10;

datestr[8]=0x30+date/10;

datestr[7]=':';

datestr[6]=0x30+month%10;

datestr[5]=0x30+month/10;

datestr[4]=':';

datestr[3]=0x30+year%10;

datestr[2]=0x30+year/10%10;

datestr[1]=0x30+year/100%10;

datestr[0]=0x30+year/1000;

lcd1602_Display(datestr,0,2);

}

void control()

{

if(!key_ch)

{

delay(5);

if(!key_ch)

{

flag++;

TR0=0;

if(flag==7)

{flag=0;TR0=1;lcd1602_Init();}

lcd1602_Display(chgstr[flag],1,12);

}

}

while(!key_ch);

if(flag==1key_add==0)

{

while(!key_add);

sec++;

if(sec==60)

sec=0;

}

if(flag==1key_minus==0)

{

while(!key_minus);

sec--;

if(sec==-1)

sec=59;

}

if(flag==2key_add==0)

{

while(!key_add);

min++;

if(min==60)

min=0;

}

if(flag==2key_minus==0)

{

while(!key_minus);

min--;

if(min==-1)

min=59;

}

if(flag==3key_add==0)

{

while(!key_add);

h++;

if(h==24)

h=0;

}

if(flag==3key_minus==0)

{

while(!key_minus);

h--;

if(h==-1)

h=23;

}

if(flag==4key_add==0)

{

while(!key_add);

date++;

if(date==29)

if((year%4!=0)(month==2))

date=1;

if(date==30)

if((year%4==0)(month==2))

date=1;

if(date==31)

if((month==4)||(month==6)||(month==9)||(month==11))

date=1;

if(date==32)

if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))

date=1;

}

if(flag==4key_minus==0)

{

while(!key_minus);

if(date1)date--;

}

if(flag==5key_add==0)

{

while(!key_add);

month++;

if(month==13)

month=1;

}

if(flag==5key_minus==0)

{

while(!key_minus);

month--;

if(month==0)

month=12;

}

if(flag==6key_add==0)

{

while(!key_add);

year++;

if(year==99)

year=1;

}

if(flag==6key_minus==0)

{

while(!key_minus);

year--;

if(year==0)

year=99;

}

}

void T0_rpt() interrupt 1

{

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

i++;

time();

}

void time()

{

if(i==20)

{

i=0;

sec++;

if(sec==60)

{

sec=0;

min++;

if(min==60)

{

min=0;

h++;

if(h==24)

{

h=0;

min=0;

sec=0;

date++;

if(date==29)

if((year%4!=0)(month==2))

{

date=1;

month++;

if(month==13)

{

month=1;

year++;

}

}

if(date==30)

if((year%4==0)(month==2))

{

date=1;

month++;

if(month==13)

{

month=1;

year++;

}

}

if(date==31)

if((month==4)||(month==6)||(month==9)||(month==11))

{

date=1;

month++;

if(month==13)

{

month=1;

year++;

}

}

if(date==32)

if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))

{

date=1;

month++;

if(month==13)

{

month=1;

year++;

}

}

}

}

}

}

}

求基于单片机的数字电子钟课程设计报告!!!

P0接数码管的8段,P2.6-P2.1分别选通6个数码管,顺序依次是:P2.6?是秒的低位,P2.1选通时的高位。再有就是P3.2-P3.5接四个按键。DCF51-1型开发系统已经通过!!

;;主程序(MAIN),如下:

ORG?0000H

AJMP?MAIN

ORG?000BH

AJMP?TIME

ORG?0300H

MAIN:

mov?20h,#00h

MOV?21H,#00H

MOV?22H,#00H

MOV?23H,#00H

MOV?IP,#02H?;IP,IE初始化

MOV?IE,#82H

MOV?TMOD,#01H?;设定定时器工作方式?

MOV?TL0,#0B0H

MOV?TH0,#3CH

SETB?TR0?;启动定时?

MOV?SP,#40H?;重设堆栈指针

NEXT:?LCALL?DISP?;调用显示子程序?

LCALL?KEY?;调用按键检测子程序

JZ?NEXT?;

LCALL?ANKEY?;调用按键处理子程序

SJMP?NEXT?;重新循环

NOP

NOP

NOP

;定时中断处理程序:

TIME:?PUSH?ACC?;保护现场

PUSH?PSW

MOV?TL0,#0B4H?;赋定时初值

MOV?TH0,#3CH

INC?20H?;

MOV?A,20H

CJNE?A,#20,RETI1

MOV?20H,#00H?;一秒钟时间到

MOV?A,21H

ADD?A,#01H

DA?A

MOV?21H,A

CJNE?A,#60H,RETI1

MOV?21H,#00H?;一分钟时间到

MOV?A,22H

ADD?A,#01H

DA?A

MOV?22H,A

CJNE?A,#60H,RETI1

MOV?22H,#00H?;一小时时间到

MOV?A,23H

ADD?A,#01H

DA?A

MOV?23H,A

CJNE?A,#24H,RETI1

MOV?23H,#00H?;到时间达到24小时,清零.

RETI1:?POP?PSW?;恢复现场

POP?ACC

RETI?;中断返回?

NOP

NOP

;显示子程序

DISP:?ANL?2FH,#10H?;处理小数点

MOV?A,21H?;处理秒21H--2DH,2EH

ANL?A,#0FH

ORL?A,2FH

MOV?2FH,A

MOV?A,21H

ANL?A,#0F0H

SWAP?A

MOV?2EH,A

ANL?2DH,#10H

MOV?A,22H?;处理分钟22H--2CH,2DH

ANL?A,#0FH

ORL?A,2DH

MOV?2DH,A

MOV?A,22H

ANL?A,#0F0H

SWAP?A

MOV?2CH,A

ANL?2BH,#10H

MOV?A,23H?;处理小时23H--2AH,2BH

ANL?A,#0FH

ORL?A,2BH

MOV?2BH,A

MOV?A,23H

ANL?A,#0F0H

SWAP?A

MOV?2AH,A

MOV?R0,#2FH?;显示偏移量

MOV?R3,#06H

MOV?DPTR,#TABLE

MOV?A,#0BFH

LOOP1:?MOV?B,A?;

MOV?P2,a

MOV?A,@R0

MOVC?A,@A+DPTR

MOV?P0,a?;送显示

MOV?R2,#80H?;延时

DJNZ?R2,$

DEC?R0

MOV?A,B

RR?A

DJNZ?R3,LOOP1?;循环显示

RET

TABLE:?db?28h,7eh,0a2h,62h,74h,61h,21h?;不带小数点

DB?7ah,20h,60h,00,00,00,00,00,00

DB?8H,5eH,82H,42H,54H,41H,1H,5aH?;带小数点

DB?00H,40H,00,00,00,00,00,00

NOP

NOP

;按键判断程序

KEY:?MOV?P3,#0FFH?;

MOV?A,P3

CPL?A

ANL?A,#3CH

JZ?RETX?;无键按下则返回

LCALL?DISP?;

LCALL?DISP

MOV?A,P3

CPL?A

ANL?A,#3CH

JZ?RETX?;键盘去抖动。

MOV?R6,A?;将键值存入R6。

LOOP2:?LCALL?DISP?;

MOV?A,P3

CPL?A

ANL?A,#3CH

JNZ?LOOP2?;等待键释放

MOV?A,R6

RETX:?RET

NOP

NOP

;按键处理子程序

ANKEY:?CLR?EA?;关中断

LX:?MOV?A,R6

JB?ACC.2,L1?;是功能键转L1

JB?ACC.3,L2?;是确认键转L2

JB?ACC.4,L3?;是减1键转L3

JNB?ACC.5,L12?;不是增1键,转L12

JB?2BH.4,L6?;判断使哪一位(时、分、秒)的值加1

JB?2DH.4,L8

JB?2FH.4,L9

L12:?LCALL?DISP

LCALL?DISP

LCALL?KEY?;判断有无键按下。

JZ?L12

LJMP?LX

L2:?MOV?25H,#00H?;确认键处理程序

CLR?2BH.4

CLR?2DH.4

CLR?2FH.4

SETB?EA

RET

L3:?JB?2BH.4,L61?;增一键处理程序

JB?2DH.4,L81

JB?2FH.4,L91

AJMP?L12

L1:?MOV?A,25H?;功能键处理程序

JZ?LB1

JB?ACC.0,LB2

JB?ACC.1,LB3

JNB?ACC.2,L12

LB1:?MOV?25H,#01H?;25H单元是标志位,(25H)=01H调节时单元的值

SETB?2BH.4

CLR?2DH.4

CLR?2FH.4

AJMP?L12

LB3:?MOV?25H,#04H?;25H单元是标志位,(25H)=01H调节秒单元的值

SETB?2FH.4

CLR?2DH.4

CLR?2BH.4

AJMP?L12

LB2:?MOV?25H,#02H?;25H单元是标志位,(25H)=01H调节分单元的值

SETB?2DH.4

CLR?2BH.4

CLR?2FH.4

AJMP?L12

L61:?AJMP?L611?;

L81:?AJMP?L811?;

L91:?AJMP?L911

L6:?MOV?A,23H?;时加一

ADD?A,#01H

DA?A

MOV?23H,A

CJNE?A,#24H,L15

L15:?JC?L112

MOV?23H,#00H

L112:?AJMP?L12

L8:?MOV?A,22H?;分加一

ADD?A,#01H

DA?A

MOV?22H,A

CJNE?A,#60H,L16

L16:?JC?L112

MOV?22H,#00H

AJMP?L12

L9:?MOV?A,21H?;秒加一

ADD?A,#01H

DA?A

MOV?21H,A

CJNE?A,#60H,L17

L17:?JC?L112

MOV?21H,#00H

AJMP?L12

L611:?MOV?A,23H?;时减一

ADD?A,#99H

DA?A

MOV?23H,A

CJNE?A,#99H,L112

MOV?23H,#23H

AJMP?L12

L811:?MOV?A,22H?;分减一

ADD?A,#99H

DA?A

MOV?22H,A

CJNE?A,#99H,L112

MOV?22H,#59H

AJMP?L12

L911:?MOV?A,21H?;秒减一

ADD?A,#99H

DA?A

MOV?21H,A

CJNE?A,#99H,L112

MOV?21H,#59H

AJMP?L12

NOP

NOP

END

数字电子钟可设报告

基于AT89c51的简易时钟设计

摘要:本电子钟是采用电子电路实现对时、分进行数字显示的计时装置,广泛的应用于生活中。电子时钟主要是利用电子技术奖时钟电子化、数字化,拥有时间精确、体积小、界面友好、课扩展性能强等特点,被广泛应用于生活和工作当中。当今市场上的电子时钟品类繁多,外形小巧别致。电子时钟数字化了时间显示。在此基础上,人们可以根据不同场合的要求,在时钟上加置其他功能,

本设计由以下几个部件组成:单片机AT89C51、四个八段码共阴极数码管显示、四个微动按钮等其它组件。在启动后开始从00时00分显示。可以手动校准时间,秒使用两个发光二极管的闪烁来提现,本设计设计简单易于实现。

关键词:AT89C51、倒计时。LED

Simple clock design based on AT89c51

Abstract: This clock is the use of electronic circuits to achieve the hours, minutes, digital display of timing devices, widely used in life. Electronic clock main prize is the use of electronic technology electronic clock, digital, with a time accurate, small, friendly interface, expanded its performance and other characteristics, are widely used in life and on the job. The market today, many kinds of electronic clock, compact and chic. Digital electronic time clock display. On this basis, one can according to the requirements of different occasions, plus set the clock on the other features

This design consists of the following components: microcontroller AT89C51, four eight out code common cathode LED display, four buttons, and other micro-components. After starting 00 points from 00 shows. You can manually calibrate the time, in seconds using two LEDs blink to mention is, the design is simple design easy to implement.

Keywords: AT89C51, countdown. LED

目 录

摘要 1

关键词 1

Simple clock design based on AT89c51 2

目录 3

第一章引言 4

1.1 时钟的概述 5

第二章电路工作原理分析 5

2.1 系统的硬件构成及功能 5

2.2硬件连接方式 6

第三章: 芯片介绍 6

3.1 MCS- 51介绍 6

3.4 LED数码管显示 10

3.4.1 LED数码管介绍 10

3.4.2 LED数码管编码方式 11

3.4.3 LED数码管显示方式和典型应用电路 12

第四章 部分电路介绍 13

4.1单片机的最小应用系统 13

4.1.1 单片机的时钟电路 13

4.1.2 复位电路和复位状态 14

4.1.3总线结构 17

4.2此设计显示电路 18

4.4看门狗电路 19

4.5 按键模块 19

第五章程序设计 19

第六章 原理图和印制板图的设计 20

( 一 ) 原 理 图 的 设 计 和 网 络 表 的 生 成 20

(二)PCB的制作和设计 21

第七章 原理图的protues仿真 23

7.1PROTUES介绍 23

7.2原理图仿真步骤 26

总 结 27

谢 辞 28

参考资料及文献 29

附录一:原理图 30

附录二:PCB 31

附录三 仿真 32

附录四:程序清单 33

第一章引言

数字钟已成为人们日常生活中必不可少的必需品,广泛用于个人家庭以及办公室等公共场所,给人们的生活、学习、工作、娱乐带来极大的方便。由于数字集成电路技术的发展和采用了先进的石英技术,使数字钟具有走时准确、性能稳定、携带方便等优点,它还用于计时、自动报时及自动控制等各个领域。尽管目前市场上已有现成的数字钟集成电路芯片出售,价格便宜、使用也方便,但鉴于单片机的定时器功能也可以完成数字钟电路的设计,因此进行数字钟的设计是必要的。在这里我们将已学过的比较零散的数字电路的知识有机的、系统的联系起来用于实际,来培养我们的综合分析和设计电路,写程序、调试电路的能力。

单片机具有体积小、功能强可靠性高、价格低廉等一系列优点,不仅已成为工业测控领域普遍采用的智能化控制工具,而且已渗入到人们工作和和生活的各个角落,有力地推动了各行业的技术改造和产品的更新换代,应用前景广阔。

1.1 时钟的概述

20世纪末,电子技术获得了飞速的发展。在其推动下,电子产品几乎渗透到了社会的各个领域,有力的推动和提高了社会生产力的发展和信息化程度,同时也使现代电子产品性能进一步提升,产品更新换代的节奏也越来越快。

电子钟是采用电子电路实现对时、分、秒进行数字显示的计时装置,广泛的应用于生活中。电子时钟主要是利用电子技术奖时钟电子化、数字化,拥有时间精确、体积小、界面友好、课扩展性能强等特点,被广泛应用于生活和工作当中。当今市场上的电子时钟品类繁多,外形小巧别致。电子时钟数字化了时间显示。在此基础上,人们可以根据不同场合的要求,在时钟上加置其他功能,比如定时闹钟,万年历,环境温度,温度检测,环境空气质量检测,USB扩展功能等。

本设计电子时钟主要功能为:具有时间显示和手动校对功能,24小时制。

本设计任务“

1:用4位LED数码管实时显示时钟计时功能;最小显示时间为00时00分,最大显示时间为23时59分;

2:能方便的校准小时和分钟。

3:了解单片机的基础知识;

4;掌握proteus的基本原理和使用方法;

5:掌握数码管和LED的显示的方法;

6:掌握单片机定时器的基本原理;

7:掌握单片机定时器的基本原理;

8:掌握绘图软件Proell99se的使用方法;

9:绘制程序流程图和编写出程序;

10:画出电路原理图并仿真运行

第二章电路工作原理分析

2.1 系统的硬件构成及功能

本设计由以下几个部件组成:单片机AT89C51、四个八段码共阴极数码管显示、四个微动按钮等其它组件。在启动后开始从00时00分显示。可以手动校准时间,秒使用两个发光二极管的闪烁来提现,本设计设计简单易于实现。

图1 99秒计时器系统原理框图

2.2硬件连接方式

数码管使用动态显示,P0口作为四个八位共阴数码管的段选输出端,为提高单片机输出能力 P0口作为输出口接了8个4.7K的电阻作为上拉电阻;P2.口是四个八位共阴数码管和两个发光二极管的位选端,显示是事位和分位,四个微动开关做的按键分别连P1.0,P1.1,P1.2,P1.3完成时和分的加减调整。硬件连接如下:

4.1单片机的最小应用系统

单片计算机是一个最小的应用系统,但由于应用系统中有一些功能器件无法集成到芯片内部,如晶振、复位电路等,需要在片外加接相应的电路。对于片内无程序存储器的单片机,还应该配置片外程序存储器。

4.1.1 单片机的时钟电路

MCS-51单片机内部的振荡电路是一个高增益反相放大器,引线XTAL1和XTAL2分别是放大器的输入端和输出端。单片机内部虽然有振荡电路,但要形成时钟,外部还需附加电路。MCS-51单片机的时钟产生方式有两种。

(1) 内部时钟方式

利用其内部的振荡电路在XTAL1和XTAL2引线上外接定时元件,内部振荡电路便产生自激振荡,用示波器可以观察到XTAL2输出的时钟信号。最常用的是在XTAL1和XTAL2之间连接晶体振荡器与电容构成稳定的自激震荡器,如图3-1所示。

晶体可在1.2~12MHz之间选择。MCS-51单片机在通常应用情况下,使用振荡频率为6MHz的石英晶体,而12Hz频率的晶体主要是在高速串行通信情况下才使用。C1和C2可在20~100pF之间取值,一般取30pF左右。

(2) 外部时钟方式

在由单片机组成的系统中,为了各单片机之间时钟信号的同步,应当引入惟一的合用外部振荡脉冲作为各单自片机的时钟。外部时钟方式中是把外部振荡信号源直接接入XTAL1或XTAL2。由于HMOS和CHMOS单片机外部时钟进入的引线不同,其外部振荡信号源接入的方式也不同。HMOS型单片机由XTAL2进入,外部振荡信号接至XTAL2,而内部反相放大器的输入端XTAL1应接地,如图3-2所示。由于XTAL2端的逻辑电平不是TTL的,故还要接一上接电阻。CHMOS型单片机由XTAL1进入,外部振荡信号接至XTAL1,而XTAL2可不接地,如图3-3所示。

图3-1内部时钟电路 图3-2HMOS型外部时钟电路 图3-3外部时钟电路

4.1.2 复位电路和复位状态

MCS-51单片机的复位是靠外部电路实现的。MCS-51单片机工作后,只要在它的RST引线上加载10ms以上的高电平,单片机就能够有效地复位。

(1) 复位电路

MCS-51单片机通常采用上电自动复位和按键复位两种方式。最简单的复位电路如图3-4所示。上电瞬间,RC电路充电,RST引线端出现正脉冲,只要RST端保持10ms以上的高电平,就能使单片机有效地复位。

图 3-4 简单的复位电路

在实际的应用系统中,为了保证单片机可靠地工作,常采用“看门狗”监视单片机的运行。采用MAX690的复位电路如图3-5所示,该电路具有上电复位和监视MCS-51单片机的P3.3的输出功能。一旦P3.3不输出高低电平交替变化的脉冲,MAX690就会自动产生一复位信号使单片机复位。

图3-5 MAX690组成的复位电路

(2) 复位状态

复位电路的作用是使单片机执行复位操作。复位操作主要是把PC初始化为0000H,使单片机从程序存储器的0000H单元开始执行程序。程序存储器的0003H单元即MCS-51单片机的外部中断0的中断处理程序的入口地址。留出的0000H~0002H 3个单元地址,仅能够放置一条转移指令,因此,MCS-51单片机的主程序的第一条指令通常情况下是一条转移指令。

除PC之外,复位还对其他一些特殊功能的寄存器有影响,它们的复位状态如表3-6所示。

由表3-6可知,除SP=07H,P0~P3 4个锁存器均为FFH外,其他所有的寄存器均为0。此外,单片机的复位不影响片内RAM的状态(包括通用寄存器Rn)。

表3-6 寄存器的复位状态

寄存器 复位状态 寄存器 复位状态

PC 0000H TMOD 00H

ACC 00H TCON OOH

PSW 00H TL0 00H

SP 07H TH0 00H

DPTR 0000H TL1 00H

P0~P3 FFH TH1 00H

IP Xxx00000B SCON 00H

IE 0xx00000B PCON 0xx00000B

P0、P1、P2、P3共有4个8位并行I/O口,它们引线为:P0.0~P0.7、P1.0~P1.7、

P2.0~P2.7、P3.0~P3.7,共32条引线。这32条引线可以全部用做I/O线,也可将其中部分用做单片机的片外总线。

① 控制线

A、ALE地址锁存允许

当单片机访问外部存储器时,输出信号ALE用于锁存P0口输出的低8位地址A7~A0。ALE的输出频率为时钟振荡频率的1/6。

B、 程序存储器选择

=0,单片机只访问外部程序存储器。对内部无程序存储器的单片机8031, 必须接地。 =1,单片机访问内部程序存储器,若地址超过内部程序存储器的范围,单片机将自动访问外部程序存储器。对内部有程序存储器的单片机, 应接高电平。

C、 片外程序存储器的选通信号。此信号为读外部程序存储器的选通信号。

D、RST复位信号输入

② 电源及时钟

VSS地端接地线,VCC电源端接+5V,XTAL1和XTAL2接晶振或外部振荡信号源。

图3-7 片外3总线结构

4.1.3总线结构

单片机的引线除了电源、复位、时钟输入、用户I/O口外,其余引线都是为实现系统扩展则设置的,这些引线构成了单片机外部的3总线形式,如图3-7所示。

① 地址总线

地址总线宽度为16位,由P0口经地址锁存器提供低8位地址(A7~A0),P2口直接提供高8位地址(A15~A8)。

由口的位结构可知,MCS-51单片机在进行外部寻址时,P0口的8根引绠低8位地址和8位数据的复用线。P0口首先将低8位的地址发送出去,然后再传送数据,因此要用锁存器将先送出的低8位地址锁存。MCS-51常用74LS373或8282做地址锁存器。

② 数据总线

数据总线宽度为8位,由P0口提供。

③ 控制总线

MCS-51用于外部扩展的控制总线除了它自身引出的控制线RES、 、ALE、 外,还有由P3口的第二功能引线:外部中断0和外部中断1输入线 和 ,以及外部RAM或I/O端口的读选通和写选通信号 和 。

3.4 MCS—51单片机的最小应用系统

构成最小应 MCS—51单片机的最小应用系统

用系统时只要将单片机接上外部的晶体或时钟电路和复位电路即可,如图3-8所示,这样构成的最小系统简单可靠,其特点是没有外部扩展,有可供用户选用的大量I/O线。

4.2此设计显示电路

数码管使用动态显示,P0口作为四个八位共阴数码管的段选输出端,因为P0口作为输出口接了8个4.7K的电阻作为上拉电阻;P2口四个八位共阴数码管的位选端,显示是两位时间的事时位和两位的分位。

4.3电源电路

由于该系统需要稳定的5 V电源,因此设计时必须采用能满足电压、电流和稳定性要求的电源。该电源采用三端集成稳压器LM7805。它仅有输人端、输出端及公共端3个引脚,其内部设有过流保护、过热保护及调整管安全保护电路,由于所需外接元件少,使用方便、可靠,因此可作为稳压电源。图4为电源电路连接图。

 

4.4看门狗电路

系统中把P1.6作为看门狗的“喂狗”信号;将MAX813的 RESET与单片机的复位信号RST连接。由于单片机每执行一次程序,就会给看门狗器件一个复位信号,这样也可以用手工方式实现复位。当按键按下时,SW-SPST就会在MAX813 引脚产生一个超过200ms的低电平,其实看门狗器件在1.6s 时间内没有复位,使7引脚输出一个复位信号的作用是相同的,其连接图如图6所示。

4.5 按键模块

下图为按键模块电路原理图,S1为时加,s2为时减,S3为分钟加调控键,S4是分钟减调控键。

LED_BIT_1 EQU 30H ; 存放8位数码管的段码

LED_BIT_2 EQU 31H

LED_BIT_3 EQU 32H

LED_BIT_4 EQU 33H

LED_BIT_5 EQU 34H

LED_BIT_6 EQU 35H

LED_BIT_7 EQU 36H

LED_BIT_8 EQU 37H ; 存放初始密码

SECOND EQU 60H

MINUTE EQU 61H

HOUR EQU 62H

TCNT EQU 63H

ORG 00H ;初始化程序 ,设置初始密码

SJMP START

ORG 0BH

LJMP INT_T0

START:

MOV DPTR,#TABLE

MOV HOUR,#0

MOV MINUTE,#0

MOV TCNT,#0

MOV TMOD,#01H

MOV TH0,#03ch ;定时50毫秒

MOV TL0,#03ch

MOV IE,#082H

SETB TR0

MOV LED_BIT_1,#00H ;段码存储区清0

MOV LED_BIT_2,#00H

MOV LED_BIT_3,#00H

MOV LED_BIT_4,#00H

MOV LED_BIT_5,#00H

MOV LED_BIT_6,#00H

MOV LED_BIT_7,#79H

MOV LED_BIT_8,#73H

MOV TMOD,#01H

MOV TH0,#0fdh

MOV TL0,#0fdh

MOV IE,#82H

A1:

LCALL DISPLAY ;调用时间显示

JNB P1.0,S1

JNB P1.1,S2

JNB P1.2,S3

JNB P1.3,S4

LJMP A1

S1: LCALL DLY_S ;去抖动

JB P1.0,A1

INC HOUR ;秒值加1

MOV A, HOUR

CJNE A,#24,J00 ;判断是否加到60秒

MOV HOUR,#0

LJMP A1

S2: LCALL DLY_S

JB P1.1,A1

K01: DEC HOUR ;SHI-

MOV A,HOUR

CJNE A,#0,J01 ;判断是否-0分

MOV HOUR,#24

LJMP A1

S3: LCALL DLY_S

JB P1.2,A1

K02: INC MINUTE ;小时值加1

MOV A,MINUTE

CJNE A,#60,J02 ;判断是否加到24小时

MOV MINUTE,#0

LJMP A1

S4: LCALL DLY_S

JB P1.3,A1

K03: DEC MINUTE ;小时值加1

MOV A,MINUTE

CJNE A,#0,J03 ;判断是否加到24小时

MOV MINUTE,#59

LJMP A1

J00: JB P1.0,A1 ;等待按键抬起

LCALL DISPLAY

SJMP J00

J01: JB P1.1,A1

LCALL DISPLAY

SJMP J01

J02: JB P1.2,A1

LCALL DISPLAY

SJMP J02

J03: JB P1.3,A1

LCALL DISPLAY

SJMP J03

INT_T0: MOV TH0,#3ch ;定时器中断服务程序

MOV TL0,#3ch ;对秒,分钟和小时的计数

INC TCNT

MOV A,TCNT

CJNE A,#20,RETUNE ;计时1秒

INC SECOND

MOV TCNT,#0

MOV A,SECOND

CJNE A,#60,RETUNE

INC MINUTE

MOV SECOND,#0

MOV A,MINUTE

CJNE A,#60,RETUNE

INC HOUR

MOV MINUTE,#0

MOV A,HOUR

CJNE A,#24,RETUNE

MOV HOUR,#0

MOV MINUTE,#0

MOV SECOND,#0

MOV TCNT,#0

RETUNE: RETI

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;DIS3闹铃设置子程序

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;DIS3

DISPLAY: ;显示时间控制子程序

MOV A,SECOND ;显示秒

MOV B,#10

DIV AB

CLR P2.6

MOVC A,@A+DPTR

MOV P0,A

LCALL DLY_S

SETB P2.6

MOV A,B

CLR P2.7

MOVC A,@A+DPTR

MOV P0,A

LCALL DLY_S

SETB P2.7

CLR P2.5

MOV P0,#40H ;显示分隔符

LCALL DLY_S

SETB P2.5

MOV A,MINUTE ;显示分钟

MOV B,#10

DIV AB

CLR P2.3

MOVC A,@A+DPTR

MOV P0,A

LCALL DLY_S

SETB P2.3

MOV A,B

CLR P2.4

MOVC A,@A+DPTR

MOV P0,A

LCALL DLY_S

SETB P2.4

CLR P2.2

MOV P0,#40H ;显示分隔符

LCALL DLY_S

SETB P2.2

MOV A,HOUR ;显示小时

MOV B,#10

DIV AB

CLR P2.0

MOVC A,@A+DPTR

MOV P0,A

LCALL DLY_S

SETB P2.0

MOV A,B

CLR P2.1

MOVC A,@A+DPTR

MOV P0,A

LCALL DLY_S

SETB P2.1

RET

TABLE: DB 3FH,06H,5BH,4FH,66H

DB 6DH,7DH,07H,7FH,6FH

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;延时

DLY_S: MOV R6,#5 ;延时程序

D1: MOV R7,#100

DJNZ R7,$

DJNZ R6,D1

RET

DLY_L: MOV R5,#50

D2: MOV R6,#100

D3: MOV R7,#100

DJNZ R7,$

DJNZ R6,D3

DJNZ R5,D2

RET

END

第五章程序设计

程序只要完成了初始化,计时,在计时过程中判断按键情况,做相应处理。流程如下。

利用单片机定时器制作数字时钟

下面是时间程序,直接下来用就行了.

/*******************************************************************************

********************************************************************************

* 描述: *

* 简易电子时钟,LED数码管显示 *

* K1---时调整 *

* K2---分调整 *

* *

* 上电时初始化显示: 12-00-00 *

* *

* * **** **** **** **** **** *

* * * * * * * * * * * *

* * * * * * * * * * * *

* * **** ****** * * * * ****** * * * * *

* * * * * * * * * * * *

* * * * * * * * * * * *

* * **** **** **** **** **** *

* *

* *

*******************************************************************************/

#include reg51.h

#include intrins.h

unsigned char data dis_digit;

unsigned char key_s, key_v;

unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3

0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, off

unsigned char data dis_buf[8];

unsigned char data dis_index;

unsigned char hour,min,sec;

unsigned char sec100;

sbit K1 = P3^2;

sbit K2 = P3^3;

bit scan_key();

void proc_key();

void inc_sec();

void inc_min();

void inc_hour();

void display();

void delayms(unsigned char ms);

void main(void)

{

P0 = 0xff;

P2 = 0xff;

TMOD = 0x11; // 定时器0, 1工作模式1, 16位定时方式

TH1 = 0xdc;

TL1 = 0;

TH0 = 0xFC;

TL0 = 0x17;

hour = 12;

min = 00;

sec = 00;

sec100 = 0;

dis_buf[0] = dis_code[hour / 10]; // 时十位

dis_buf[1] = dis_code[hour % 10]; // 时个位

dis_buf[3] = dis_code[min / 10]; // 分十位

dis_buf[4] = dis_code[min % 10]; // 分个位

dis_buf[6] = dis_code[sec / 10]; // 秒十位

dis_buf[7] = dis_code[sec % 10]; // 秒个位

dis_buf[2] = 0xbf; // 显示"-"

dis_buf[5] = 0xbf; // 显示"-"

dis_digit = 0xfe;

dis_index = 0;

TCON = 0x01;

IE = 0x8a; // 使能timer0,1 中断

TR0 = 1;

TR1 = 1;

key_v = 0x03;

while(1)

{

if(scan_key())

{

delayms(10);

if(scan_key())

{

key_v = key_s;

proc_key();

}

}

}

}

bit scan_key()

{

key_s = 0x00;

key_s |= K2;

key_s = 1;

key_s |= K1;

return(key_s ^ key_v);

}

void proc_key()

{

EA = 0;

if((key_v 0x01) == 0) // K1

{

inc_hour();

}

else if((key_v 0x02) == 0) // K2

{

min++;

if(min 59)

{

min = 0;

}

dis_buf[3] = dis_code[min / 10]; // 分十位

dis_buf[4] = dis_code[min % 10]; // 分个位

}

EA = 1;

}

void timer0() interrupt 1

// 定时器0中断服务程序, 用于数码管的动态扫描

// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量

// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,

// 选通P2.0口数码

// dis_buf --- 显于缓冲区基地址

{

TH0 = 0xFC;

TL0 = 0x17;

P2 = 0xff; // 先关闭所有数码管

P0 = dis_buf[dis_index]; // 显示代码传送到P0口

P2 = dis_digit; //

dis_digit = _crol_(dis_digit,1); // 位选通值左移, 下次中断时选通下一位数码管

dis_index++; //

dis_index = 0x07; // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描

}

void timer1() interrupt 3

{

TH1 = 0xdc;

sec100++;

if(sec100 = 100)

{

sec100 = 0;

inc_sec();

}

}

void inc_sec()

{

sec++;

if(sec 59)

{

sec = 0;

inc_min();

}

dis_buf[6] = dis_code[sec / 10]; // 秒十位

dis_buf[7] = dis_code[sec % 10]; // 秒个位

}

void inc_min()

{

min++;

if(min 59)

{

min = 0;

inc_hour();

}

dis_buf[3] = dis_code[min / 10]; // 分十位

dis_buf[4] = dis_code[min % 10]; // 分个位

}

void inc_hour()

{

hour++;

if(hour 23)

{

hour = 0;

}

if(hour 9)

dis_buf[0] = dis_code[hour / 10]; // 时十位

else

dis_buf[0] = 0xff; // 当小时的十位为0时不显示

dis_buf[1] = dis_code[hour % 10]; // 时个位

}

void delayms(unsigned char ms)

// 延时子程序

{

unsigned char i;

while(ms--)

{

for(i = 0; i 120; i++);

}

}

单片机课程设计(数字时钟) 麻烦大家不要发链接 直接帮我把程序写过来。

哈哈?有个1602显示的?不过程序太长?贴不上?给你个数码管的吧?不行再联系

1302.c

#includeDS1302.h

#includekey.h

uchar?bit_ser[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};

uchar?seven_seg[]?=?{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

/***********************时间显示*****************/

void?timer0_init(void) ?//T0初始化函数,用于时间的动态显示

{

TMOD?=?0x21;

TL0?=?(65536-5000)?%?256;

TH0?=?(65536-5000)?/?256;

EA?=?1;

ET0?=?1;

TR0?=?1;

}

void?timer0_isr(void)?interrupt?1 ?//T0中断处理函数

{

char?flag;? ?//flag用于表示调整时闪烁的亮或灭

TR0?=?0;

TL0?=?(65536-5000)?%?256;

TH0?=?(65536-5000)?/?256;

TR0?=?1;

flag?=?x?/?100?*?0xff; //设置闪烁标志,如果x大于100则flag为0xff,小于100则为0x00

x++;

if(x??200)

x?=?0;

switch(i)

{

case?0:

P2?=?bit_ser[0];

if(setflag?==?3) ?//根据setflag的值判断当前位是否需要闪烁

P0?=?flag?|?seven_seg[dis_buffer[0]];

else

P0?=?seven_seg[dis_buffer[0]];

break;

case?1:

P2?=?bit_ser[1];

if(setflag?==?3)

P0?=flag?|?seven_seg[dis_buffer[1]];

else

P0?=seven_seg[dis_buffer[1]];

break;

case?2:

P2?=?bit_ser[2];

if(setflag?==?2)

P0?=flag?|?seven_seg[dis_buffer[2]];

else

P0?=seven_seg[dis_buffer[2]];

break;

case?3:

P2?=?bit_ser[3];

if(setflag?==?2)

P0?=flag?|?seven_seg[dis_buffer[3]];

else

P0?=seven_seg[dis_buffer[3]];

break;

case?4:

P2?=?bit_ser[4];

if(setflag?==?1)

P0?=flag?|?seven_seg[dis_buffer[4]];

else

P0?=seven_seg[dis_buffer[4]];

break;

case?5:

P2?=?bit_ser[5];

if(setflag?==?1)

P0?=flag?|?seven_seg[dis_buffer[5]];

else

P0?=seven_seg[dis_buffer[5]];

break;

}

i++;

if(i?=?6)

{

i?=?0;

if(j?==?10)

{

j?=?0;

if(setflag?==?0)

DS1302_GetTime(Time); //如果setflag是0,就从1302中读出时间,因为setflag不是0时,说明处于调整状态,不需要读时间

dis_buffer[5]?=?Time.Second?%?10; //把当前时间放入显示缓冲区

dis_buffer[4]?=?Time.Second?/?10;

dis_buffer[3]?=?Time.Minute?%?10;

dis_buffer[2]?=?Time.Minute?/?10;

dis_buffer[1]?=?Time.Hour?%?10;

dis_buffer[0]?=?Time.Hour?/?10;

}

j++;

}

}

void?main()

{

Initial_DS1302(Time);

timer0_init();

while(1)

{

set_down();

timer_down();

up_down();

down_down();

beepflag_down();

if(setflag?==?0??Time.Hour?==?romhour??Time.Minute?==?romminute??Beepflag?==?1) //判断蜂鸣器是否要响

Beep?=?!Beep;

}

}

//key.c

#includereg51.h

#define?uchar?unsigned?char

#define?uint?unsigned?int

uchar?i?=?0,j?=?0,x?=?0,setflag,flag_set,flag_timer;???//setflag用来表示调整的位置,flag_set和flag_timer分别表示当前处于调整状态还是定时状态

SYSTEMTIME?Time={0,20,15,3,30,6,10}; ???//系统时间的初始值2010年6月30日星期三,15时20分0秒

char?dis_buffer[6]; ???//存放显示数据的缓冲区

sbit?Beep_flag?=?P3^2; ???//蜂鸣器的接口

sbit?key_timer?=?P3^4; ???//定时按钮

sbit?key_set?=?P3^5; ???//调整按钮

sbit?key_up?=?P3^6; ???//增加按钮

sbit?key_down?=?P3^7; ???//减小按钮

char?romhour,romminute,romsec; ???//分别存放定时的时,分,秒

bit?Beepflag; ???//标记闹钟是否开启

//延时函数

void?delays(uchar?x)

{

while(x)?x--;

}

//设置键的处理函数

void?set()

{

setflag?++;

flag_set?=?1;

if(setflag?=?4)

{

setflag?=?0;

flag_set?=?0;

Initial_DS1302(Time);

}

}

//定时间的处理函数

void?timer()

{

setflag?++;

flag_timer?=?1;

if(setflag?==?1)

{

Time.Hour?=?romhour;

Time.Minute?=?romminute;

Time.Second?=?romsec;

}

else?if(setflag?=?4)

{

setflag?=?0;

flag_timer?=?0;

romhour?=?Time.Hour;

romminute?=?Time.Minute;

romsec?=?Time.Second;

}

}

//增加键的处理函数

void?up()

{

switch(setflag)

{

case?0:

break;

case?1:

Time.Second?++;

if(Time.Second?=?60)

Time.Second?=?0;

break;

case?2:

Time.Minute?++;

if(Time.Minute?=?60)

Time.Minute?=?0;

break;

case?3:

Time.Hour?++;

if(Time.Hour?=?24)

Time.Hour?=?0;

break;

}

}

//减小键的处理函数

void?down()

{

switch(setflag)

{

case?0:

break;

case?1:

Time.Second?--;

if(Time.Second??0)

Time.Second?=?59;

break;

case?2:

Time.Minute?--;

if(Time.Minute??0)

Time.Minute?=?59;

break;

case?3:

Time.Hour?--;

if(Time.Hour??0)

Time.Hour?=?23;

break;

}

}

//设置键的扫描函数

void?set_down()

{

if(key_set?==?0??flag_timer?==?0)

{

delays(100);

if(key_set?==?0)

{

set();

}

while(!key_set);

}

}

//定时键的扫描函数

void?timer_down()

{

if(key_timer?==?0??flag_set?==?0)

{

delays(100);

if(key_timer?==?0)

{

timer();

}

while(!key_timer);

}

}

//增加键的扫描函数

void?up_down()

{

if(key_up?==?0??setflag?!=?0)

{

delays(100);

if(key_up?==?0)

{

up();

while(!key_up);

}

}

}

//减少键的处理函数

void?down_down()

{

if(key_down?==?0??setflag?!=?0)

{

delays(100);

if(key_down?==?0)

{

down();

while(!key_down);

}

}

}

//定时开关的扫描处理函数

void?beepflag_down()

{

if(Beep_flag?==?0)

{

delays(100);

{

Beepflag?=?!Beepflag;

while(!Beep_flag);

}

}

}

//ds1302.h

#ifndef?_REAL_TIMER_DS1302

#define?_REAL_TIMER_DS1302

#include?REG51.h

sbit??DS1302_CLK?=?P1^1;??????????????//实时时钟时钟线引脚

sbit??DS1302_IO??=?P1^2;??????????????//实时时钟数据线引脚

sbit??DS1302_RST?=?P1^3;??????????????//实时时钟复位线引脚

sbit??ACC0?=?ACC^0;

sbit??ACC7?=?ACC^7;

sbit??Beep?=?P2^7;

typedef?struct?__SYSTEMTIME__

{?? char?Second;

char?Minute;

char?Hour;

char?Week;

char?Day;

char?Month;

char?Year;

}SYSTEMTIME; //定义的时间类型

#define?AM(X) X

#define?PM(X) (X+12)???????????? ??//?转成24小时制

#define?DS1302_SECOND 0x80??????????//秒寄存器

#define?DS1302_MINUTE 0x82??????????//分寄存器

#define?DS1302_HOUR 0x84

#define?DS1302_WEEK 0x8A

#define?DS1302_DAY 0x86

#define?DS1302_MONTH 0x88

#define?DS1302_YEAR 0x8C

#define?DS1302_RAM(X) (0xC0+(X)*2)??? //用于计算?DS1302_RAM?地址的宏

void?DS1302InputByte(unsigned?char?d)? //实时时钟写入一字节(内部函数)

{???unsigned?char?i;

ACC?=?d;

for(i=8;?i0;?i--)

{ DS1302_IO??=?ACC0;??????????? //相当于汇编中的?RRC

DS1302_CLK?=?1;

DS1302_CLK?=?0;?????????????????//发一个高跳变到低的脉冲

ACC?=?ACC??1;

}

}

unsigned?char?DS1302OutputByte(void)? //实时时钟读取一字节(内部函数)

{? unsigned?char?i;

for(i=8;?i0;?i--)

{ ACC?=?ACC?1;????????? //相当于汇编中的?RRC

ACC7?=?DS1302_IO;

DS1302_CLK?=?1;

DS1302_CLK?=?0;?????????????????//发一个高跳变到低的脉冲

}

return(ACC);

}

void?Write1302(unsigned?char?ucAddr,?unsigned?char?ucDa)//ucAddr:?DS1302地址,?ucData:?要写的数据

{ DS1302_RST?=?0;

DS1302_CLK?=?0;

DS1302_RST?=?1;

DS1302InputByte(ucAddr);??????? //?地址,命令

DS1302InputByte(ucDa);??????? //?写1Byte数据

DS1302_CLK?=?1;

DS1302_RST?=?0;??????????????????//RST?0-1-0,CLK?0-1

}

unsigned?char?Read1302(unsigned?char?ucAddr) //读取DS1302某地址的数据

{ unsigned?char?ucData;

DS1302_RST?=?0;

DS1302_CLK?=?0;

DS1302_RST?=?1;??????????????????????//enable

DS1302InputByte(ucAddr|0x01);????????//?地址,命令

ucData?=?DS1302OutputByte();?????????//?读1Byte数据

DS1302_CLK?=?1;??????????????????????//RST?0-1-0,CLK?0-1

DS1302_RST?=?0;

return(ucData);

}

void?DS1302_SetProtect(bit?flag)????????//是否写保护

{ if(flag)

Write1302(0x8E,0x80);?//WP=1,不能写入

else

Write1302(0x8E,0x00);//WP=0,可以写入

}

void?DS1302_SetTime(unsigned?char?Address,?unsigned?char?Value)????????//?设置时间函数

{ DS1302_SetProtect(0);

Write1302(Address,?((Value/10)4?|?(Value%10)));?//高4位为十位,低4位为个位

DS1302_SetProtect(1);

}

//获取时间函数,从DS1302内读取时间然后存入Time内

void?DS1302_GetTime(SYSTEMTIME?*Time)

{ unsigned?char?ReadValue;

ReadValue?=?Read1302(DS1302_SECOND);

Time-Second?=?((ReadValue0x70)4)*10?+?(ReadValue0x0F);//转换成10进制的秒

ReadValue?=?Read1302(DS1302_MINUTE);

Time-Minute?=?((ReadValue0x70)4)*10?+?(ReadValue0x0F);

ReadValue?=?Read1302(DS1302_HOUR);

Time-Hour?=?((ReadValue0x70)4)*10?+?(ReadValue0x0F);

ReadValue?=?Read1302(DS1302_DAY);

Time-Day?=?((ReadValue0x70)4)*10?+?(ReadValue0x0F);

ReadValue?=?Read1302(DS1302_WEEK);

Time-Week?=?((ReadValue0x70)4)*10?+?(ReadValue0x0F);

ReadValue?=?Read1302(DS1302_MONTH);

Time-Month?=?((ReadValue0x70)4)*10?+?(ReadValue0x0F);

ReadValue?=?Read1302(DS1302_YEAR);

Time-Year?=?((ReadValue0x70)4)*10?+?(ReadValue0x0F);

}

//利用STime初始化DS1302

void?Initial_DS1302(SYSTEMTIME?STime)

{ unsigned?char?Second=Read1302(DS1302_SECOND);

if(Second0x80)?? DS1302_SetTime(DS1302_SECOND,0);??//如果第七为1(表明没有启动),?则启动时钟

DS1302_SetTime(DS1302_SECOND,STime.Second); ?//设定起始时间

DS1302_SetTime(DS1302_MINUTE,STime.Minute);

DS1302_SetTime(DS1302_HOUR,STime.Hour);

DS1302_SetTime(DS1302_DAY,STime.Day);

DS1302_SetTime(DS1302_MONTH,STime.Month);

DS1302_SetTime(DS1302_YEAR,STime.Year);

DS1302_SetTime(DS1302_WEEK,STime.Week);

}

#endif

(责任编辑:IT教学网)

更多

推荐测评专题文章