导航:首页 > 操作系统 > 单片机课程设计电子时钟

单片机课程设计电子时钟

发布时间:2022-07-14 05:58:05

Ⅰ 求C51单片机数字电子时钟课程设计

#include<reg52.h>
#include<absacc.h>
#include<intrins.h>
#define
unit
unsigned
int
#define
uchar
unsigned
char
//#define
HZ
12
sbit
key0=P0^0;
//
分钟调整
sbit
key1=P0^1;
//
小时调整
sbit
P2_0=P2^7;
//秒
指示灯
sbit
MN_RXD=P3^6;
sbit
MN_TXD=P3^7;
uchar
data
CLOCK[4]={0,0,0,12};//存放时钟时间(百分秒,秒,分,和时位)
//数码管显示表0-f

uchar
code
TABLE[]={0xBE,0x06,0xEA,0x6E,0x56,0x7C,0xFC,0x0E,0xFE,0x7E,0x00};
//**********************************
//模拟串口发送一个字节数据
函数
//**********************************
void
SendData(unsigned
char
senddata)
{
unsigned
char
i;
for(i=0;i<8;i++)
{
if((senddata&0x01)==0)
MN_RXD=0;
else
MN_RXD=1;
_nop_();
MN_TXD=0;
_nop_();
MN_TXD=1;
senddata=senddata>>1;
}
}
//**********************************
//显示程序函数
//**********************************
void
display(void)
{
//
unsigned
int
n;
uchar
temp;
temp=CLOCK[1];
temp=temp%10;
SendData(TABLE[temp]);
temp=CLOCK[1];
temp=temp/10;
SendData(TABLE[temp]);
temp=CLOCK[2];
temp=temp%10;
SendData(TABLE[temp]);
temp=CLOCK[2];
temp=temp/10;
SendData(TABLE[temp]);
temp=CLOCK[3];
temp=temp%10;
SendData(TABLE[temp]);
temp=CLOCK[3];
temp=temp/10;
SendData(TABLE[temp]);
/*
for(n=0;n<5000;n++);
for(n=0;n<6;n++)
{
SendData(TABLE[10]);
}
*/
}
//**********************************
//按键控制函数
//**********************************
void
keycan()
{
unsigned
int
n;
EA=0;
if(key0==0)
//
分钟调整
{
for(n=0;n<10000;n++);
//延时去抖动
while(key0==0);
CLOCK[2]=CLOCK[2]+1;
if(CLOCK[2]==60)
//到一时
{
CLOCK[2]=0;
}
display();
}
if(key1==0)
//
小时调整
{
for(n=0;n<10000;n++);
//延时去抖动
while(key1==0);
CLOCK[3]=CLOCK[3]+1;
if(CLOCK[3]==24)
{
CLOCK[3]=0;
}
display();
}
EA=1;
}
//**********************************
//T0中断服务函数
//**********************************
void
time0()
interrupt
1
//using
1
{
TH0=0xD8;
TL0=0xF0;
//重置初值
//
TH0=0xB1;
TL0=0xE0;
//时钟处理
CLOCK[0]=CLOCK[0]+1;
}
//**********************************
//主函数
//**********************************
void
main()
{
EA=1;
ET0=1;
TMOD=0x01;
//T0方式1定时
TH0=0xD8;
TL0=0xF0;
//D8F0
定时10ms
//
TH0=0xB1;
TL0=0xE0;
//定时
20ms
TR0=1;
for(;;)
{
if(CLOCK[0]==100)
//到一秒
10ms*100
{
CLOCK[0]=0;
P2_0=~P2_0;
CLOCK[1]=CLOCK[1]+1;
if(CLOCK[1]==60)
//到一分
{
CLOCK[1]=0;
CLOCK[2]=CLOCK[2]+1;
if(CLOCK[2]==60)
//到一时
{
CLOCK[2]=0;
CLOCK[3]=CLOCK[3]+1;
if(CLOCK[3]==24)
{
CLOCK[3]=0;
}
}
}
display();
}
keycan();
}
}

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

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

1302.c

#include<DS1302.h>

#include<key.h>

ucharbit_ser[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};

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

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

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

{

TMOD=0x21;

TL0=(65536-5000)%256;

TH0=(65536-5000)/256;

EA=1;

ET0=1;

TR0=1;

}

voidtimer0_isr(void)interrupt1 //T0中断处理函数

{

charflag; //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)

{

case0:

P2=bit_ser[0];

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

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

else

P0=seven_seg[dis_buffer[0]];

break;

case1:

P2=bit_ser[1];

if(setflag==3)

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

else

P0=seven_seg[dis_buffer[1]];

break;

case2:

P2=bit_ser[2];

if(setflag==2)

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

else

P0=seven_seg[dis_buffer[2]];

break;

case3:

P2=bit_ser[3];

if(setflag==2)

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

else

P0=seven_seg[dis_buffer[3]];

break;

case4:

P2=bit_ser[4];

if(setflag==1)

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

else

P0=seven_seg[dis_buffer[4]];

break;

case5:

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++;

}

}

