1. 基于单片机多功能数字钟
带万年历的LCD显示多功能数字钟
程序清单:
;SMC1602接口程序(MCS51模拟口线方式)
;***************************************************************************
;连线图:*LCM---8031**LCM---8031**LCM------------8031*
;*DB0---P0.0**DB4---P0.4**RS-------------P2.0*
;*DB1---P0.1**DB5---P0.5**RW-------------P2.1*
;*DB2---P0.2**DB6---P0.6**E--------------P2.2*
;*DB3---P0.3**DB7---P0.7**VLCD接10K可调电阻到GND*
;注:8051的晶振频率为11.0592MHzR0设置数据存放S8为设置键S7为加键S4为确认键
;**************************************************************************
;P0口液晶显示
;P2.4位选键P2.3加一键P2.2返回键及报时功能键闹钟设置P2.0控制显示键
;寄存器clrrs0setbrs1R0R4R5在按键中用到延时中用到SETBRS0SETBRS1的R0R1R2
;SETBRS0CLRRS1显示中用到CLRRS0CLRRS1在闹钟调整子程序中用到R1
;*********************************************************************
;
;报时功能P2.6和闹钟功能P2.5闹钟调整时间功能已经可以设置显示的切换方式变了再关闭的情况下一切正常运行
;*****************************
RSPINBITP1.2
RWPINBITP1.1
EPINBITP1.0
WEIXUANBITP2.4;位选键设置键
JIAJIANBITP2.3;加一键
JIANJIANBITP2.2;减一键
FANHUIBITP2.1;返回键
NZKGBITP2.0;闹钟设置键
SECONTLEQU30H;秒
SECONTHEQU31H;秒
MAOHAOLEQU32H;:
MINIUTLEQU33H;分
MINIUTHEQU34H;分
MAOHAOHEQU35H;:
HOURLEQU36H;时
HOURHEQU37H;时
;*****************************日期部分***************************
DAYLEQU40H;日个
DAYHEQU41H;日十
HENLEQU42H;-
MONTHLEQU43H;yue
MONTHHEQU44H;yue
HENHEQU45H;-
YEAROEQU46H;年
YEARTEQU47H
YEARSEQU48H
YEARFEQU49H
TEMPEQU50H;用做存储单元显示子程序(DISPLAY)里用到
BIJIAOEQU51H;加一子程序(JIAYI)中用到
ZDRQOEQU55H;中断加一程序中用到
ZDRQTEQU56H;中断加一程序中用到
ZDRQSEQU57H;中断加一程序中用到
ZDRQFEQU58H;中断加一程序中用到
DIZHIEQU59H;键盘(JIANPAN)子程序里用到
NZBZBIT60H;定时标志位在(闹钟开关部分)
;38H到3FH没用到
BSCSBZBIT39H;报时次数转换标志(BSCS)里用到
BSCSCCEQU3AH;报时次数存储(BSCS)里用到
ZDBSBZBIT3BH;整点报时标志(SSBS)里用到
ZMBSBZBIT3CH;整秒闪烁标志(SSBS)里用到
BSKGBZBIT3DH;报时开启标志(BSKG)里用到
XKQHBZBIT3EH;显示开启关闭标志(XIANKONG)里用到
ORG0000H
AJMPMAIN
ORG000BH
AJMPZD
ORG0030H
MAIN:MOVSP,#60H;给堆栈指针赋初值
MOV30H,#05H;秒
MOV31H,#05H;秒
MOV32H,#3AH;:
MOV33H,#09H;分
MOV34H,#05H;分
MOV35H,#3AH;:
MOV36H,#03H;时
MOV37H,#01H;时
;*****************************日期部分***************************
MOV40H,#09H;日个
MOV41H,#02H;日十
MOV42H,#2DH;-
MOV43H,#09H;yue
MOV44H,#00H;yue
MOV45H,#2DH;-
MOV46H,#09H;年
MOV47H,#09H
MOV48H,#09H
MOV49H,#02H
CLRP2.5;闹钟
CLRP2.6;整点报时
MOV03H,#00H;闹钟分个位
MOV04H,#00H;闹钟分十位
MOV06H,#04H;闹钟时个位
MOV07H,#01H;闹钟时十位
;CLRP1.5
;CLRP1.4
MOVB,#20
MOVTMOD,#01H;定时器工作方式1
MOVTH0,#4CH
MOVTL0,#08H
SETBET0;允许T0中断
SETBEA;总中断开放
LCALLLCDRESET;初始化LCD
LCALLDISPSTART;调用显示初始状态
SETBTR0;开启定时器
CLRNZBZ;闹钟开启关闭标志
CLRBSKGBZ;报时开启关闭标志
CLRXKQHBZ;显示开启关闭标志
LOOP:LCALLJIANPAN;按键子程序
LCALLDISPLAY;显示子程序
LCALLNZBF;NAOZHONGBUFENG
LCALLNZBJ;NAOZHONGBIJIAO
LCALLBSKG;BAOSHIKAIGUAN
LCALLBSCS;BAOSHICISHU
LCALLSSBS;闪烁报时
SJMPLOOP
;==============================中断加一程序===================================
ZD:PUSHACC
MOVTH0,#4CH
MOVTL0,#08H
DJNZB,ZDEND
MOVB,#20
INCSECONTL
SETBZMBSBZ
MOVA,SECONTL
CJNEA,#0AH,ZDEND
MOVSECONTL,#00H
INCSECONTH
MOVA,SECONTH
CJNEA,#06H,ZDEND
MOVSECONTH,#00H
INCMINIUTL
MOVA,MINIUTL
CJNEA,#0AH,ZDEND
MOVMINIUTL,#00H
INCMINIUTH
MOVA,MINIUTH
CJNEA,#06H,ZDEND
MOVMINIUTH,#00H
INCHOURL
SETBBSCSBZ
SETBZDBSBZ
MOVA,HOURL;24小时的判断
CJNEA,#04H,ZDF
MOVA,HOURH
CJNEA,#02H,ZDEND
MOVHOURL,#00H
MOVHOURH,#00H
LCALLZDRQ
SJMPZDEND
ZDF:CJNEA,#0AH,ZDEND
MOVHOURL,#00H
INCHOURH
ZDEND:POPACC
RETI
;日期部分
ZDRQ:PUSHACC
INCDAYL
;判断天数28,30,31部分
MOVA,MONTHH;用于判断月份时为31天30天28天
CJNEA,#01H,LL
MOV55H,#0AH;存放月份的十位转化为个位是0AH
MOVA,MONTHL
ADDA,55H;月分高低相加用于查表
SJMPLL3
LL:MOVA,MONTHL
ADDA,MONTHH
LL3:MOV56H,A;存放相加后的月份数据
MOVDPTR,#TAB5
MOVCA,@A+DPTR;查十位和天数的十位比较
MOV57H,A
MOVA,56H
MOVDPTR,#TAB6;查个位和天数的个位比较
MOVCA,@A+DPTR
MOV58H,A
MOVA,DAYH
CJNEA,57H,LL2
MOVA,DAYL
CJNEA,58H,LL2
MOVDAYH,#00H
MOVDAYL,#01H
SJMPLL4
LL2:MOVA,DAYL
CJNEA,#0AH,ZDRQEND
MOVDAYL,#00H
INCDAYH
MOVA,DAYH;比较天数是否要进位
CJNEA,57H,ZDRQEND
MOVA,DAYL
CJNEA,58H,ZDRQEND
MOVDAYH,#00H
MOVDAYL,#01H
;月份和年份
LL4:INCMONTHL
MOVA,MONTHL
CJNEA,#03H,ZDRQ1;用于判断月份时为12月时进位
MOVA,MONTHH
CJNEA,#01H,ZDRQ1
MOVMONTHL,#01H;天数符合要求
MOVMONTHH,#00H
SJMPZDRQ2
ZDRQ1:CJNEA,#0AH,ZDRQEND
MOVMONTHL,#00H
INCMONTHH
SJMPZDRQEND
ZDRQ2:INCYEARO;年的加一
MOVA,YEARO
CJNEA,#0AH,ZDRQEND
MOVYEARO,#00H
INCYEART;年的进位
MOVA,YEART
CJNEA,#0AH,ZDRQEND
MOVYEART,#00H
INCYEARS
MOVA,YEARS
CJNEA,#0AH,ZDRQEND
MOVYEARS,#00H
INCYEARF
MOVA,YEARF
CJNEA,#0AH,ZDRQEND
MOVYEARF,#00H
ZDRQEND:
POPACC
RET
;液晶初始化
;========================初始化程序=======================================
LCDRESET:;初始化程序
LCALLDELAY5MS;延时15MS
LCALLDELAY5MS
LCALLDELAY5MS
MOVA,#38H;显示模式设置(不检测忙信号)
LCALLLCDWCN;共三次
LCALLDELAY5MS
MOVA,#38H
LCALLLCDWCN
LCALLDELAY5MS
MOVA,#38H
LCALLLCDWCN
MOVA,#38H;显示模式设置(以后均检测忙信号)
LCALLLCDWC
MOVA,#08H;显示关闭
LCALLLCDWC
MOVA,#01H;显示清屏
LCALLLCDWC
MOVA,#06H;显示光标移动设置
LCALLLCDWC
MOVA,#0CH;显示开及光标设置
LCALLLCDWC
RET
;==============================写指令===================================
LCDWC:;送控制字子程序(检测忙信号)
LCALLWAITIDLE
;******写指令*******;送控制字子程序(不检测忙信号)
LCDWCN:CLRRSPIN;RS=0RW=0E=高脉冲
CLRRWPIN
MOVP0,A
SETBEPIN;(
NOP;给高电平脉冲
CLREPIN;)
RET
;==========================写数据=======================================
LCDWD:;写字符子程序
LCALLWAITIDLE
SETBRSPIN;RS=1RW=0E=高脉冲
CLRRWPIN
MOVP0,A
SETBEPIN
NOP
CLREPIN
RET
;===============================等待控制器空闲==================================
WAITIDLE:
PUSHACC;正常读写操作之前必须检测LCD控制器状态
MOVP0,#0FFH
lcallDELAY5MS;666666666666666666666666
CLRRSPIN;RS=0RW=1E=高电平
SETBRWPIN
SETBEPIN
lcallDELAY5MS;98
WTD_PA:NOP;DB7:0LCD控制器空闲
JBP0.7,WTD_PA;1LCD控制器忙
CLREPIN
POPACC
RET
;***********************初始状态子程序*******************************
DISPSTART:;显示初始状态子程序
PUSHACC
MOVA,#80H
LCALLLCDWC
MOVDPTR,#TAB;显示字符
DISP1:CLRA
MOVCA,@A+DPTR
JZDISP2
LCALLLCDWD
INCDPTR
SJMPDISP1
DISP2:MOVA,#0C0H
LCALLLCDWC
MOVDPTR,#TAB1
DISP3:CLRA
MOVCA,@A+DPTR
JZDISP_END
LCALLLCDWD
INCDPTR
SJMPDISP3
DISP_END:
POPACC
RET
;==========================显示子程序=======================================
DISPLAY:PUSHPSW
PUSHACC
SETBRS0
CLRRS1
MOVA,#85H
LCALLLCDWC
MOVR1,#38H;第一行显示数据存储单元的启始地址
MOVTEMP,#30H;第一行显示数据存储单元的结束地址
MOVR6,#2
PLAY:DECR1
CJNER1,#32H,PLY;判断是否为冒号位
MOVA,MAOHAOL;是者送冒号的ACSI码
SJMPPLAY1
PLY:CJNER1,#35H,PLY1
MOVA,MAOHAOH
SJMPPLAY1
PLY1:CJNER1,#42H,PLY2;判断是否为横杠的位置
MOVA,HENL;是者送横杠的ACSI码
SJMPPLAY1
PLY2:CJNER1,#45H,PLY3
MOVA,HENH
SJMPPLAY1
PLY3:MOVA,@R1;用查表法送要显示的数据
MOVDPTR,#TAB2
MOVCA,@A+DPTR
PLAY1:LCALLLCDWD
MOVA,R1
CJNEA,TEMP,PLAY;判断第一行是否显示好了
MOVA,#0C5H
LCALLLCDWC
MOVR1,#4AH;第二行显示数据存储单元的启始地址
MOVTEMP,#40H;第二行的结束地址
DJNZR6,PLAY;R6为0时两行显示结束
POPACC
POPPSW
RET
;************************按键子程序************************
JIANPAN:clrrs0;键盘子程序
setbrs1;键盘子程序
JBWEIXUAN,JIAN_ZEND;设置键的判断
LCALLDELAY5MS
JBWEIXUAN,JIAN_ZEND
PUSHACC
JNBWEIXUAN,$
;MOVA,#0FH;开启光标闪烁设置
;LCALLLCDWCN
fah:JNBNZBZ,JPNZSJ;为“1”闹钟为“0”时钟
LCALLJPXS
MOVR4,#86H;闹钟设定时间R4存放显示位地址
MOVR5,#2;闹钟设定时间第一行第二行•••••位置改变次数
MOVDIZHI,#8CH;闹钟设定时间第一行结束地址
MOVR0,#06H
SJMPGIVED
JPNZSJ:CLRTR0
MOVR4,#86H;R4存放显示位地址
MOVR5,#2;第一行第二行•••••位置改变次数
MOVDIZHI,#8DH;第一行结束地址
MOVR0,#36H
GIVED:MOVA,#0FH;开启光标闪烁设置
LCALLLCDWCN
MOVA,R4
LCALLLCDWC
UPONE:JBFANHUI,UPtwo;返回键的判断
LCALLDELAY5MS
JBFANHUI,UPtwo
JNBFANHUI,$
SJMPGOBACK
JIAN_ZEND:SJMPJIAN_END;中继跳转
UPtwo:JBJIAJIAN,IAM;加一键的判断
LCALLDELAY5MS
JBJIAJIAN,IAM
JNBJIAJIAN,$
LCALLJIAYI;调用按键加一子程序
;MOVA,#0FH;开启光标闪烁设置
;LCALLLCDWCN
IAM:JBJIANJIAN,IAM22;减一键的判断
LCALLDELAY5MS
JBJIANJIAN,IAM22
JNBJIANJIAN,$
LCALLJIANYI;调用按键减一子程序
AJMPGIVED
IAM22:JBWEIXUAN,UPONE;位选键的判断
LCALLDELAY5MS
JBWEIXUAN,UPONE
JNBWEIXUAN,$
DECR0
INCR4
LCALLJIAN;调用位选比较程序
CJNEr4,#88H,JJ11
DECR0
INCR4
SJMPJJ22
JJ11:CJNEr4,#8BH,JJ22
DECR0
INCR4
JJ22:MOVA,R4
CJNEA,DIZHI,GIVED
JBNZBZ,fah;为“1”闹钟为“0”时钟
MOVR4,#0C5H
MOVDIZHI,#0CFH
MOVR0,#49H
DJNZR5,GIVED
LJMPfah
GOBACK:MOVA,#0CH;关闭光标闪烁设置
LCALLLCDWCN
POPACC
JIAN_END:
SETBTR0
RET
;111111
;1111
JPXS:MOVA,#85H
LCALLLCDWC
MOVR1,#08H;第一行显示数据存储单元的启始地址
JPXS_LL:DECR1
CJNER1,#05H,JPXS_LP
MOVA,#3AH
SJMPJPXS_LY
JPXS_LP:MOVA,@R1;用查表法送要显示的数据
MOVDPTR,#TAB2
MOVCA,@A+DPTR
JPXS_LY:LCALLLCDWD
CJNER1,#03H,JPXS_LL
RET
;
;
;************************位选比较控制程序************************
;在调整时间时这几位是符号冒号和横杠的数据
;在这几位时跳过到下一位
JIAN:CJNER4,#87H,JIAN5
DECR0
INCR4
SJMPJIANEND
JIAN5:CJNER4,#8AH,JIAN1
DECR0
INCR4
SJMPJIANEND
JIAN1:CJNER4,#0C9H,JIAN2
DECR0
INCR4
SJMPJIANEND
JIAN2:CJNER4,#0CCH,JIANEND
DECR0
INCR4
JIANEND:RET
;************************按键加一子程序********************
JIAYI:INC@R0
CJNE@R0,#0AH,JIAYI_END
MOV@R0,#0
CJNER4,#86H,JIAYI55
SJMPJIAYI33
JIAYI55:CJNEr4,#89H,JIAYI11
SJMPJIAYI33
JIAYI11:CJNEr4,#8CH,JIAYI22
SJMPJIAYI33
JIAYI22:CJNER0,#30H,JIAYI_END
JIAYI33:INCR0
INC@R0
CJNE@R0,#06H,JIAYI44
MOV@R0,#0
JIAYI44:DECR0
JIAYI_END:MOVA,#0CH;开启光标闪烁设置
LCALLLCDWCN
JNBNZBZ,JIAYI88;为“1”闹钟为“0”时钟
LCALLJPXS
SJMPJIAYI99
JIAYI88:LCALLDISPLAY;显示子程序
JIAYI99:RET
;%%%%%%%%%%%%%%%%%%减一%%%%%%%%%%%%%%%%%%%%%%%%
JIANYI:DEC@R0
CJNE@R0,#00H,JIANYI_END
MOV@R0,#9
CJNER4,#86H,JIANYI55
SJMPJIANYI33
JIANYI55:CJNEr4,#89H,JIANYI11
SJMPJIANYI33
JIANYI11:CJNEr4,#8CH,JIANYI22
SJMPJIANYI33
JIANYI22:CJNER0,#30H,JIANYI_END
JIANYI33:INCR0
DEC@R0
CJNE@R0,#0FFH,JIANYI44
MOV@R0,#5
JIANYI44:DECR0
JIANYI_END:MOVA,#0CH;开启光标闪烁设置
LCALLLCDWCN
JNBNZBZ,JIANYI88;为“1”闹钟为“0”时钟
LCALLJPXS
SJMPJIANYI99
JIANYI88:LCALLDISPLAY;显示子程序
JIANYI99:RET
;******************************闹钟开关部分************************
NZBF:JBNZKG,NZBF_END
LCALLDELAY5MS
JBNZKG,NZBF_END
JNBNZKG,$
CPLNZBZ
JBNZBZ,NZBF_LL
MOVA,#01H;显示清屏
LCALLLCDWC
CLRP2.5
LCALLDISPSTART;调用显示初始状态
LCALLDISPLAY;调用显示初始状态
JBBSKGBZ,NZBF_LP;|
SJMPNZBF_END;|
NZBF_LP:MOVA,#8FH;报时标志显示位置;|
LCALLLCDWC;|保护报时标志在清屏是不被误清
MOVA,#25H;显示报时标志;|
LCALLLCDWD;|
SJMPNZBF_END;|
NZBF_LL:MOVA,#8EH;闹钟标志显示位置
LCALLLCDWC
MOVA,#26H;显示闹钟标志
LCALLLCDWD
NZBF_END:RET
;******************************闹钟比较部分************************
NZBJ:JBNZBZ,NZBJ_LL
SJMPNZBJ_END
NZBJ_LL:MOVA,07H
CJNEA,37H,NZBJ_END
MOVA,06H
CJNEA,36H,NZBJ_END
MOVA,04H
CJNEA,34H,NZBJ_END
MOVA,03H
CJNEA,33H,NZBJ_END
SETBP2.5
NZBJ_END:RET
;***************报时开关********************
BSKG:JBFANHUI,BSKG_END
LCALLDELAY5MS
JBFANHUI,BSKG_END
JNBFANHUI,$
CPLBSKGBZ
JBBSKGBZ,BSKG_LL
MOVA,#01H;显示清屏
LCALLLCDWC
CLRP2.6
LCALLDISPSTART;调用显示初始状态
LCALLDISPLAY;调用显示
JBNZBZ,BSKG_LP;|
SJMPBSKG_END;|
BSKG_LP:MOVA,#8EH;|
LCALLLCDWC;|保护闹钟标志在清屏是不被误清
MOVA,#26H;|
LCALLLCDWD;|
SJMPBSKG_END;|
BSKG_LL:MOVA,#8FH;报时标志显示位置
LCALLLCDWC
MOVA,#25H;显示报时标志
LCALLLCDWD
BSKG_END:RET
;*********************报时次数********************
BSCS:JNBBSKGBZ,BSCS_END
JNBBSCSBZ,BSCS_END
MOVA,37H
CJNEA,#01H,BSCS_LL
MOVA,#0AH
SJMPBSCS_LP
BSCS_LL:CJNEA,#02H,BSCS_LP
MOVA,#14H
BSCS_LP:ADDA,36H
RLA
MOVBSCSCC,A
CLRBSCSBZ
BSCS_END:RET
;**********************闪烁报时********************************
SSBS:JNBBSKGBZ,SSBS_END
JNBZDBSBZ,SSBS_END
JNBZMBSBZ,SSBS_END
CPLP2.6
CPLP2.7
CLRZMBSBZ
DJNZBSCSCC,SSBS_END
CLRZDBSBZ
CLRP2.6
SSBS_END:RET
;************************延时子程序(5MS)************************
DELAY5MS:
PUSHPSW
SETBRS0
SETBRS1
MOVR1,#25;延时子程序(5MS)
DL5_PA:MOVR2,#100
DJNZR2,$
DJNZR1,DL5_PA
POPPSW
RET
TAB:DB"TIME:",00h
TAB1:DB"DATE:",00h
TAB2:DB"01234567891"
TAB3:DB0AH,06H,00H,0AH,06H,00H,0AH,03H;用于比较调整时间时的比较
TAB4:DB0AH,04H,00H,0AH,02H,00H,0AH,0AH,0AH,0AH;用于调整日期时的比较
TAB5:DB00H,03H,02H,03H,03H,03H,03H,03H,03H,03H,03H,03H,03H;用于天数十位比较
TAB6:DB00H,02H,09H,02H,01H,02H,01H,02H,02H,01H,02H,01H,02H;用于天数个位比较
2. 基于单片机的数字时钟设计开题报告
//我这里有一个定时的闹钟,你把蜂鸣器的中断改为LED就行了,可以通过P2^0--P2^3实现秒表的显示和以及调时调分和调节闹钟以及闹钟的开关,有问题可以给我留言QQ834589429
#include<reg52.h>//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
codeunsignedchartab[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//共阴数码管0-9
sbitA1=P2^0;
sbitA2=P2^1;
sbitA3=P2^2;
sbitA4=P2^3;
sbitbeep=P1^4;
unsignedcharShiwan;
unsignedcharWanwei;
unsignedcharQianwei;
unsignedcharBaiwei;
unsignedcharShiwei;//定义十位
unsignedcharGewei,Naoling1,Naoling2,Naoling3,Naoling4;//定义个位
staticunsignedcharhour=12,minute=30,second=0,count=0;
staticunsignedcharalarmhour=12,alarmminute=29,i=0,j=0,k;
/******************************************************************/
/*延时函数*/
/******************************************************************/
voiddelay(unsignedintcnt)
{
while(--cnt);
}
voidxianshi(void)
{
Gewei=tab[second%10];//个位显示处理
Shiwei=tab[second/10];//十位显示值处理
if(second%2==0)
{
Baiwei=tab[minute%10];
Qianwei=tab[minute/10];//千位
}
else
{
Baiwei=(tab[minute%10]|0x80);//百位显示处理:加点的字码
Qianwei=(tab[minute/10]|0x80);
}
if(second%2!=0)
{
Wanwei=tab[hour%10];
Shiwan=tab[hour/10];
}
else
{
Wanwei=(tab[hour%10]|0x80);
Shiwan=(tab[hour/10]|0x80);
}
Naoling1=~tab[alarmhour%10];
Naoling2=~tab[alarmhour/10];
Naoling3=~tab[alarmminute%10];
Naoling4=~tab[alarmminute/10];
}
voidtimer0()interrupt3using1
{
TH1=0x3c;//中断设置初始化
TL1=0xb0;
if(alarmhour==hour&&alarmminute==minute&&j==1)
{
beep=0;
}
}
/******************************************************************/
/*定时器中断函数*/
/******************************************************************/
voidtimer1()interrupt1using0
{
TH0=0xd8;//重新赋值
TL0=0xf0;
count++;
xianshi();
if(count==99)//100x10ms=1S,大致延时时间
{
count=0;
second++;//秒加1
if(second==60)
minute++;
{
if(second==60)
second=0;
{
if(minute==60)
hour++;
{
if(minute==60)
minute=0;
{
if(hour==24)
hour=0;
}
}
}
}
}
}
/******************************************************************/
/*主函数*/
/******************************************************************/
voidmain()
{
TMOD|=0x01;//定时器设置10msin12Mcrystal,工作在模式1,16位定时
TH0=0xd8;
TL0=0xf0;
IE=0x82;//打开中断
TR0=1;//打开定时开关
xianshi();
EA=1;ET0=1;TMOD|=0x21;TR0=1;//开中断总开关,计数器0允许中断,设置中断模式,启动计数器0
ET1=1;TR1=1;
while(1)
{
{
if(!A3)
{
delay(10000);
if(!A3)
{
i++;if(i==7)i=0;
xianshi();
}
}
}
{
if(!A4)
{
delay(10000);
if(!A4)
{
i--;if(i==255)i=6;
xianshi();
}
}
}
switch(i)
{
case0://正常显示控制
{
P1=0x1e;//片选个位
P0=~Baiwei;//显示个位
delay(300);//短暂延时
P1=0x1d;//片选十位
P0=~Qianwei;//显示十位
delay(300);//短暂延时
P1=0x1b;//片选百位
P0=~Wanwei;//显示百位
delay(300);//短暂延时
P1=0x17;//片选千位
P0=~Shiwan;//显示千位
delay(300);//短暂延时
P1=0x1f;
P0=0xff;
delay(300);
};break;
case1://调分控制
{
if(second%2!=0)
{
P1=0x1e;//片选个位
P0=~Baiwei;//显示个位
delay(300);//短暂延时
P1=0x1d;//片选十位
P0=~Qianwei;//显示十位
delay(300);//短暂延时
P1=0x1f;
P0=0xff;
delay(300);
}
else
delay(300);
delay(300);
{
if(!A1)
{
delay(10000);//消抖
if(!A1)
{
minute++;if(minute==61)minute=0;
xianshi();
}
}//按键处理
}
{
if(!A2)
{
delay(10000);//消抖
if(!A2)
{
minute--;if(minute==255)minute=59;
xianshi();
}
}
}
};break;
case2://调时控制
{
if(second%2==0)
{
P1=0x1b;//片选百位
P0=~Wanwei;//显示百位
delay(300);//短暂延时
P1=0x17;//片选千位
P0=~Shiwan;//显示千位
delay(300);//短暂延时
P1=0x1f;
P0=0xff;
delay(300);
}
else
delay(300);
delay(300);
{
if(!A1)
{
delay(10000);//消抖
if(!A1)
{
hour++;if(hour==24)hour=0;
xianshi();
}
}//按键处理
}
{
if(!A2)
{
delay(10000);//消抖
if(!A2)
{
hour--;if(hour==255)hour=23;
xianshi();
}
}
}
};break;
case3://秒显示控制
{
P1=0x1e;//片选个位
P0=~Gewei;//显示个位
delay(300);//短暂延时
P1=0x1d;//片选十位
P0=~Shiwei;//显示十位
delay(300);//短暂延时
P1=0x1f;
P0=0xff;
delay(300);
delay(300);
delay(300);
};break;
case4://闹钟控制
{
if((!A1)||(!A2))
{
delay(10000);
if((!A1)||(!A2))j++;
if(j==2)
j=0;
}
switch(j)
{
case0:{
P1=0x1e;//片选个位
P0=~0x71;//显示个位
delay(300);//短暂延时
P1=0x1d;//片选十位
P0=~0x71;//显示十位
delay(300);//短暂延时
P1=0x1b;//片选百位
P0=~0x3f;//显示百位
delay(300);//短暂延时
P1=0x17;//片选千位
P0=~0x40;//显示千位
delay(300);//短暂延时
delay(300);
};break;
case1:{
P1=0x1e;//片选个位
P0=~0x37;//显示个位
delay(300);//短暂延时
P1=0x1d;//片选十位
P0=~0x3f;//显示十位
delay(300);//短暂延时
P1=0x1b;//片选百位
P0=0xff;//显示百位
delay(300);//短暂延时
P1=0x17;//片选千位
P0=~0x40;//显示千位
delay(300);//短暂延时
delay(300);
}
}
};break;
case5://闹铃分钟调整
{
{
P1=0x1e;
P0=Naoling3;
delay(300);
P1=0x1d;
P0=Naoling4;
delay(300);
P1=0x1f;
P0=0xff;
delay(300);
delay(300);
delay(300);
}
{
if(!A1)
{
delay(10000);//消抖
if(!A1)
{
alarmminute++;if(alarmminute==61)alarmminute=0;
}
}//按键处理
}
{
if(!A2)
{
delay(10000);//消抖
if(!A2)
{
alarmminute--;if(alarmminute==255)alarmminute=59;
}
}
}
};break;
case6://闹铃小时调整
{
{
P1=0x1b;
P0=Naoling1;
delay(300);
P1=0x17;
P0=Naoling2;
delay(300);
P1=0x1f;
P0=0xff;
delay(300);
delay(300);
delay(300);
}
{
if(!A1)
{
delay(10000);//消抖
if(!A1)
{
alarmhour++;if(alarmhour==24)alarmhour=0;
}
}//按键处理
}
{
if(!A2)
{
delay(10000);//消抖
if(!A2)
{
alarmhour--;if(alarmhour==255)alarmhour=23;
}
}
};break;
default:break;
}
}
}
}
3. 单片机数字时钟设计
ORG 0X00
LJMP START
ORG 0X30
#30H ; 设置堆栈
MOV P1, #0XFE ; 设置在数码管的第0位显示
MOV A, #0X01 ; A置初值为0000 0001
LOOP: MOV P0, A ; 在数码管上显示寄存器A中的二进制数
MOV R3, #0X5C ; 延时1S
ACALL EXTDELAY ; 延时观察和记录对应的显示结果
RL A ; 将A寄存器的值循环左移一位
SJMP LOOP ; 循环显示
DELAY: MOV R1, #0XC8 ; 延时20MS
DL2: MOV R2, #0X18
DL1: NOP
NOP
DJNZ R2, DL1
DJNZ R1, DL2
RET
EXTDELAY:ACALL DELAY
DJNZ R3,EXTDELAY
RET
END
ORG 0X00
SJMP START
ORG 0X30
START: MOV SP, #30H ; 设置堆栈
MOV P1, #0XFE ; 位选信号,选中第0个数码管
MOV P0, #0X6F ; 在数码管上显示"9"
LOOP: SJMP LOOP ; 循环执行程序
END
ORG 0X00
LJMP START
ORG 0X30
START: MOV SP, #30H ; 设置堆栈
MOV P1, #0XFE ; 设置在数码管的第0位显示
MOV DPTR, #TABLE ; 送TABLE地址到DPTR指针
MOV R7, #0X00 ; 标志变量,限制指针在TABLE区
LOOP: CLR A
MOVC A, @A+DPTR ; 取TABLE区的字形码
MOV P0, A ; 在数码管上显示寄存器A中的二进制数
INC R7 ; 指针控制加一
MOV R3, #0X5C ; 延时
ACALL EXTDELAY ; 延时观察和记录对应的显示结果
CJNE R7, #0X10, NEXT ; 如果TABLE中数未取到最后一个,继续取下一个
MOV R7, #0X00 ; 如果已经取过所有数,则重新开始去第一个数
MOV DPTR, #TABLE
SJMP LOOP
NEXT: INC DPTR ; 指针寄存器加1
SJMP LOOP ; 循环显示
DELAY: MOV R1, #0XC8 ; 延时20MS
DL2: MOV R2, #0X18
DL1: NOP
NOP
DJNZ R2, DL1
DJNZ R1, DL2
RET
EXTDELAY: ACALL DELAY
DJNZ R3 ,EXTDELAY
RET
TABLE: ; 相对地址
DB 0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F ;十六进制字形数据
0 1 2 3 4 5 6 7 8 9 (十六进制数)
DB 0X77,0X7C,0X39,0X5E,0X79,0X71 ; 十六进制字形数据
A B C D E F (十六进制数)
END
ORG 0X00
LJMP START
ORG 0X30
START: MOV SP, #30H
MOV A, #0XFE ; 置A寄存器为0XFE
MOV DPTR, #TABLE
MOV R7, #0X00
LOOP: MOV P1, A ; 在数码管的第0位显示
MOV R4,A ; 保存A寄存器的制
CLR A
MOVC A, @A+DPTR
MOV P0, A
MOV A, R4 ; 还原A寄存器的值
CJNE A, #0XBF, SKIP ; 如果已在第五位显示,那么下一次
MOV A, #0XFE ; 从第0位开始显示
SJMP LOOP ; 跳回执行下一次显示
SKIP: RL A ; A左移一位,下一次在数码管的下一位显示数字
INC R7
MOV R3, #0X5C
ACALL EXTDELAY
CJNE R7, #0X10, NEXT ; 如果TABLE中数未取到最后一个,继续取下一个
MOV R7, #0X00 ; 如果已经取过所有数,则重新开始去第一个数
MOV DPTR, #TABLE
SJMP LOOP
NEXT: INC DPTR ; 指针寄存器加1
SJMP LOOP ; 循环显示
DELAY: MOV R1, #0XC8 ; 延时20MS
DL2: MOV R2, #0X18
DL1: NOP
NOP
DJNZ R2, DL1
DJNZ R1, DL2
RET
EXTDELAY: ACALL DELAY
DJNZ R3, EXTDELAY
RET
TABLE: ; 相对地址
DB 0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F ;十六进制字形数据
0 1 2 3 4 5 6 7 8 9 (十六进制数)
DB 0X77,0X7C,0X39,0X5E,0X79,0X71 ; 十六进制字形数据
A B C D E F (十六进制数)
END