㈠ 51单片机如何实时显示时间
单片机实时显示时间,可以用ds1302产生时钟,然后计算时钟,并送出结果。
㈡ 用51单片机制作可以显示年月日时分秒的万年历,有电路图和汇编语言程序。
可以,有1602LCD就可以
记得采纳啊
㈢ 51单片机雨滴定时燃气温度的程序
proteus。根据使用手册下载。51单片机是对兼容英特尔8051指令系统的单片机的统称。51单片机广泛应用于家用电器、汽车、工业测控、通信设备中。因为51单片机的指令系统、内部结构相对简单,所以国内许多高校用其进行单片机入门教学。
㈣ 求怎么用51单片机8*8点阵显示出生日快乐四个字有源代码就更好了,求大佬指点!
用51单片机8*8点阵显示出“生日快乐”四个字,这办不到的。至少要用16X16的点阵才能显示出汉字。8*8的点阵只能显示0~9的数字。如果是仿真显示,就用4个8*8的点阵组成一个显示屏,也很简单的。要是实物开发板,那就无法显示了。
仿真的效果如下:
㈤ 51单片机万年历实现24节气有的可以,有的不行,怎么回事
看看数据有无溢出,不同的单片机或者编译平台各数据类型的位宽有所不同。
㈥ 51单片机 制作 日历时钟 用汇编语言 要详细的代码和硬件图示
你好这是基于DS1302日历时钟的单片机汇编程序 51单片机
ORG 0000H
MOV SP,#30H
LOAD EQU P2.0
CLR LOAD
MOV R0,#0FH
MOV R1,#0AH ;亮度
ACALL TRT
MOV R0,#02H
MOV R1,#0BH ;扫描位数
ACALL TRT
MOV R0,#0FFH
MOV R1,#09H ;译码
ACALL TRT
MOV R0,#01H
MOV R1,#0CH
CALL TRT
SETB P1.0
MOV 22H,#00H
;以下为按键扫描输入初值子程序
KEYSET: MOV 73H,#01H ;设温度初值为10度
MOV 74H,#00H
MOV 75H,#00H
CALL DISPLAY
KEY1: CALL KS1 ;调判断有无键按下子程序
JNZ LK1 ;有键按下(A)<>0转消抖延时
AJMP KEY1 ;无键按下返回,等键按下
LK1: CALL DEL10MS ;延时
CALL KS1 ;若有键按下则为真实按下
JNZ KEYI ;键按下(A)<>0转键扫描
AJMP KEY1 ;不是键按下返回
KEYI: JNB ACC.0,KEYR ;加1键未按下,转查减1键
LK2: CALL KS1 ;等待键释放
CALL DEL10MS
JNZ LK2 ;未释放,等待
INC 75H ;末位加1
MOV A,75H
CJNE A,#0AH,PPA
MOV 75H,#00H
INC 74H
MOV A,74H
CJNE A,#0AH,PPA
MOV 74H,#00H
INC 73H
PPA: CALL DISPLAY
AJMP KEY1 ;转再次扫描
KEYR: JNB ACC.1,KEYH ;减1键未按下,转查上限确认键
LK3: CALL KS1
CALL DEL10MS
JNZ LK3
MOV A,75H
CJNE A,#00H,PPC
MOV 75H,#09H
MOV A,74H
CJNE A,#00H,PPD
MOV 74H,#09H
DEC 73H
AJMP PPB
PPD: DEC 74H
AJMP PPB
PPC: DEC 75H
PPB: CALL DISPLAY
AJMP KEY1 ;再次扫描
KEYH: JNB ACC.2,KEYL ;上限键未按下,转查下限确认键
LK4: CALL KS1
CALL DEL10MS
JNZ LK4
MOV A,73H
MOV 70H,A ;保存上限
MOV A,74H
MOV 71H,A
MOV A,75H
MOV 72H,A
AJMP KEY1
;KEYL: JNB ACC.3,KEY1
LK5: CALL KS1
CALL DEL10MS
JNZ LK5
MOV A,73H
MOV 6DH,A ;保存下限
MOV A,74H
MOV 6EH,A
MOV A,75H
MOV 6FH,A
EX_CON: ;CPL P1.3 ;使用仪器测试时用
CALL DS18B20 ;转DS18B20采样子程序
CALL DISPLAY
;以下为后向通道控制部分
CONTROL:MOV A,73H
CJNE A,6DH,NEQA
MOV A,74H
CJNE A,6EH,NEQB
CLR P1.5
CLR P1.6
JMP EX_CON ;样温=下限,返回采样
NEQA: JNC NEQD ;CY=0,即(73H)>(6DH)时转比上限
SETB P1.5
CLR P1.6
JMP EX_CON
NEQB: JNC NEQD
SETB P1.5
CLR P1.6
JMP EX_CON
NEQD: MOV A,73H
CJNE A,70H,NEQE
MOV A,74H
CJNE A,71H,NEQF
CLR P1.5
CLR P1.6
JMP EX_CON ;样温=上限,返回采样
NEQE: JNC NEQH ;CY=0,即(73H)>(70H)时转打开降温开关
CLR P1.5
CLR P1.6
JMP EX_CON
NEQF: JNC NEQH
CLR P1.5
CLR P1.6
JMP EX_CON
NEQH: CLR P1.5
SETB P1.6
JMP EX_CON
KS1: MOV P0,#0FFH
MOV A,P0
CPL A
ANL A,#0FH
RET
DEL10MS:MOV R7,#20
S2: MOV R6,#250
S1: DJNZ R6,S1
DJNZ R7,S2
RET
;以下为显示
DISPLAY:MOV A,73H ;字码
MOV R0,A
MOV R1,#01H ;位置
ACALL TRT
MOV A,74H
MOV R0, A
MOV R1,#02H
ACALL TRT
MOV A,75H
MOV R0,A
MOV R1,#03H
ACALL TRT
RET
;JMP DIS
DS18B20:LCALL RESET ;测试温度探头存在否?
MOV A,#0CCH
LCALL WRITE
MOV A,#44H
LCALL WRITE ;命令字写入探头内
MOV R7,#70D ;延时
CALL DE11
LCALL RESET
MOV A,#0CCH
LCALL WRITE
MOV A,#0BEH
LCALL WRITE
LCALL READ ;读取探头内的温度值
MOV B,A
MOV 21H,A ;保存温度值低位
LCALL READ
MOV 20H,A ;保存温度值高位
LCALL EXCHANG ;温度值B转D并送入显示缓存
RET
RESET:
LA: SETB P1.0 ;复位
NOP
LB: CLR P1.0 ;480US < TS < 960US
MOV R7,#36D
CALL DE11
SETB P1.0 ;60US < T <90US
LC: MOV R7,#6D
CALL DE11
CLR C
ORL C,P1.0
JC LB
LF: MOV R7,#18D ;T > 270
CALL DE11
SETB P1.0
RET
WRITE:
MOV R3,#8
WR1: SETB P1.0
CLR P1.0 ;延时
MOV R4,#2
WR2: DJNZ R4,WR2
RRC A
MOV P1.0,C ;写的数据在线上需延时
MOV R4,#18
WR3: DJNZ R4,WR3
NOP
SETB P1.0
DJNZ R3,WR1
SETB P1.0
RET
READ:
MOV R3,#8
RD1: CLR C
SETB P1.0 ;适当延时
NOP
NOP
CLR P1.0 ;适当延时
NOP
NOP
SETB P1.0 ;延时
MOV R4,#9
RD2: DJNZ R4,RD2
MOV C,P1.0
RRC A
MOV R5,#23
RD3: DJNZ R5,RD3
DJNZ R3,RD1
RET
DELAY: MOV R7,#10
DL2: MOV R6,#200
DL1: MOV R5,#250
DL0: DJNZ R5,DL0
DJNZ R6,DL1
DJNZ R7,DL2
RET
EXCHANG: MOV A,21H
SWAP A
ANL A,#0FH
MOV 24H,A
MOV A,20H
ANL A,#07H
SWAP A
ADD A,24H
MOV B,#10D
DIV AB
MOV 73H,A
MOV 74H,B
MOV A,21H
ANL A,#0FH
mov dptr,#SADDR ;小数部分的转换查表
movc a,@a+dptr
MOV 75H,A
ret
SADDR: DB 00H,1H,02h ; bo_ying address in eeprom 0800h-0A08H
DB 03H,3H,04h ; da_ling address in eeprom 0A10H-0AD3H
DB 04H,05H,06h ;shou_ying address in eeprom 0AE0H-0C25H
DB 06H,7H,08h ; lu_ying address in eeprom 0C30H-0D75H
DB 08H,9H,9h,9H
DELAY15US: ;12MHZ ,15US
DE11: NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R7,DE11
RET
TRT: CLR P2.0 ;LOAD
MOV R2,#08H
MOV A,R1
T_1: CLR P2.2 ;SETB P2.2 ;CLK
RLC A
MOV P2.1,C ;DATA
CALL TDELAY
SETB P2.2 ;CLR P2.2
DJNZ R2,T_1
CALL TDELAY
MOV R2, #08H
MOV A,R0
TT2: CLR P2.2 ;SETB P2.2
RLC A
MOV P2.1,C
CALL TDELAY
SETB P2.2 ;CLR P2.2
DJNZ R2,TT2
SETB P2.0 ;CLR P2.0
RET
TDELAY: MOV R6,#01H
TMS0: MOV R7,#03H
TMS1: DJNZ R7,TMS1
DJNZ R6,TMS0
RET
㈦ 51单片机数字温度计常见故障及解决办法
用51做处理器,外围电路如图,一片双积分转换芯片ICL7135做AD,它的时钟需要125K,用51的ALE经过一片CD4024分频得到。1403提供基准源。另外,一片7660提供7135工作所需要的负压。
为了省电,把所有模拟电路部分电源用一个晶体管管理起来,由P1.0来控制。(上图为示意图,省去了电阻没画)P1.0为地的时候,模拟系统才上电
现在怪现象如下:
仿真机正常运行,烧写芯片后无反应。
仿真正常,说明外围芯片完全正常,电路也没有错误。
经过检查,晶体正常,复位可靠,EA高,程序堆栈都没有溢出,并排除其它一切低级错误的可能。
再编写一程序,
main()
{
while(1) {P1.1=0;}
}
P1.1和VCC间接有一发光管,开机无反应。
后来,发现更奇怪的现象:
拔除CD4024,MC1403,ICL7135,ICL7660中的任何一个,系统就可以正常运行!
百思不得其解,茶饭不思,郁闷了N久
更换全部芯片,如故。
更换ATMEL/PHILIPS/WINBOND的N款单片机,如故。
检查,排除电路故障的可能,
后来又发现,只要上电之前把P1.0对地短路,(也就是模拟部分强加电源),上电,系统正常运行。
但是,如果开机前P1.0不对地短路,上电一定不能运行,此后即使再把P1.0对地接,也不行。
顺这个思路,应该是和模拟部分有关……
又是郁闷N久,之后,无意间翻看CD4024内部图,茅塞顿开……
CD4024等TTL/CMOS逻辑芯片,为了防止静电或错误的IO电平,内部都有保护电路
51单片机故障分析一个 - cryinrain_cug - cryinrain_cug的博客
如图2,每个IO口都有如图的2个二极管,集成在芯片内部。保证IO口电压在-0.6~5.6V之间
复位的过程中,全部IO为高,P1.0和ALE当然也是高。这样模拟部分不上电。
那么,ALE的输出角就等效于通过一个二极管向这四块模拟芯片供电!!!(如图)
ALE的输出能力不强,自然,ALE就被拉低了。
在查看51的手册,ALE和/PROG脚是复用的!!
在复位过程中,ALE如果为低,芯片进入编程状态!!!
也就是说,我的系统在上电复位的过程中就进入了PROG编程模式,难怪一条语句都不能执行
那么,也很好解释为什么四个芯片中拔掉一个就能正常工作了,因为负载轻了,ALE可能还没有被拉到2.5V以下,所以正常复位进入程序。
解决的办法:ALE接2K的上拉,再通过47K电阻接到Cd4024上,上电,一切正常!
结论:单片机编程模式/ISP模式是通过用户很不容易出现的一个时序来启动的,在一些特殊应用时要小心避开这些非用户代码模式。
㈧ 求只用51单片机设计的能显示时分秒且能校时的C语言程序最好详解哦
//at89c2051单片机 运用在(sft ck301)时钟上的程序 12m晶振
//省去其他的功能,只有显示时间功能,是24小时显示制。
//三个按键的设置安排由左向右是
//k1:设置秒分时退出的循环按钮 P3.5初始高电平
//k2; 数字上加循环 P3.4初始高电平
//k3: 数字下减循环 P3.2 初始高电平
//
//蜂鸣器 P3.7 初始高电平 低电平触发
//
//数码管
//段码端口P1
//位码分别是 P3.0十万位 P3.4万位 P3.2千位 P3.5百位P3.3十位 P3.1个位
//原11版本的计数器设置TMOD设置为0X20是错误的,应该是0x10,已经更正
//且装填的数字是50000累加中断数字是20都已经更正
#include<reg51.h> //包含单片机寄存器的头文件
unsigned char code Tab[]={0x81,0xe7,0x92,0xa2,0xe4,0xa8,0x88,0xe3,0x80,0xa0,0xff};//数码管段码///P1口
////////////////////////----0----1----2---3-----4----5----6----7----8---9---空
unsigned int m; //// 秒
unsigned int f;//// 分
unsigned int s; //// 时
unsigned int a;//////主秒a
unsigned int b;//////主秒 b
unsigned int c; //////调节循环 0//显示 1//调分 2//调时
sbit p30=P3^0;
sbit p31=P3^1;
sbit p32=P3^2;
sbit p33=P3^3;
sbit p34=P3^4;
sbit p35=P3^5;
sbit p37=P3^7;
sbit p17=P1^7;
/****************************************************************
函数名 delay(); 函数功能:延时一段时间 始
*****************************************************************/
void delay(void) //两个void意思分别为无需返回值,没有参数传递
{
unsigned int i; //定义无符号整数,最大取值范围65535
for(i=0;i<10;i++) //做20000次空循环
; //什么也不做,等待一个机器周期
}
/****************************************************************
函数名 delay(); 函数功能:延时一段时间 终
*****************************************************************/
/****************************************************************
函数名 xianshi(); 函数功能:显示整个时钟 始
*****************************************************************/
void xianshi() //两个void意思分别为无需返回值,没有参数传递
{
////////// 个位
p33=0;
p31=1;
p32=1;
p35=1;
p30=1;
p34=1;
P1=Tab[m%10];
delay();
//////////
p33=1;//////消除鬼影语句
delay();//////消除鬼影语句
P1=0xff;//////消除鬼影语句
////////// 十位
p33=1;
p31=0;
p32=1;
p35=1;
p30=1;
p34=1;
P1=Tab[m/10];
delay();
//////////
p31=1;//////消除鬼影语句
delay();//////消除鬼影语句
P1=0xff;//////消除鬼影语句
////////// 百位
p33=1;
p31=1;
p32=0;
p35=1;
p30=1;
p34=1;
P1=Tab[f%10];
delay();
//////////
p32=1;//////消除鬼影语句
delay();//////消除鬼影语句
P1=0xff;//////消除鬼影语句
////////// 千位
p33=1;
p31=1;
p32=1;
p35=0;
p30=1;
p34=1;
P1=Tab[f/10];
delay();
//////////
p35=1;//////消除鬼影语句
delay();//////消除鬼影语句
P1=0xff;//////消除鬼影语句
////////// 万位
p33=1;
p31=1;
p32=1;
p35=1;
p30=0;
p34=1;
P1=Tab[s%10];
delay();
//////////
p30=1;//////消除鬼影语句
delay();//////消除鬼影语句
P1=0xff;//////消除鬼影语句
//////////十万位
p33=1;
p31=1;
p32=1;
p35=1;
p30=1;
p34=0;
P1=Tab[s/10];
delay();
//////////
p34=1;//////消除鬼影语句
delay();//////消除鬼影语句
P1=0xff;//////消除鬼影语句
p33=1;
p31=1;
p32=1;
p35=1;
p30=1;
p34=1;
}
/****************************************************************
函数名 xianshi(); 函数功能:显示整个时钟 终
*****************************************************************/
/****************************************************************
函数名 xianshifen(); 函数功能:显示分 始
*****************************************************************/
void xianshifen() //两个void意思分别为无需返回值,没有参数传递
{
////////// 百位
p33=1;
p31=1;
p32=0;
p35=1;
p30=1;
p34=1;
P1=Tab[f%10];
delay();
//////////
p32=1;//////消除鬼影语句
delay();//////消除鬼影语句
P1=0xff;//////消除鬼影语句
////////// 千位
p33=1;
p31=1;
p32=1;
p35=0;
p30=1;
p34=1;
P1=Tab[f/10];
delay();
//////////
p35=1;//////消除鬼影语句
delay();//////消除鬼影语句
P1=0xff;//////消除鬼影语句
p33=1;
p31=1;
p32=1;
p35=1;
p30=1;
p34=1;
}
/****************************************************************
函数名 xianshifen(); 函数功能:显示分 终
*****************************************************************/
/****************************************************************
函数名 xianshishi(); 函数功能:显示时 始
*****************************************************************/
void xianshishi() //两个void意思分别为无需返回值,没有参数传递
{
////////// 万位
p33=1;
p31=1;
p32=1;
p35=1;
p30=0;
p34=1;
P1=Tab[s%10];
delay();
//////////
p30=1;//////消除鬼影语句
delay();//////消除鬼影语句
P1=0xff;//////消除鬼影语句
//////////十万位
p33=1;
p31=1;
p32=1;
p35=1;
p30=1;
p34=0;
P1=Tab[s/10];
delay();
//////////
p34=1;//////消除鬼影语句
delay();//////消除鬼影语句
P1=0xff;//////消除鬼影语句
p33=1;
p31=1;
p32=1;
p35=1;
p30=1;
p34=1;
}
/****************************************************************
函数名 xianshishi(); 函数功能:显示时 终
*****************************************************************/
/****************************************************************
函数名 leijijiamiao(); 函数功能:利用中断累计加秒 始
*****************************************************************/
void leijijiamiao(void) //两个void意思分别为无需返回值,没有参数传递
{
if(b==1)
{
b=0;
m++;
p17=~p17; ////p17取反实现冒号闪烁
if(m==60)
{
m=0;
f++;
}
if(f==60)
{
f=0;
s++;
}
if(s==24)
{
s=0;
}
}
}
/****************************************************************
函数名 leijijiamiao(); 函数功能:利用中断累计加秒 终
*****************************************************************/
/*******************************************************************
函数功能:主函数 (C语言规定必须有也只能有1个主函数) 始
********************************************************************/
void main()
{ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/******************************************************************
定义初始值
******************************************************************/
p37=1;////蜂鸣器不发声
f=0;
m=0;
s=0;
c=0;
p17=1;
/******************************************************************
定义初始值
******************************************************************/
/***********************************************************************
定时计数器的操作 作为定时器使用1秒计时 始
************************************************************************/
EA=1; //开总中断
ET1=1; //定时器T1中断允许
TR1=1;//启动定时计数器T1
TMOD=0x10;////0001 0000 设置定时计数器T1为定时使用,并使用16位定时器
TH1=(65536-50000)/256;//////装填定时计数器T1高8位//定时5000次的时间是0.05秒。得循环20次才是1秒
TL1=(65536-50000)%256;//////装填定时技数器T1底8位//定时5000次的时间是0.05秒。得循环20次才是1秒
TF1=0;/////////定时计数器1的溢出位清零
/***********************************************************************
定时计数器的操作 作为定时器使用1秒计时 终
************************************************************************/
while(1) ////////////////////////////////////主循环
{////////////////////////////////////主循环 始
//////////////////////////////////////////////////////////显示 循环
while(c==0)
{
xianshi();
leijijiamiao();
if(p35==0)
{
delay();
delay();
delay();
delay();
if(p35==0)
{
c++;
while(!p35)
{
;
}
}
}
}
//////////////////////////////////////////////////////////显示 循环
//////////////////////////////////////////////////////////调分 循环
while(c==1)
{
xianshifen();
////////////////// 调分 上加按钮判断
if(p34==0)
{
delay();
delay();
delay();
delay();
if(p34==0)
{
f++;
if(f==60)
{
f=0;
}
while(!p34)
{
;
}
}
}
/////////////////// 调分 上加按钮判断
/////////////////// 调分 下减按钮判断
if(p32==0)
{
delay();
delay();
delay();
delay();
if(p32==0)
{
if(f==00)
{
f=60;
}
f--;
while(!p32)
{
;
}
}
}
///////////////////调分 下减按钮判断
///////////////////循环按钮判断
if(p35==0)
{
delay();
delay();
delay();
delay();
if(p35==0)
{
c++;
while(!p35)
{
;
}
}
}
///////////////////循环按钮判断
}
//////////////////////////////////////////////////////////调分 循环
//////////////////////////////////////////////////////////调时 循环
while(c==2)
{
xianshishi();
///////////////////调时 上加按钮判断
if(p34==0)
{
delay();
delay();
delay();
delay();
if(p34==0)
{
s++;
if(s==24)
{
s=0;
}
while(!p34)
{
;
}
}
}
///////////////////调时 上加按钮判断
///////////////////调时 下减按钮判断
if(p32==0)
{
delay();
delay();
delay();
delay();
if(p32==0)
{
if(s==00)
{
s=24;
}
s--;
while(!p32)
{
;
}
}
}
///////////////////调时 下减按钮判断
///////////////////循环按钮判断
if(p35==0)
{
delay();
delay();
delay();
delay();
if(p35==0)
{
c=0;
while(!p35)
{
;
}
}
}
///////////////////循环按钮判断
}
//////////////////////////////////////////////////////////调时 循环
}////////////////////////////////////主循环 终
} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*******************************************************************
函数功能:主函数 (C语言规定必须有也只能有1个主函数) 终
********************************************************************/
/*****************************************************************************************************************
中断服务函数;定时器T1中断服务函数//当定时计数器T1有溢出时则执行本函数,执行完本函数后接着执行之前的运行的程序
******************************************************************************************************************/
void Time1(void) interrupt 3 using 0
//interrupt 3 理解是中断函数修饰后面的数字取值由0--31,
//目前数字意义是0--外部中断0、1--定时计数器T0、2--外中断1、3--定时计数器T1、4--串行中断、5--定时计数器T2(其他数值保留)
//using 0 理解是工作寄存器组,可以忽略 通常取0
{
TF1=0;
TH1=(65536-50000)/256;//////装填定时计数器T1高8位//定时5000次的时间是0.05秒。得循环20次才是1秒
TL1=(65536-50000)%256;//////装填定时技数器T1底8位//定时5000次的时间是0.05秒。得循环20次才是1秒
a++;
if(a==20)////检测a的数值为3713后给b加1///当定时器有3713次溢出时最接近1秒计时(20121018号由原来的3713改为3715)之前时钟偏快
{
a=0;
b=1;
}
}
/*****************************************************************************************************************
中断服务函数;定时器T1中断服务函数//当定时计数器T1有溢出时则执行本函数,执行完本函数后接着执行之前的运行的程序
******************************************************************************************************************/
㈨ 关于51单片机哪款适合做电子时钟
STC8952足够了,网上有现成的万年历51,包括时间,日期,(阴历)节气都有,当然闹钟也是有的,代码也非常小,你不一定要去看那个代码,
实际上就是告诉你写出这个程序代码不需要很大的空间,52完全是够了,速度方面52足够强了,再去买ds1302芯片,其它的也可以,不买都行,上面万年历那个就可以实现这个功能,+显示屏
淘宝上大量都可以选择。
㈩ 51单片机电子钟程序数码管显示
#include<reg51.h>
#define uchar unsigned char
sbit la=P2^6;
sbit wela=P2^7;
sbit beep=P2^3;
unsigned char j,k,a1,a0,b1,b0,c1,c0,s,f,m,key=10,temp,qq;
uchar shi20,shi10,fen20,fen10,miao20,miao10,new,ok=1,wei;
unsigned int pp;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay(unsigned char i)
{
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void display(uchar shi2,uchar shi1,uchar fen2,uchar fen1,uchar miao2,uchar miao1)
{
la=0;
P0=table[shi2];
la=1;
la=0;
wela=0;
P0=0xfe;
wela=1;
wela=0;
delay(5);
P0=table[shi1]|0x80;
la=1;
la=0;
P0=0xfd;
wela=1;
wela=0;
delay(5);
P0=table[fen2];
la=1;
la=0;
P0=0xfb;
wela=1;
wela=0;
delay(5);
P0=table[fen1]|0x80;
la=1;
la=0;
P0=0xf7;
wela=1;
wela=0;
delay(5);
P0=table[miao2];
la=1;
la=0;
P0=0xef;
wela=1;
wela=0;
delay(5);
P0=table[miao1];
la=1;
la=0;
P0=0xdf;
wela=1;
wela=0;
delay(5);
}
void keyscan0()
{
P3=0xfb;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xbb:
ok=0;
break;
case 0x7b:
ok=1;
break;
}
}
}
}
void keyscan()
{
{
P3=0xfe;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:
key=0;
wei++;
break;
case 0xde:
key=1;
wei++;
break;
case 0xbe:
key=2;
wei++;
break;
case 0x7e:
key=3;
wei++;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
}
}
P3=0xfd;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:
key=4;
wei++;
break;
case 0xdd:
key=5;
wei++;
break;
case 0xbd:
key=6;
wei++;
break;
case 0x7d:
key=7;
wei++;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
}
}
P3=0xfb;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:
key=8;
wei++;
break;
case 0xdb:
key=9;
wei++;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
}
}
}
}
void main()
{
TMOD=0x01;
TH0=(65536-46080)/256;// 由于晶振为11.0592,故所记次数应为46080,计时器每隔50000微秒发起一次中断。
TL0=(65536-46080)%256;//46080的来历,为50000*11.0592/12
ET0=1;
EA=1;
while(1)
{ keyscan0();
if(ok==1)
{ TR0=1;
wei=0;
if(pp==20)
{ pp=0;
m++;
if(m==60)
{
m=0;
f++;
if(f==60)
{
f=0;
s++;
if(s==24) //为24h一个循环,若要12h,只需在此改为12即可。
{
s=0;
}
}
}
}
a0=s%10;
a1=s/10;
b0=f%10;
b1=f/10;
c0=m%10;
c1=m/10;
display(a1,a0,b1,b0,c1,c0);
}
else
{ TR0=0;
keyscan();
if(key!=10)
{
switch(wei)
{
case 1: if(key<3) //小时最高位为2
a1=key;
else
wei--;
break;
case 2: if(a1==1|a1==0)
a0=key;
else
if(key<5)
a0=key; //当小时最高位为2时,低位最高为4
break;
case 3: if(key<7) //分钟最高位为6
b1=key;
else
wei--;
break;
case 4: b0=key; break;
case 5: if(key<7) //秒最高位为6
c1=key;
else
wei--;
break;
case 6: c0=key; break;
}
key=10;
}
m=c1*10+c0;
f=b1*10+b0;
s=a1*10+a0;
display(a1,a0,b1,b0,c1,c0);
}
}
}
void time0() interrupt 1
{ TH0=(65536-46080)/256;
TL0=(65536-46080)%256;
pp++;
}