voidmain()

{

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

#include<reg51.h>

#defineucharunsignedchar

#defineuintunsignedint

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

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

chardis_buffer[6]; //存放显示数据的缓冲区

sbitBeep_flag=P3^2; //蜂鸣器的接口

sbitkey_timer=P3^4; //定时按钮

sbitkey_set=P3^5; //调整按钮

sbitkey_up=P3^6; //增加按钮

sbitkey_down=P3^7; //减小按钮

charromhour,romminute,romsec; //分别存放定时的时,分,秒

bitBeepflag; //标记闹钟是否开启

//延时函数

voiddelays(ucharx)

{

while(x)x--;

}

//设置键的处理函数

voidset()

{

setflag++;

flag_set=1;

if(setflag>=4)

{

setflag=0;

flag_set=0;

Initial_DS1302(Time);

}

}

//定时间的处理函数

voidtimer()

{

setflag++;

flag_timer=1;

if(setflag==1)

{

Time.Hour=romhour;

Time.Minute=romminute;

Time.Second=romsec;

}

elseif(setflag>=4)

{

setflag=0;

flag_timer=0;

romhour=Time.Hour;

romminute=Time.Minute;

romsec=Time.Second;

}

}

//增加键的处理函数

voip()

{

switch(setflag)

{

case0:

break;

case1:

Time.Second++;

if(Time.Second>=60)

Time.Second=0;

break;

case2:

Time.Minute++;

if(Time.Minute>=60)

Time.Minute=0;

break;

case3:

Time.Hour++;

if(Time.Hour>=24)

Time.Hour=0;

break;

}

}

//减小键的处理函数

voiddown()

{

switch(setflag)

{

case0:

break;

case1:

Time.Second--;

if(Time.Second<0)

Time.Second=59;

break;

case2:

Time.Minute--;

if(Time.Minute<0)

Time.Minute=59;

break;

case3:

Time.Hour--;

if(Time.Hour<0)

Time.Hour=23;

break;

}

}

//设置键的扫描函数

voidset_down()

{

if(key_set==0&&flag_timer==0)

{

delays(100);

if(key_set==0)

{

set();

}

while(!key_set);

}

}

//定时键的扫描函数

voidtimer_down()

{

if(key_timer==0&&flag_set==0)

{

delays(100);

if(key_timer==0)

{

timer();

}

while(!key_timer);

}

}

//增加键的扫描函数

voip_down()

{

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

{

delays(100);

if(key_up==0)

{

up();

while(!key_up);

}

}

}

//减少键的处理函数

voiddown_down()

{

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

{

delays(100);

if(key_down==0)

{

down();

while(!key_down);

}

}

}

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

voidbeepflag_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>

sbitDS1302_CLK=P1^1;//实时时钟时钟线引脚

sbitDS1302_IO=P1^2;//实时时钟数据线引脚

sbitDS1302_RST=P1^3;//实时时钟复位线引脚

sbitACC0=ACC^0;

sbitACC7=ACC^7;

sbitBeep=P2^7;

typedefstruct__SYSTEMTIME__

{ charSecond;

charMinute;

charHour;

charWeek;

charDay;

charMonth;

charYear;

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

#defineAM(X) X

#definePM(X) (X+12) //转成24小时制

#defineDS1302_SECOND 0x80//秒寄存器

#defineDS1302_MINUTE 0x82//分寄存器

#defineDS1302_HOUR 0x84

#defineDS1302_WEEK 0x8A

#defineDS1302_DAY 0x86

#defineDS1302_MONTH 0x88

#defineDS1302_YEAR 0x8C

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

voidDS1302InputByte(unsignedchard) //实时时钟写入一字节(内部函数)

{unsignedchari;

ACC=d;

for(i=8;i>0;i--)

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

DS1302_CLK=1;

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

ACC=ACC>>1;

}

}

unsignedcharDS1302OutputByte(void) //实时时钟读取一字节(内部函数)

{ unsignedchari;

for(i=8;i>0;i--)

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

ACC7=DS1302_IO;

DS1302_CLK=1;

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

}

return(ACC);

}

voidWrite1302(unsignedcharucAddr,unsignedcharucDa)//ucAddr:DS1302地址,ucData:要写的数据

{ DS1302_RST=0;

DS1302_CLK=0;

DS1302_RST=1;

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

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

DS1302_CLK=1;

DS1302_RST=0;//RST0->1->0,CLK0->1

}

unsignedcharRead1302(unsignedcharucAddr) //读取DS1302某地址的数据

{ unsignedcharucData;

DS1302_RST=0;

DS1302_CLK=0;

DS1302_RST=1;//enable

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

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

DS1302_CLK=1;//RST0->1->0,CLK0->1

DS1302_RST=0;

return(ucData);

}

voidDS1302_SetProtect(bitflag)//是否写保护

{ if(flag)

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

else

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

}

voidDS1302_SetTime(unsignedcharAddress,unsignedcharValue)//设置时间函数

{ DS1302_SetProtect(0);

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

DS1302_SetProtect(1);

}

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

voidDS1302_GetTime(SYSTEMTIME*Time)

{ unsignedcharReadValue;

ReadValue=Read1302(DS1302_SECOND);

Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//转换成10进制的秒

ReadValue=Read1302(DS1302_MINUTE);

Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_HOUR);

Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_DAY);

Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_WEEK);

Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_MONTH);

Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_YEAR);

Time->Year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

}

//利用STime初始化DS1302

voidInitial_DS1302(SYSTEMTIMESTime)

{ unsignedcharSecond=Read1302(DS1302_SECOND);

if(Second&0x80) 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

Ⅲ 单片机实现电子时钟

ORG 0000H ;程序执行开始地址
LJMP START ;跳到标号START执行
ORG 0003H ;外中断0中断程序入口
LJMP OUTINTT0 ;外中断0中断返回
ORG 000BH ;定时器T0中断程序入口
LJMP INTT0 ;跳至INTTO执行
ORG 0013H ;外中断1中断程序入口
RETI;外中断1中断返回
ORG 001BH ;定时器T1中断程序入口
LJMP INTT1 ;跳至INTT1执行;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 主 程 序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
START:
MOV R0,#70H ;清70H-7AH共11个内存单元
MOV R7,#0BH ;
CLEARDISP:
MOV @R0,#00H ;
INC R0 ;
DJNZ R7,CLEARDISP ;
MOV 70H,#07H;
MOV 71H,#05H;
MOV 76H,#09H;
MOV 77H,#05H;
MOV 78H,#05H;
MOV 79H,#00H;
MOV 20H,#00H ;清20H(标志用)
MOV 7AH,#0AH ;放入"熄灭符"数据
MOV 7BH,#00H ;清报时寄存器
MOV TMOD,#11H ;设T0、T1为16位定时器
MOV TL0,#0B0H ;50MS定时初值(T0计时用)
MOV TH0,#3CH ;50MS定时初值
MOV TL1,#0B0H ;50MS定时初值(T1闪烁定时用)
MOV TH1,#3CH ;50MS定时初值
SETB PT1;定时器T1为高优先级
SETB EA ;总中断开放
SETB ET0 ;允许T0中断
SETB TR0 ;开启T0定时器
SETB EX0 ;开启外部中断0
MOV R4,#14H ;1秒定时用初值(50MS×20)
MOV R2,#06H ;0.3秒的闪动初值(50MS*6)
START1:
LCALL DISPLAY;调用显示子程序
LCALL BELL;
LCALL DISCLOSE;

SJMP START1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 计时程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;T0中断服务程序
INTT0:
PUSH ACC ;累加器入栈保护
PUSH PSW ;状态字入栈保护
CLR ET0 ;关T0中断允许
CLR TR0 ;关闭定时器T0
MOV TL0,#0B0H ;重装初值(低8位修正值)
MOV TH0,#3CH ;重装初值(高8位修正值)
SETB TR0 ;开启定时器T0
DJNZ R4, OUTT0 ;20次中断未到中断退出
ADDSS:
MOV R4,#14H ;20次中断到(1秒)重赋初值
MOV R0,#71H ;指向秒计时单元(70H-71H)
ACALL DBchange ;调用数据处理程序(加1并存入显示单元)
MOV A,R3 ;秒数据放入A(R3为2位十进制数组合)
CLR C ;清进位标志
CJNE A,#60H,ADDMM ;
ADDMM:
JC OUTT0 ;小于60秒时中断退出
LCALL CLR0 ;大于或等于60秒时对秒计时单元清0
MOV R0,#77H ;指向分计时单元(76H-77H)
ACALL DBchange ;
MOV A,R3 ;分数据放入A
CLR C ;清进位标志
CJNE A,#60H,ADDHH ;
ADDHH:
JC OUTT0 ;小于60分时中断退出
ACALL CLR0 ;大于或等于60分时分计时单元清0
MOV R0,#79H ;指向小时计时单元(78H-79H)
ACALL DBchange ;
MOV A,R3 ;时数据放入A
CLR C ;清进位标志
MOV 7BH,#01H
CJNE A,#24H,HOUR ;
HOUR:
JC OUTT0 ;小于24小时中断退出
ACALL CLR0 ;大于或等于24小时小时计时单元清0
OUTT0:
MOV 72H,76H ;中断退出时将分、时计时单元数据移
MOV 73H,77H ;入对应显示单元
MOV 74H,78H ;
MOV 75H,79H ;
POP PSW ;恢复状态字(出栈)
POP ACC ;恢复累加器
SETB ET0 ;开放T0中断
RETI ;中断返回;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 闪动调时 程 序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;T1中断服务程序,用作时间调整时调整单元闪烁指示
INTT1:
PUSH ACC ;中断现场保护
PUSH PSW ;
MOV TL1, #0B0H ;装定时器T1定时初值
MOV TH1, #3CH ;
DJNZ R2,INTT1OUT ;0.3秒未到退出中断(50MS中断6次)
MOV R2,#06H ;重装0.3秒定时用初值
CPL 02H ;0.3秒定时到对闪烁标志取反
JB 02H,FLASH1 ;02H位为1时显示单元"熄灭"
MOV 72H,76H ;02H位为0时正常显示
MOV 73H,77H ;
MOV 74H,78H ;
MOV 75H,79H ;
INTT1OUT:
POP PSW ;恢复现场
POP ACC ;
RETI ;中断退出
FLASH1:
JB 01H,FLASH2 ;01H位为1时,转小时熄灭控制
MOV 72H,7AH ;01H位为0时,"熄灭符"数据放入分
MOV 73H,7AH ;显示单元(72H-73H),将不显示分数据
MOV 74H,78H ;
MOV 75H,79H ;
AJMP INTT1OUT ;转中断退出
FLASH2:
MOV 72H,76H ;01H位为1时,"熄灭符"数据放入小时
MOV 73H,77H ;显示单元(74H-75H),小时数据将不显示
MOV 74H,7AH ;
MOV 75H,7AH ;
AJMP INTT1OUT ;转中断退出
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 数据处理程序,把6个数码管显示内容存入相应的地址;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
DBchange:
MOV A,@R0 ;取当前计时单元数据到A
DEC R0 ;指向前一地址
SWAP A ;A中数据高四位与低四位交换
ORL A,@R0 ;前一地址中数据放入A中低四位
ADD A,#01H ;A加1操作
DA A ;十进制调整
MOV R3,A ;移入R3寄存器
ANL A,#0FH ;高四位变0
MOV @R0,A ;放回前一地址单元
MOV A,R3 ;取回R3中暂存数据
INC R0 ;指向当前地址单元
SWAP A ;A中数据高四位与低四位交换
ANL A,#0FH ;高四位变0
MOV @R0,A ;数据放入当削地址单元中
RET ;子程序返回
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 清零程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;对计时单元复零用
CLR0:
CLR A ;清累加器
MOV @R0,A ;清当前地址单元
DEC R0 ;指向前一地址
MOV @R0,A ;前一地址单元清0
RET ;子程序返回
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 时钟调整中断程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;当调时按键按下时进入此程序
OUTINTT0:
PUSH ACC;
PUSH PSW;
CLR ET0 ;关定时器T0中断
CLR TR0 ;关闭定时器T0
CLR EX0 ;关闭外部中断0
MOV R2,#06H ;进入调时状态,赋闪烁定时初值
SETB ET1 ;允许T1中断
SETB TR1 ;开启定时器T1
SET2: JNB P1.0,SET1 ;P1.0口为0(键未释放),等待
SETB 00H ;键释放,分调整闪烁标志置1
SET4:
JB P1.0,SET3 ;p1.0没有按下时进入分调整程序
LJMP SETHH ;p1.0按下转调小时状态
SET3:
LCALL DISPLAY ;等待调分按键时时钟显示用
JB P1.1,SET4;等待p1.1按下
LCALL DL1S; MOV R0,#77H;按下时加1分钟操作
LCALL DBchange ;调用加1子程序
MOV A,R3 ;取调整单元数据
CLR C ;清进位标志
CJNE A,#60H,HHH ;调整单元数据与60比较
HHH:
JC SET4 ;调整单元数据小于60转SET4循环
LCALL CLR0 ;调整单元数据大于或等于60时清0
CLR C ;清进位标志
lJMP SET4 SETHH:
CLR 00H ;分闪烁标志清除(进入调小时状态)
SETHH1:
JNB P1.0,SET5 ;等待键释放
SETB 01H ;小时调整标志置1
SET6:
JNB P1.0,SETOUT ;P1.0再次按下时退出时间调整
LCALL DISPLAY;
JB P1.1,SET6;等待按键按下
LCALL DL1S;
MOV R0,#79H ;按下P1.1时加1小时操作
LCALL DBchange ;调加1子程序
MOV A,R3 ;
CLR C ;
CJNE A,#24H,HOUU ;计时单元数据与24比较
HOUU:
JC SET6;小于24转SET6循环
LCALL CLR0 ;大于或等于24时清0操作
AJMP SET6;跳转到SET6循环
SETOUT:
JNB P1.0,SETOUT1 ;调时退出程序。等待键释放
LCALL DISPLAY ;延时削抖
JNB P1.0,SETOUT ;是抖动,返回SETOUT再等待
OUTRETEND:
CLR 01H ;清调小时标志
CLR 00H ;清调分标志
CLR 02H ;清闪烁标志
CLR TR1 ;关闭定时器T1
CLR ET1 ;关定时器T1中断
SETB TR0 ;开启定时器T0
SETB ET0 ;开定时器T0中断(计时开始)
SETB EX0;开启外部中断0
POP PSW;
POP ACC;
RETI ;反回主程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SET1:
LCALL DISPLAY ;键释放等待时调用显示程序(调分)
LJMP SET2 ;防止键按下时无时钟显示
SET5:
LCALL DISPLAY ;键释放等待时调用显示程序(调小时)
LJMP SETHH1 ;防止键按下时无时钟显示
SETOUT1:
LCALL DISPLAY ;退出时钟调整时键释放等待
LJMP SETOUT ;防止键按下时无时钟显示
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 显示程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 显示数据在70H-75H单元内,用六位LED共阳数码管显示,P0口输出段码数据,P2口作
; 扫描控制,每个LED数码管亮1MS时间再逐位循环。
DISPLAY:
MOV R1,#70H ;指向显示数据首址
MOV R5,#01H ;扫描控制字初值
PLAY:
MOV A,R5 ;扫描字放入A
MOV P2,A ;从P2口输出
MOV A,@R1 ;取显示数据到A
MOV DPTR,#TAB ;取段码表地址
MOVC A,@A+DPTR ;查显示数据对应段码
MOV P0,A ;段码放入P0口
LCALL DL1MS ;显示1MS
INC R1 ;指向下一地址
MOV A,R5 ;扫描控制字放入A
JB ACC.5,ENDOUT ;ACC.5=1时一次显示结束
RL A ;A中数据循环左移
MOV R5,A ;放回R5内
LJMP PLAY ;跳回PLAY循环
ENDOUT:
MOV P0,#00H ;P0口复位
RET ;子程序返回
TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,00H
;共阴段码表 "0""1""2" "3""4""5""6""7" "8""9""不亮"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;整点报时;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BELL:
MOV A,7BH;
CLR C;
MOV 7BH,#00H ;
CJNE A,#01H,BELLEND MOV A,79H;
SWAP A;
ORL A,78H;
MOV 7CH ,ABELLRING:
CLR P1.7;
LCALL DL05S;
SETB P1.7;
LCALL DL05S;
DJNZ 7CH,BELLRING; MOV A ,#00H;
MOV 7BH,#00H ;BELLEND:RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;省电模式
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DISCLOSE:
JB P1.3,OUTDISCLOSE;
CLOSE1: MOV P2,#0FFH;
JNB P1.3,CLOSE1;
JB P1.3,CLOSE1;
CLOSE2: JNB P1.3,CLOSE2;
MOV P2,R5;
OUTDISCLOSE:RET;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 延时程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;1MS延时程序,LED显示程序用
DL1MS: MOV R6,#14H
DL1: MOV R7,#19H
DL2: DJNZ R7,DL2
DJNZ R6,DL1
RET
;20MS延时程序,采用调用显示子程序以改善LED的显示闪烁现象
DS20MS: ACALL DISPLAY
ACALL DISPLAY
ACALL DISPLAY
RET
;延时程序,用作按键时间的长短判断
DL1S: LCALL DL05S
LCALL DL05S
RET
DL05S: MOV R3,#20H ;8毫秒*32=0.196秒
DL05S1: LCALL DISPLAY
DJNZ R3,DL05S1
RET
END ;程序结束 但是做这个是自己做的,是可以调时间,不要的话可以把那个部分删除。

Ⅳ 用单片机设计一个电子时钟

MAIN
ORG 0000H
AJMP MAIN
ORG 000BH
AJMP CLOCK
ORG 0030H
PORT EQU 8000H
PORTA EQU 8001H
PORTB EQU 8002H
PORTC EQU 8003H
DISP0 EQU 30H
DISP1 EQU 31H
DISP2 EQU 32H
DISP3 EQU 33H
DISP4 EQU 34H
DISP5 EQU 35H
HOUR EQU 3CH
MIN EQU 3DH
SEC EQU 3EH
MSEC EQU 3FH
AHOUR EQU 40H
AMIN EQU 41H
ASEC EQU 42H
F1 BIT PSW.1
MAIN: MOV SP, #50H ;设置堆栈区
MOVX DPTR, #PORT
MOV A, #03H
MOVX @DPTR, A ;8155初始化
CLR F1 ;清零闹钟标志位
CLR F0 ;允许计时显示
MOV AHOUR, #0FFH
MOV AMIN, #0FFH
MOV ASEC, #0FFH
MOV R7, #10H
MOV R0, #DISP0
CLR A
LOOP: MOV @R0, A
INC R0
DJNZ R7, LOOP ;设置初值
MOV TMOD, #01H
MOV TL0, #0B0H
MOV TH0, #3CH ;定时器0初始化,定时时间100ms
SETB TR0 ; 启动定时器
SETB EA ;开中断
SETB ET0
BEGIN: ACALL ALARM ;调用定时比较
ACALL KEYSCAN
CJNE A, #0AH, NEXT1 ;是CLR/RST键否?
CLR TR0 ;是则暂停计时
MOV R1, #HOUR ;地址指针指向计时缓冲区首地址
AJMP MOD
NEXT1: CJNE A, #0BH, BEGIN ;是ALARM键否?
JB F1, NEXT2 ;闹钟正在闹响否?
MOV R1, #AHOUR ;地址指针指向闹钟值寄存区首地址
MOD: SETB F0 ;置位时间设置/闹钟定时标志禁止显示计时时间ACALL MODIFY ;调用时间设置/闹钟定时程序
SETB TR0 ;重新开始计时
CLR F0 ;清零时间设置/闹钟定时标志,恢复显示计时时间
AJMP BEGIN
NEXT2: SETB P1.0 ;闹钟正在闹响,停闹
CLR F1 ;清零闹钟标志
AJMP BEGIN
MODIFY: ACALL KEYIN ;调用键盘设置子程序
ACALL COMB ;调用合字子程序
RET
KEYIN: PUSH PSW
PUSH ACC
SETB RS1 ;保护现场
MOV R0, #DISP0 ;R0指向显示缓冲区首地址
MOV R7, #06H ;设置键盘输入次数

L1: CLR RS1
ACALL KEYSCAN ;调用数合法性检测(是否在于9)
SETB RS1R
CJNE A, #0AH, L2
L2: JNC L1 ;大于9,重新键入
MOV @R1, A ;键号送显示缓冲区
INC R1
DJNZ R7, L1 ;6位时间输入完否?未完继续,否则返回
POP ACC
POP PSW
CLR RS1 ;恢复现场
RET
KEYSCAN: ACALL TEST ;调判按键是否按下子程序TEST
JNZ REMOV ;有键按下调消抖延时
ACALL DISPLAY
ACALL ALARM
AJMP KEYSCAN ;无按键按下继续判断是否按键
REMOV: ACALL DISPLAY ;调用显示子程序延时消抖
ACALL TEST ;再判是否有键按下
JNZ LIST ;有键按下转逐列扫描
ACALL DISPLAY
ACALL ALARM
AJMP KEYSCAN ;无键按下继续判断是否按键
LIST: MOV R2, #0FEH ;首列扫描字送R2
MOV R3, #00H ;首列键号送R3
LINE0: MOV DPTR, #PORTA ;DPTR指针指向8155的A口
MOV A, R2 ;首列扫描字送R2
MOVX @DPTR, A ;首列扫描字送8155的A口
MOV DPTR, #PORTC ;DPTR指针指向8155的C口
MOVX A, @DPTR ;读入C口的行状态
JB ACC.0, EXIT ;第0行无键按下转第一行
MOV A, #00H ;第0行有键按下,行首键号送A
AJMP TRYK ;求键号
NEXT: INC R3 ;扫描下一列
MOV A, R2 ;扫描字送A
JNB ACC.3, EXIT ;4列扫描完,重新进行下一轮扫描
RL A ;4列未扫描完,扫描字左移扫描下一列
MOV R2, A ;扫描字送A
AJMP LINE0 ;转向扫描下一列
EXIT: AJMP KEYSCAN ;等待下一次按键
TRYK: ADD A, R3 ;按公式计算键码,求得键号
PUSH ACC ;键号入栈保护
LETK: ACALL TEST ;等待按键释放
JNZ LETK ;按键未释放,继续等待
POP ACC ;按键释放,键号出栈
RET
TEST: MOV DPTR, #PORTA ;DPTR指针指向8155的A口
MOV A, #00H
MOVX @DPTR, A ;全扫描字00H送8155的A口
MOV DPTR, #PORTC ;DPTR指针指向8155的C口
MOVX A, @DPTR ;读入C口行状态
CPL A ;A取反,以高电平表示有键按下
ANL A, #07H ;屏蔽高5位
RET
DISPLAY:JB F0, DISP ;允许时间显示标志F0=1转DISP
ACALL SEPA ;否则调用SEPA刷新显示缓冲区
DISP: PUSH PSW ;动态扫描显示子程序
PUSH ACC
SETB RS0
MOV DPTR, #PORTA
MOV A, #0FFH
MOVX @DPTR, A ;关显示
MOV R0, #DISP0
MOV R7, #00H
MOV R6, #06H
MOV R5, #0FEH
DIS1: MOV DPTR, #TAB
MOV A, @R0
MOVC A, @A+DPTR
MOV DPTR, #PORTB
MOVX @DPTR, A
MOV DPTR, #PORTA
MOV A, R5
MOVX @DPTR, A
HERE: DJNZ R7, HERE
INC R0
MOV A, R5
RL A
MOV R5, A
DJNZ R6, DIS1
CLR RS0
POP ACC
POP PSW
RET
TAB:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
COMB: MOV R0, #DISP1 ;R0指向显示缓冲区小时低位
ACALL COMB1 ;合字
CJNE A, #24, CHK ;小时大于24否?
CHK: JNC EXIT1 ;大于24则取消本次设置,退出
MOV @R1, A ;否则小时送计时缓冲区/闹钟值寄存区小时单元
INC R1
MOV R0, #DISP3 ;R0指向显示缓冲区分低位
ACALL COMB1
CJNE A, #60H, CHK1
CHK1: JNC EXIT1
MOV @R1, A
INC R1
MOV R0, #DISP5 ;R0指向显示缓冲区秒低位
ACALL COMB1
CJNE A, #60H,CHK2
CHK2: JNC EXIT1
MOV @R1, A
RET
EXIT1: AJMP MAIN ;输入不合法退出,重新清零计时
COMB1: MOV A, @R0
ANL A, #0FH ;取出低位
MOV 43H,A ;暂存于43H单元
DEC R0 ;指向高位
MOV A, @R0
ANL A, #0FH
SWAP A ;高位送高4位
ORL A, 43H ;高低位合并
RET

SEPA: PUSH PSW
PUSH ACC
SETB RS0
MOV R0, #DISP5 ;指向显示缓冲区秒低位
MOV A, SEC
ACALL SEPA1
MOV A, MIN
ACALL SEPA1
MOV A, HOUR
ACALL SEPA1
POP ACC
POP PSW
RET
SEPA1: MOV 44H,A ;暂存44H
ANL A, #0FH ;取出低位
MOV @R0, A ;送显示缓冲区低位
DEC R0 ;指向显示缓冲区高位
MOV A, 44H
ANL A, #0F0H ;取出高位
SWAP A ;高位送往低四位形成高位数据
MOV @R0, A ;高位数据送显示缓冲区高位
RET
ALARM: MOV A, ASEC
CJNE A, SEC, BACK ;秒单元相同则继续比较,否则返回
MOV A, AMIN
CJNE A, MIN, BACK ;分单元相同则继续比较,否则返回
MOV A, AHOUR
CJNE A, HOUR, BACK ;小时单元相同定时时间到
CLR P1.0 ;启动闹钟鸣叫
SETB F1 ;置位闹钟标志
BACK: RET
CLOCK: MOV TL0, #0B7H
MOV TH0, #3CH ;重装初值,时间校正
PUSH PSW
PUSH ACC ;保护现场
INC MSEC
MOV A, MSEC
CJNE A, #14H, DONE
MOV MSEC, #00H
MOV A, SEC
INC A
DA A ;二—十进制转换
MOV SEC, A
CJNE A, #60H, DONE
MOV SEC, #00H
MOV A, MIN
INC A
DA A
MOV MIN, A
CJNE A, #60H, DONE
MOV MIN, #00H
MOV A, HOUR
INC A
DA A
MOV HOUR, A
CJNE A, #24H, DONE
MOV HOUR, #00H
DONE: POP ACC
POP PSW ;恢复现场
RETI

Ⅳ 急求:单片机课程设计电子时钟

A方案
--------------------------
外加一颗时钟芯片DS1302(非常准确)。
按键为单片机中断。
--------------------------

1、上电时自动显示时、分、秒;
实现方式:上电时单片机去启动DS1202,然后读取里面的时间值,自动显示时、分、秒;

2、设置一个控制按键,按下按键,则时钟以秒为单位开始计时;
实现方式:将DS1302此时的值暂时保存,最为计时开始的时间。
然后不停地读取DS1302里的新的时间值,
并将新的时间值 - 计时开始的时间 = 已计时数值

3、运行状态下可通过控制按键使时钟暂停,同时显示已计时数值;
实现方式:显示步骤2里的已计时数值。

4、停止状态下(已上电),按下复位按钮,时钟复位(清零),并进入下一次计时状态。
实现方式:计时开始的时间换成当前时间。

B方案
--------------------------
采用单片机内部定时器计时(不准)。
按键为单片机中断。
--------------------------
步骤类似,不用去读DS1302的时间,读自己内部的时间。

Ⅵ 51单片机设计电子时钟。

#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
sbit key1=P3^0;
sbit key2=P3^1;
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar shi,fen,miao,num1 ,num2,num3,num4,num5,num6,num7;
void delayms (uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void miaodisplay (uchar num6,uchar num5)
{
P2=0x00;
P2=0x80;
P1=table[num6];
delayms(5);
P2=0x00;
P2=0x40;
P1=table[num5];
delayms(5);
}
void fendisplay(uchar num4,uchar num3)
{
P2=0x00;
P2=0x10;
P1=table[num4];
delayms(5);
P2=0x00;
P2=0x08;
P1=table[num3];
delayms(5);
}
void shidisplay(uchar num2,uchar num1)
{
P2=0x00;
P2=0x02;
P1=table[num2];
delayms(5);
P2=0x00;
P2=0x01;
P1=table[num1];
delayms(5);
}

void main ()
{
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
ET0=1;
TR0=1;
shi=0;
fen=0;
miao=0;
num7=0;
while (1)
{
num1=shi/10;
num2=shi%10;
num3=fen/10;
num4=fen%10;
num5=miao/10;
num6=miao%10;
miaodisplay(num6,num5);
P2=0x00;
P2=0x20;
P1=0xbf;
delayms(5);
fendisplay(num4,num3);
P2=0x00;
P2=0x04;
P1=0xbf;
delayms(5);
shidisplay(num2,num1);

}
}
void T0_time () interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
num7++;
if(num7==20)
{
num7=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
fen=0;
miao=0;
}
}
}
}
}

Ⅶ 单片机数字时钟课程设计

这个 我正在学单片机,也刚刚做过了这个实验没多久,不过我的是8098单片机,确实是汇编语言。不过我做的仅仅是个电子钟,你可以随时改变你输入的时间然后它就会按时分秒跳动,我做的是24小时制的。不过我没有弄闹钟额……不过也简单,可以弄一个中断申请就ok。话说你的闹钟要求是什么?我记得8098是不能响的,只有一个发光二极管可以亮一亮……
话说能请你把问题补充一下么?我的程序写在纸上,然后我们还要求是要把程序翻译出机器码然后在单片机上实验出结果的。所以我连机器码都翻译了的……实在不知道你们的要求。

原理可以先和你说一下:主程序先是一系列的初始化(中断悬挂的清零和寄存器的设置,堆栈的设置等),然后开启中断,写显示程序(显示程序前要弄好你显示的寄存器以及扫描子程序的地址,还要对十六进制数进行转换变成十进制数,只要做一个除法就行,用十六进制数除以A就能够得出相应的十进制数。)
然后就是你的中断程序了,比如你的中断申请是每10ms申请一次,那你就计数,如果到了100次中断了,那就秒加一,再查看秒是否到60,是则清零让分加一,否则跳到中断程序末端;然后再依次查分和时。最后中断程序的末端还要用一次计时器软件中断申请。再跳回主程序反复运行。可能比较麻烦,我记得我打的草稿就好多张纸呢,后来在16进制向10进制转换的时候还出了个寄存器的问题。
不知道和你程序的要求是否相同= =。

期待你能够补充一下你的问题。

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

#include <reg52.h>

#include<stddef.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',..,''};

* 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!='') && i<16)

{

lcd1602_WriteData(*q);

q++;

i++;

}

break;

case 1:

lcd1602_WriteCmd(0xc0+xaddr);

while(q!=NULL && (*q!='') && i<16)

{

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;x>0;x--)

for(y=110;y>0;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==1&&key_add==0)

{

while(!key_add);

sec++;

if(sec==60)

sec=0;

}

if(flag==1&&key_minus==0)

{

while(!key_minus);

sec--;

if(sec==-1)

sec=59;

}


if(flag==2&&key_add==0)

{

while(!key_add);

min++;

if(min==60)

min=0;

}

if(flag==2&&key_minus==0)

{

while(!key_minus);

min--;

if(min==-1)

min=59;

}


if(flag==3&&key_add==0)

{

while(!key_add);

h++;

if(h==24)

h=0;

}

if(flag==3&&key_minus==0)

{

while(!key_minus);

h--;

if(h==-1)

h=23;

}


if(flag==4&&key_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==4&&key_minus==0)

{

while(!key_minus);

if(date>1)date--;

}


if(flag==5&&key_add==0)

{

while(!key_add);

month++;

if(month==13)

month=1;

}

if(flag==5&&key_minus==0)

{

while(!key_minus);

month--;

if(month==0)

month=12;

}


if(flag==6&&key_add==0)

{

while(!key_add);

year++;

if(year==99)

year=1;

}

if(flag==6&&key_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++;

}

}

}

}

}

}

}

Ⅸ 51单片机做数字电子钟

这么复杂的东西给这么少分 晕死了 你也太小气了吧,分多的话还可能帮你动动脑

阅读全文

与单片机课程设计电子时钟相关的资料

热点内容
gz压缩文件夹 浏览:175
字母h从右往左跑的c语言编程 浏览:127
安卓手机如何拥有苹果手机横条 浏览:765
业余编程语言哪个好学 浏览:137
按照文件夹分个压缩 浏览:104
航空工业出版社单片机原理及应用 浏览:758
如何在电信app上绑定亲情号 浏览:376
安卓的怎么用原相机拍月亮 浏览:805
配音秀为什么显示服务器去配音了 浏览:755
c盘清理压缩旧文件 浏览:325
app怎么交付 浏览:343
图虫app怎么才能转到金币 浏览:175
如何做征文app 浏览:446
用什么app管理斐讯 浏览:169
安卓如何下载宝可梦剑盾 浏览:166
编译器开发属于哪个方向 浏览:940
megawin单片机 浏览:687
以色列加密货币监督 浏览:909
程序员前端现在怎么样 浏览:499
服务器和接口地址ping不通 浏览:557