单片机实验 脉冲计数和电脑时钟程序
51单片机作的电子钟程序及电路图

51单片机作的电子钟程序在很多地方已经有了介绍,对于单片机学习者而言这个程序基本上是一道门槛,掌握了电子钟程序,基本上可以说51单片机就掌握了80%。
常见的电子钟程序由显示部分,计算部分,时钟调整部分构成。
时钟的基本显示原理:时钟开始显示为0时0分0秒,也就是数码管显示000000,然后每秒秒位加1 ,到9后,10秒位加1,秒位回0。
10秒位到5后,即59秒,分钟加1,10秒位回0。
依次类推,时钟最大的显示值为23小时59分59秒。
这里只要确定了1秒的定时时间,其他位均以此为基准往上累加。
开始程序定义了秒,十秒,分,十分,小时,十小时,共6位的寄存器,分别存在30h,31h,32h,33h,34h,35h单元,便于程序以后调用和理解。
6个数码管分别显示时、分、秒,一个功能键,可以切换调整时分秒、增加数值、熄灭节电等功能全部集一键。
以下是部分汇编源程序,购买我们产品后我们用光盘将完整的单片机汇编源程序和烧写文件送给客户。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 中断入口程序 ;; (仅供参考) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ORG 0000H ;程序执行开始地址LJMP START ;跳到标号START执行ORG 0003H ;外中断0中断程序入口RETI ;外中断0中断返回ORG 000BH ;定时器T0中断程序入口LJMP INTT0 ;跳至INTTO执行ORG 0013H ;外中断1中断程序入口RETI ;外中断1中断返回ORG 001BH ;定时器T1中断程序入口LJMP INTT1 ;跳至INTT1执行ORG 0023H ;串行中断程序入口地址RETI ;串行中断程序返回;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 主程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;START: MOV R0,#70H ;清70H-7AH共11个内存单元MOV R7,#0BH;clr P3.7 ;CLEARDISP: MOV @R0,#00H ;INC R0 ;DJNZ R7,CLEARDISP ;MOV 20H,#00H ;清20H(标志用)MOV 7AH,#0AH ;放入"熄灭符"数据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 EA ;总中断开放SETB ET0 ;允许T0中断SETB TR0 ;开启T0定时器MOV R4,#14H ;1秒定时用初值(50M S×20)START1: LCALL DISPLAY ;调用显示子程序JNB P3.7,SETMM1 ;P3.7口为0时转时间调整程序SJMP START1 ;P3.7口为1时跳回START1 SETMM1: LJMP SETMM ;转到时间调整程序SETMM; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 1秒计时程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;T0中断服务程序INTT0: PUSH ACC ;累加器入栈保护PUSH PSW ;状态字入栈保护CLR TR0 ;关闭定时器T0MOV A,#0B7H ;中断响应时间同步修正ADD A,TL0 ;低8位初值修正MOV TL0,A ;重装初值(低8位修正值)MOV A,#3CH ;高8位初值修正ADDC A,TH0 ;MOV TH0,A ;重装初值(高8位修正值)SETB TR0 ;开启定时器T0DJNZ R4, OUTT0 ;20次中断未到中断退出ADDSS: MOV R4,#14H ;20次中断到(1秒)重赋初值MOV R0,#71H ;指向秒计时单元(71H-72H)ACALL ADD1 ;调用加1程序(加1秒操作)MOV A,R3 ;秒数据放入A(R3为2位十进制数组合)CLR C ;清进位标志CJNE A,#60H,ADDMM ;ADDMM: JC OUTT0 ;小于60秒时中断退出ACALL CLR0 ;大于或等于60秒时对秒计时单元清0MOV R0,#77H ;指向分计时单元(76H-77H)ACALL ADD1 ;分计时单元加1分钟MOV A,R3 ;分数据放入ACLR C ;清进位标志CJNE A,#60H,ADDHH ;ADDHH: JC OUTT0 ;小于60分时中断退出ACALL CLR0 ;大于或等于60分时分计时单元清0MOV R0,#79H ;指向小时计时单(78H-79H)ACALL ADD1 ;小时计时单元加1小时MOV A,R3 ;时数据放入ACLR C ;清进位标志CJNE A,#24H,HOUR ;HOUR: JC OUTT0 ;小于24小时中断退出ACALL CLR0 ;大于或等于24小时小时计时单元清0OUTT0: MOV 72H,76H ;中断退出时将分、时计时单元数据移MOV 73H,77H ;入对应显示单元MOV 74H,78H ;MOV 75H,79H ;POP PSW ;恢复状态字(出栈)POP ACC ;恢复累加器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 ;转中断退出; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 加1子程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ADD1: MOV A,@R0 ;取当前计时单元数据到ADEC R0 ;指向前一地址SWAP A ;A中数据高四位与低四位交换ORL A,@R0 ;前一地址中数据放入A中低四位ADD A,#01H ;A加1操作DA A ;十进制调整MOV R3,A ;移入R3寄存器ANL A,#0FH ;高四位变0MOV @R0,A ;放回前一地址单元MOV A,R3 ;取回R3中暂存数据INC R0 ;指向当前地址单元SWAP A ;A中数据高四位与低四位交换ANL A,#0FH ;高四位变0MOV @R0,A ;数据放入当削地址单元中RET ;子程序返回; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 清零程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;............. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 时钟调整程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;当调时按键按下时进入此程序SETMM: cLR ET0 ;关定时器T0中断CLR TR0 ;关闭定时器T0LCALL DL1S ;调用1秒延时程序JB P3.7,CLOSEDIS ;键按下时间小于1秒,关闭显示(省电)MOV R2,#06H ;进入调时状态,赋闪烁定时初值SETB ET1 ;允许T1中断SETB TR1 ;开启定时器T1SET2: JNB P3.7,SET1 ;P3.7口为0(键未释放),等待SETB 00H ;键释放,分调整闪烁标志置1SET4: JB P3.7,SET3 ;等待键按下LCALL DL05S ;有键按下,延时0.5秒JNB P3.7,SETHH ;按下时间大于0.5秒转调小时状态MOV R0,#77H ;按下时间小于0.5秒加1分钟操作LCALL ADD1 ;调用加1子程序MOV A,R3 ;取调整单元数据CLR C ;清进位标志CJNE A,#60H,HHH ;调整单元数据与60比较HHH: JC SET4 ;调整单元数据小于60转SET4循环LCALL CLR0 ;调整单元数据大于或等于60时清0CLR C ;清进位标志AJMP SET4 ;跳转到SET4循环CLOSEDIS: SETB ET0 ;省电(LED不显示)状态。
单片机程序 一分钟外部脉冲计数

/***************************利用外部中断0 和定时器0 来计算一分钟脉冲数交流 QQ: 357076835***************************/#include <reg52.h>#include <intrins.h>int N=0,m=0,p;unsigned char code dat[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};unsigned int led[3];sbit LS138A = P2^2; //定义138译码器的输入A脚由P2.2控制sbit LS138B = P2^3; //定义138译码器的输入脚B由P2.3控制sbit LS138C = P2^4; //定义138译码器的输入脚C由/****************************/void coun() //初始化设置{TMOD=0x01;TH0=0x4c;TL0=0x00;//定义50msTR0=1;IT0=1;EX0=1;ET0=1;EA=1;}void delay(int z) //延时函数{unsigned char x,y;for(x=0;x<50;x++)for(y=z;y>0;y--) ;}void display() //显示函数 138译码器显示{ char i;p=N;led[0]=dat[p/100];led[1]=dat[p%100/10];led[2]=dat[p%10];for( i=0; i<3; i++) //实现8位动态扫描循环{P0 = led[i]; //将字模送到P0口显示switch(i) //使用switch 语句控制位选也可以是用查表的方式学员可以试着自己修改 {case 0:LS138A=0; LS138B=0; LS138C=0; break;case 1:LS138A=1; LS138B=0; LS138C=0; break;case 2:LS138A=0; LS138B=1; LS138C=0; break;}delay(10);}}/*************主函数***************/void main(){// delay(50);coun();while(1){if(m>=1200) 达到一分钟之后关闭外部中断0EX0=0;display();}}/*************中断函数***************/void int0() interrupt 0 using 1{EX0=0;N++;EX0=1;void int1() interrupt 1 using 2 {TH0=0x4c;TL0=0x00;m++;}。
单片机—电子钟实验源程序

;22H~24H存时钟时间;32H~34H存闹钟时间;42H~44H存秒表时间;MON用于选择时钟/闹钟调时;30H作为标志;RST用于选择时、分、秒;LAST调时减1,NEXT调时加1;EXEC用于开始秒表计时;40H作为标志CM1 EQU 8001HCM2 EQU 8002HCM4 EQU 8004HORG 0000HLJMP MAINORG 000BHLJMP SER0ORG 001BHLJMP SER1ORG 0030HMAIN: MOV SP,#70HMOV 32H,#00HMOV 33H,#00HMOV 34H,#00H;设置闹钟初始值MOV 42H,#00HMOV 43H,#00HMOV 44H,#00H;设置秒表初始值MOV 26H,#11H;26H作为标志(h,min,s)MOV 30H,#00H;30H作为时钟(0)与闹钟(1)的标志MOV R4,#0C8H;设200次循环MOV TMOD,#20H;T0方式0,T2方式2MOV TH0,#63H ;5msMOV TL0,#10HMOV TH1,#9CHMOV TL1,#9CH ;100MSSETB P1.1SETB EASETB ET0SETB ET1SETB TR0MOV A,22H;检查时钟格式是否正确CLR CSUBB A,#24HJNC INITMOV A,23HCLR CSUBB A,#60HJNC INITMOV A,24HCLR CSUBB A,#60HJNC INITLJMP LOADINIT: MOV 22H,#12H;时钟格式不正确时进行初始化,为12:00:00MOV 23H,#00HMOV 24H,#00HLOAD: CLR RS0CLR RS1;第一组工作寄存器MOV A,40HJZ S1;40H为1时,42H~44H(秒表)送显示缓冲区MOV R0,#42HLJMP NOADS1: MOV A,30HJZ SOAD;30H为0时,22H~24H(时钟)送显示缓冲区MOV R0,#32H;30H为1时,32H~34H(闹钟)送显示缓冲区LJMP NOADSOAD: MOV R0,#22HNOAD: MOV R1,#60H;将对应的时间送入显示缓冲区60H~65HMOV R5,#03HLOOP1: MOV A,@R0ANL A,#0F0HSWAP AMOV @R1,AINC R1MOV A,@R0ANL A,#0FHMOV @R1,AINC R1INC R0DJNZ R5,LOOP1LCALL DP1;调用显示子程序MOV A,32HCJNE A,22H,SWEEPMOV A,33HCJNE A,23H,SWEEPSETB TR1;时钟与闹钟的时和分相等时开定时器1 SWEEP: LCALL SEARCHMOV A,25H;25H存键号CJNE A,#04H,C6MOV A,40HADD A,#01HMOV B,#02HDIV ABMOV 40H,B;键值为EXEC时,处理40H标志位MOV 42H,#00HMOV 43H,#00HMOV 44H,#00H;秒表赋初值LJMP SENDC6: CJNE A,#02H,C3MOV A,30HADD A,#01HMOV B,#02HDIV ABMOV 30H,B;键值为MON时,处理30H标志位LJMP SENDC3: CJNE A,#03H,C1MOV A,26HRL A;键值为RST时,处理26H标志位MOV 26H,AMOV A,30HJZ C4LCALL NJ ;闹钟调用NJLJMP SENDC4: LCALL AJ ;时钟调用AJLJMP SENDC1: MOV A,25HCJNE A,#01H,C2LCALL LAST;键值为LAST时,调用减1运算LJMP SENDC2: MOV A,25HJNZ SENDLCALL NEXT;键值为NEXT时,调用加1运算SEND: MOV 25H,#99HCLR RS0CLR RS1LJMP LOAD;-------------------------------------------------------- ;-------判断时钟h/min/s标志位26H-------- ;-------------------------------------------------------- AJ: SETB RS0;换工作寄存器CLR RS1MOV A,26HCJNE A,#11H,AJ1MOV R1,#21HSETB TR0LJMP ARET;R1存对应时钟位AJ1: CLR TR0CJNE A,#22H,AJ2MOV R1,#22HAJ2: CJNE A,#44H,AJ3MOV R1,#23HAJ3: CJNE A,#88H,ARETMOV R1,#24HARET: RET;--------------------------------------------------------- ;-------判断闹钟h/min/s标志位26H--------- ;--------------------------------------------------------- NJ: SETB RS0CLR RS1;第1组工作寄存器MOV A,26HCJNE A,#11H,NJ1MOV R1,#31HLJMP ARET;R1存对应时钟位NJ1: CJNE A,#22H,NJ2MOV R1,#32HNJ2: CJNE A,#44H,NJ3MOV R1,#33HNJ3: CJNE A,#88H,NJRETMOV R1,#34HNJRET: RET;--------------------------------------;------------减1运算-------------;--------------------------------------LAST: MOV A,30HJZ LA0;30H为0时,时钟进行减1运算LJMP NA0;30H为1时,闹钟进行减1运算LA0: LCALL AJCJNE R1,#21H,LA1LJMP LRETLA1: CLR CMOV A,#9AHSUBB A,#01HADDC A,@R1DA AMOV @R1,ACJNE A,#99H,LRET;当A不等于99H时,即不是从0开始减1,此时对应时间不需要调整CJNE R1,#22H,LA2MOV @R1,#23H;当指向22H(时)时,对应值调整为#23H LJMP LRETLA2: MOV @R1,#59H;当不指向22H(指向分或秒)时,对应值调整为#59HLJMP LRETNA0: LCALL NJCJNE R1,#31H,NA1LJMP LRET NA1: CLR CMOV A,#9AHSUBB A,#01HADDC A,@R1DA AMOV @R1,ACJNE A,#99H,LRET;当A不等于99H时,即不是从0开始减1,此时对应值不需要调整CJNE R1,#32H,NA2MOV @R1,#23H;当指向22H(时)时,对应值调整为#23H LJMP LRETNA2: MOV @R1,#59H;当不指向32H(指向分或秒)时,对应值调整为#59HLRET: RET;--------------------------------------;--------------加1运算-----------;--------------------------------------NEXT: MOV A,30HJZ NE0;30H为0时,时钟进行加1运算LJMP NZ0;30H为1时,闹钟进行加1运算NE0: LCALL AJCJNE R1,#21H,NE1LJMP NRETNE1: MOV A,@R1ADD A,#01HDA AMOV @R1,ACJNE R1,#22H,NE2;当指向22H(时)时,比较A与#24H;当不指向22H(指向分或秒)时,转向NE2比较A与#60HCJNE A,#24H,NRETMOV @R1,#00H;A等于#24H时,给对应位赋0NE2: CJNE A,#60H,NRETMOV @R1,#00H;A等于#60H时,给对应位赋0LJMP NRETNZ0: LCALL NJCJNE R1,#31H,NZ1LJMP NRETNZ1: MOV A,@R1ADD A,#01HDA AMOV @R1,ACJNE R1,#32H,NZ2;当指向32H(时)时,比较A与#24H;当不指向32H(指向分或秒)时,转向NZ2比较A与#60HCJNE A,#24H,NRETMOV @R1,#00H;A等于#24H时,给对应位赋0NZ2: CJNE A,#60H,NRETMOV @R1,#00H;A等于#60H时,给对应位赋0NRET: RET;--------------------------------------;-----------显示子程序-----------;--------------------------------------DP1: CLR RS0CLR RS1MOV R1,#60HMOV R2,#20HDP2: MOV DPTR,#CM2MOV A,#00HMOVX @DPTR,AMOV DPTR,#DATA0MOV A,@R1MOVC A,@A+DPTRMOV DPTR,#CM4MOVX @DPTR,AMOV DPTR,#CM2MOV A,R2MOVX @DPTR,ALCALL DL1MSCLR CRRC AINC R1MOV R2,AJNZ DP2RETDL1MS: MOV R6,#03HDL1: MOV R5,#02H DL2: DJNZ R5,DL2DJNZ R6,DL1RET;--------------------------------------;-----SEAROH扫描子程序-----;-------------------------------------- SEARCH: CLR RS1SETB RS0;第1组工作寄存器MOV DPTR,#CM4MOV A,#00HMOVX @DPTR,AMOV R2,#06HMOV R3,#0FEHMOV R5,#00HSC: MOV DPTR,#CM2MOV A,R3MOVX @DPTR,AMOV DPTR,#CM1MOVX A,@DPTRORL A,#0F0HCPL AJB ACC.0,L1JB ACC.1,L2JB ACC.2,L3JB ACC.3,L4MOV A,R3RL AINC R5MOV R3,ADJNZ R2,SCLJMP L6L1: MOV R4,#00HLJMP GETL2: MOV R4,#01HLJMP GETL3: MOV R4,#02HLJMP GETL4: MOV R4,#03HGET: MOV A,R5MOV B,#04HMUL ABADD A,R4 ;列*4+行MOV 25H,AL5: LCALL DP1MOV A,#00HMOV DPTR,#CM2MOVX @DPTR,AMOV DPTR,#CM1MOVX A,@DPTRORL A,#0F0HCPL AJNZ L5L6: CLR RS0RET;--------------------------------------;----------中断子程序1---------;--------------------------------------SER0: CLR RS0CLR RS1;第0组工作寄存器MOV TH0,#63HMOV TL0,#18HDJNZ R4,EXITMOV R4,#0C8HPUSH APUSH PSWMOV A,40HJZ INT0MOV A,44H ;闹钟秒ADD A,#01HDA AMOV 44H,ACJNE A,#60H,INT0;每次中断都需要对时钟进行加1运算,故要跳转到INT0,而不是EXIT0CLR AMOV 44H,AMOV A,43H ;闹钟分ADD A,#01HDA AMOV 43H,ACJNE A,#60H,INT0CLR AMOV 43H,AMOV A,42H ;闹钟时ADD A,#01HDA AMOV 42H,ACJNE A,#24H,INT0CLR AMOV 42H,AINT0: MOV A,24H ;时钟秒ADD A,#01HDA AMOV 24H,ACJNE A,#60H,EXIT0CLR AMOV 24H,AMOV A,23H ;时钟分ADD A,#01HDA AMOV 23H,ACJNE A,#60H,EXIT0CLR AMOV 23H,AMOV A,22H ;时钟时ADD A,#01HDA AMOV 22H,ACJNE A,#24H,EXIT0CLR AMOV 22H,AEXIT0: POP PSWPOP AEXIT: RETI;--------------------------------------;----------中断子程序2---------;--------------------------------------SER1: CPL P1.1CLR TR1RETIDATA0:DB 3FH,06H,5BH,4FH,66H,6DH,7DH, DB 07H,7FH,6FH,77H,7CH,39H,5EHDB 79H,71HEND。
单片机制作数字钟(含万年历、秒表功能)

数字钟、万年历制作(基于单片机)电路原理图:程序://********************20131206****数字钟程序#pragma SMALL#include <reg51.h>#include <absacc.h>#include <intrins.h>//********************************************************* *********编译预处理void display(unsigned char *p); //显示函数,P为显示数据首地址unsigned char keytest(); //按键检测函数unsigned char search(); //按键识别函数void alarm(); //闹钟判断启动函数void ftion0(); //始终修改函数void ftion1(); //闹钟修改函数void ftion3(); //日期修改函数void cum(); //加1修改函数void minus(); //减1修改函数void jinzhi(); //进制修改函数void riqi(); //日期void stopwatch(); //秒表函数//********************************************************* *******函数声明sbit P2_7=P2^7;//********************************************************* *******端口定义unsigned char clockbuf[3]={0,0,0};unsigned char bellbuf[3]={0,0,0};unsigned char date[3]={1,1,1}; //日期存放数组unsigned char stop[3]={0,0,0};unsigned char msec1,msec2;unsigned char timdata,rtimdata,dtimdata;unsigned char count;unsigned char *dis_p;unsigned char or; //12进制控制标志unsigned char ri; //日期显示控制标志位unsigned char mb; //秒表控制标志位bit arm,rtim,rhour,rmin,hour,min,sec,day,mon,year; //定义位变量//********************************************************* *****全局变量定义void main(){unsigned char a;or=0; //12进制修改标志清零ri=0;mb=0;P2_7=0;arm=0;msec1=0;msec2=0;timdata=0;rtimdata=0;count=0;TMOD=0x12;TL0=0x06;TH0=0x06;TH1=(65536-10000)/256;TL1=(65536-10000)%256;EA=1;ET0=1;ET1=1;TR0=1;TR1=0;dis_p=clockbuf;while(1){a=keytest();if(a==0x78) //判断是否有键按下{display(dis_p);if(arm==1) alarm();}else{display(dis_p);a=keytest();if(a!=0x78){a=search();switch(a){case 0x00:ftion0();break;case 0x01:ftion1();break;case 0x02:cum();break;case 0x06:jinzhi();break;case 0x03:riqi();break;case 0x04:ftion3();break;case 0x05:minus();break;case 0x07:stopwatch();break;case 0x09:TR1=1;break;case 0x0a:TR1=0;break;case 0x0b:stop[0]=0;stop[1]=0;stop[2]=0;break;default:break;}}}}}//********************************************主函数【完】void display(unsigned char *p){unsigned char buffer[]={0,0,0,0,0,0};unsigned char k,i,j,m,temp;unsigned char led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};buffer[0]=p[0]/10;buffer[1]=p[0]%10;buffer[2]=p[1]/10;buffer[3]=p[1]%10;buffer[4]=p[2]/10;buffer[5]=p[2]%10;if((sec==0)&&(min==0)&&(hour==0)&&(rmin==0)&&(rhour==0)&&( day==0)&&(mon==0)&&(year==0)) //没有修改标志,正常显示{for(k=0;k<3;k++){temp=0x01;for(i=0;i<6;i++){P0=0x00; //段选端口j=buffer[i];P0=led[j];P1=~temp; //位选端口temp<<=1;for(m=0;m<200;m++);}}}else //若有修改标志,则按以下标志分别显示{if(sec==1||day==1){P1=0x1f;i=buffer[5];P0=led[i];for(m=0;m<200;m++);P1=0x2f;j=buffer[4];P0=led[j];for(m=0;m<200;m++);}if(min==1||rmin==1||mon==1){P1=0x3b;i=buffer[2];P0=led[i];for(m=0;m<200;m++);P1=0x37;j=buffer[3];P0=led[j];for(m=0;m<200;m++);}if(hour==1||rhour==1||year==1) {P1=0x3e;i=buffer[0];P0=led[i];for(m=0;m<200;m++);P1=0x3d;j=buffer[1];P0=led[j];for(m=0;m<200;m++);}}}//**********************************LED显示函数【完】unsigned char keytest(){unsigned char c;P2=0x78; //检测是否有键按下c=P2;c=c&0x78;return(c);}//******************************************键盘检测函数【完】unsigned char search(){unsigned char a,b,c,d,e;c=0x3f;a=0; //行号while(1){P2=c;d=P2;d=d&0x07;if(d==0x03){b=0;break;} //列号else if(d==0x05){b=1;break;}else if(d==0x06){b=2;break;}a++;c>>=1;if(a==5){a=0;c=0x3f;}}e=a*3+b;do{display(dis_p);}while((d=keytest())!=0x78);return(e);}//***********************************************查键值函数【完】void alarm(){if((clockbuf[0]==bellbuf[0])&&(clockbuf[1]==bellbuf[1])){P2_7=1;rtim=1;if(count==10){count=0;P2_7=0;arm=0;rtim=0;}}}//****************************************闹钟判断启动函数【完】void ftion0(){TR0=0;rhour=0;rmin=0;dis_p=clockbuf;rtimdata=0;timdata++;switch(timdata){case 0x01:sec=1;break;case 0x02:sec=0;min=1;break;case 0x03:min=0;hour=1;break;case 0x04:timdata=0;hour=0;TR0=1;break;default:break;}}//*********************************************时钟设置函数【完】void ftion1(){if(TR0==0) TR0=1;sec=0;min=0;hour=0;dis_p=bellbuf;timdata=0;rtimdata++;switch(rtimdata){case 0x01:rmin=1;break;case 0x02:rmin=0;rhour=1;break;case 0x03:rtimdata=0;rhour=0;arm=1;dis_p=clockbuf;break;default:break;}}//*********************************************闹钟设置函数【完】void ftion3(){if(TR0==0) TR0=1;day=0;mon=0;year=0;dis_p=date;timdata=0;rtimdata=0;dtimdata++;switch(dtimdata){case 0x01:day=1;break;case 0x02:day=0;mon=1;break;case 0x03:mon=0;year=1;break;case 0x04:dtimdata=0;year=0;dis_p=clockbuf;break;default:break;}}//*************************************************日期修改函数【完】void minus(){if(sec==1){if(0==clockbuf[2]) clockbuf[2]=59;else clockbuf[2]--;}else if(min==1){if(0==clockbuf[1]) clockbuf[1]=59;else clockbuf[1]--;}else if(hour==1){if(or==0) //判断进制{if(0==clockbuf[0]) clockbuf[0]=23;else clockbuf[0]--;}if(or==1){if(1==clockbuf[0]) clockbuf[0]=12;else clockbuf[0]--;}}else if(rmin==1){if(bellbuf[1]==0) bellbuf[1]=59;else bellbuf[1]--;}else if(rhour==1){if(or==0){if(bellbuf[0]==0) bellbuf[0]=23;else bellbuf[0]--;}if(or==1){if(bellbuf[0]==1) bellbuf[0]=12;else bellbuf[0]--;}}else if(day==1){if(date[2]==1) date[2]=31;else date[2]--;}else if(mon==1){if(date[1]==1) date[1]=12;else date[1]--;}else if(year==1){if(date[0]==1) date[0]=99;else date[0]--;}}//*************************************减1修改功能函数【完】void cum(){if(sec==1){if(59==clockbuf[2]) clockbuf[2]=0;else clockbuf[2]++;}else if(min==1){if(59==clockbuf[1]) clockbuf[1]=0;else clockbuf[1]++;}else if(hour==1){if(or==0) //判断进制{if(23==clockbuf[0]) clockbuf[0]=0;else clockbuf[0]++;}if(or==1){if(12==clockbuf[0]) clockbuf[0]=1;else clockbuf[0]++;}}else if(rmin==1){if(bellbuf[1]==59) bellbuf[1]=0;else bellbuf[1]++;}else if(rhour==1){if(or==0){if(bellbuf[0]==23) bellbuf[0]=0;else bellbuf[0]++;}if(or==1){if(bellbuf[0]==12) bellbuf[0]=1;else bellbuf[0]++;}}else if(day==1){if(date[2]==31) date[2]=1;else date[2]++;}else if(mon==1){if(date[1]==12) date[1]=1;else date[1]++;}else if(year==1){if(date[0]==99) date[0]=0;else date[0]++;}}//*************************************加1修改功能函数【完】void jinzhi(){if(or==0) or=1;else or=0;}//***********************************进制修改控制函数【完】void riqi(){if(ri==0){dis_p=date;}if(ri==1){dis_p=clockbuf;}ri++;if(ri==2) ri=0;}//********************************日期控显示函数【完】void stopwatch(){if(mb==0){dis_p=stop;mb=1;}else{mb=0;dis_p=clockbuf;}}//************秒表**********秒表**********秒表函数【完】void clock() interrupt 1{EA=0;if(msec1!=0x14) msec1++; //6MHz晶振定时10mselse{msec1=0;if(msec2!=100) msec2++; //定时1selse{if(rtim==1) count++; //闹钟启动标志计时10smsec2=0;if(clockbuf[2]!=59) clockbuf[2]++;else{clockbuf[2]=0;if(clockbuf[1]!=59) clockbuf[1]++;else{clockbuf[1]=0;if(or==0){if(clockbuf[0]!=23) clockbuf[0]++;else{clockbuf[0]=0;if((date[1]==1)||(date[1]==1)||(date[1]==1)||(date[1]==3)||(date[ 1]==5)||(date[1]==7)||(date[1]==8)||(date[1]==10)||(date[1]==12)){if(date[2]!=30) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if((date[1]==4)||(date[1]==6)||(date[1]==9)||(date[1]==11)){if(date[2]!=29) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if(date[1]==2){if((((date[0]%4==0)&&(date[0]%100!=0))||(date[0]%400==0))){if(date[2]!=28) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}else{if(date[2]!=27) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}}}}if(or==1){if(clockbuf[0]!=12) clockbuf[0]++;else{clockbuf[0]=0;if((date[1]==1)||(date[1]==1)||(date[1]==1)||(date[1]==3)||(date[ 1]==5)||(date[1]==7)||(date[1]==8)||(date[1]==10)||(date[1]==12)){if(date[2]!=30) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if((date[1]==4)||(date[1]==6)||(date[1]==9)||(date[1]==11)){if(date[2]!=29) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if(date[1]==2){if((((date[0]%4==0)&&(date[0]%100!=0))||(date[0]%400==0))){if(date[2]!=28) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}else{if(date[2]!=27) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}}}}}}}}EA=1;}//*******************************定时器0中断函数【完】void miaobiao() interrupt 3{TH1=(65536-10000)/256;TL1=(65536-10000)%256;if(stop[2]!=99) stop[2]++;else{stop[2]=0;if(stop[1]!=59) stop[1]++;else{stop[1]=0;if(stop[0]!=59) stop[0]++;else stop[0]=0;}}}//***********************************定时器1中断函数【完】。
单片机课程设计外部脉冲计数器

单片机课程设计外部脉冲计数器目录摘要:单片机是一种集成在电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计时器等功能集成到一块硅片上构成的一个小而完善的计算机系统。
本课程设计的指导思想是控制单片机实现从0到99的计数功能,其结果显示在两位一体的共阳极数码管上。
关键词:脉冲计数器数码管单片机本设计基于单片机技术原理,以单片机芯片STC89C52作为核心控制器,通过硬件电路的制作以及软件程序的编制,设计制作出一个计数器,包括以下功能:输出脉冲,按下键就开始计数,并将数值显示在两位一体的共阳极数码管上。
1课题原理PCB板上设置开始计数按键和清零按键,以上按键与89C52单片机的P1口连接,通过查询按键是否被按下来判断进行计数或者清零。
若按下计数健,则单片机控制两位一体的共阳极数码管显示从00开始的数字,按下一次,则数字加一,一次类推;若按下清零键,则程序返回程序开始处,并且数码管显示00。
2 硬件及软件设计2.1 硬件系统2.1.1 硬件系统设计此设计是在单片机最小系统的基础上进行开发和拓展,增加了按键电路和和数码管显示电路,由于单片机输出电流不足以驱动数码管发光,所以数码管需要驱动电路。
我们采用了三极管对数码管电流进行放大,使电流大小达到要求值。
2.1.2 单元电路设计基本框架如下图2.1开始按键数码管 89C52单片机清零按键显示控制加一按键2.1基本框架SEL11JDB91627384954.7kR112P3VCC142C00Q91vccVCC5PP25440CCPC-RXPC-TX0112110Q9465317126118vcc01-+DpVV7SEG-2abcdefghNVCCGR1INR2IN39867412T1OUTT2OUT0000000000000000R104.7k11111111D S232A-NR1OUTT2INC1+C1-C2+C2-T1INR2OUT123456781RRRRRRRRU20134519SEL2111DB0DB1DB2DB3DB4DB5DB6DB7PP1444 VCCCC0011RXDTXDDB0DB1DB2DB3DB4DB5DB6DB7TXDRXD92987654321234567800010333333332 222222242113DNP00P01P02P03P04P05P06P07P20P21P22P23P24P25P26P27VCCGPSENP30/ RXDP31/ TXDALE/ PROGP10P11P12P13P14P15P16P17P32/ INT0P33/ INT1P34/ T0P35/T1EA/VppXTAL1XTAL2RST/VpdP36/ WRP37/RD89C52AT89S5X123456784518991131123671111VCCR10DTTWRINT1INT0P10P11SEL1SE L2SPEAKP12P13VCCC1010UF/16V12311.0592MHzXTALVCC4K35021RSTP1KEYK0R121PP67 00C3C3VCC211234SSW-PBSSW-PBSSW-PBSSW-PB2PDC5V图2.2 计数器原理图图2.3 计数器PCB图1(STC89C52芯片 89C52STC89C52RC芯片包括: 8k字节139P10P00238P11P01Flash,512字节RAM, 32位I/O口337P12P02436P13P03线,看门狗定时器,两个数据指针,535P14P04634三个16位定时器/计数器,一个6向P15P05733P16P06832量2级中断结构,全双工串行口,片P17P071221内晶振及时钟电路。
51单片机脉冲产生程序设计

51单片机脉冲产生程序设计脉冲产生是嵌入式系统中非常重要的功能之一、在51单片机中,我们可以通过定时器/计数器和中断来实现脉冲的产生。
下面将详细介绍如何设计一个脉冲产生的程序。
首先,我们需要选择一个定时器作为脉冲产生的源。
在51单片机中,有两个可用的定时器,分别是定时器0和定时器1、我们选择一个定时器后,就需要设置定时器的工作模式和计数方式。
在这个例子中,我们选择使用定时器1,并设置为工作模式1和16位计数。
下面是相关的代码示例:```c#include <reg51.h>//定义定时器1的计数周期,用于控制脉冲的频率//主函数void main//声明并初始化定时器计数值unsigned int count = 0xFFFF - TIM1_CYCLE;//设置定时器1的工作模式和计数方式TMOD=0x20;//工作模式1TH1 = count / 256; // 设置高字节TL1 = count % 256; // 设置低字节//启动定时器1TR1=1;while (1)//脉冲输出的相关处理//这里可以添加相关操作}```在上述代码中,我们通过`TIM1_CYCLE`宏定义了定时器1的计数周期,用于控制脉冲的频率。
然后,我们设置了定时器1的工作模式为工作模式1,并计算出计数值,将其分别赋值给TH1和TL1寄存器。
最后,启动定时器1,并在主循环中进行相关的脉冲输出处理。
通过以上的代码段,我们实现了一个简单的脉冲产生程序。
在实际应用中,我们可以根据需要进行进一步的处理,例如根据输入信号进行触发控制、与其他模块进行通信等。
需要注意的是,在上述代码中,我们使用了51单片机的计数方式1,即工作模式1、根据实际需求,您可以根据相应的定时器和计数方式进行调整。
另外,定时器的计数周期也可以根据具体应用进行调整,以满足不同的脉冲需求。
总结起来,设计一个脉冲产生的程序需要选择定时器和计数方式,设置定时器的工作模式和计数值,然后启动定时器,并在主循环中进行相关的处理。
单片机脉冲计数器程序

单片机脉冲计数器1、设计内容用单片机实现对一路脉冲计数和显示的功能。
硬件包括单片机最小系统、LED显示、控制按钮;软件实现检测到显示2、要求计数范围0~2000;脉冲输入有光电隔离整形,有清零按钮程序如下:ORG 0000HLJMP MAINORG 0003HLJMP 0100HORG 0013HLJMP 0150HORG 0050HMAIN: CLR AMOV 30H , A ;初始化缓存区MOV 31H , AMOV 32H , AMOV 33H , AMOV R6 , AMOV R7 , ASETB EASETB EX0SETB EX1SETB IT0SETB IT1SETB PX1NEXT1: ACALL HEXTOBCDD ;调用数制转换子程序ACALL DISPLAY ;调用显示子程序LJMP NEXT1ORG 0100H ;中断0服务程序MOV A , R7ADD A , #1MOV R7, AMOV A , R6ADDC A , #0MOV R6 , ACJNE R6 , #07H , NEXTCLR AMOV R6 , AMOV R7 , ANEXT: RETIORG 0150H ;中断1服务程序CLR AMOV R6 , AMOV R7 , ARETIORG 0200HHEXTOBCDD:MOV A , R6 ;由十六进制转化为十进制PUSH ACCMOV A , R7PUSH ACCMOV A , R2PUSH ACCCLR AMOV R3 , AMOV R4 , AMOV R5 , AMOV R2 , #10HHB3: MOV A , R7 ;将十六进制中最高位移入进位位中RLC AMOV R7 , AMOV A , R6RLC AMOV R6 , AMOV A , R5 ;每位数加上本身相当于将这个数乘以2 ADDC A , R5DA AMOV R5 , AMOV A , R4ADDC A , R4DA A ;十进制调整MOV R4 , AMOV A , R3ADDC A , R3DJNZ R2 , HB3POP ACCMOV R2 , APOP ACCMOV R7 , APOP ACCMOV R6 , ARETORG 0250HDISPLAY: MOV R0 , #30HMOV A , R5ANL A , #0FHMOV @R0 , AMOV A , R5SW AP AANL A , #0FHINC R0MOV @R0 , AMOV A , R4ANL A , #0FHINC R0MOV @R0 , AMOV A , R4SW AP AANL A , #0FHINC R0MOV @R0 , AMOV R0 , #30HMOV R2 , #11111110BAGAIN: MOV A , R2MOV P2 , AMOV A , @R0MOV DPTR , #TABMOVC A , @A+DPTRMOV P0 , AACALL DELAYINC R0MOV A , R2RL AMOV R2 , AJB ACC.4 , AGAINRETTAB: DB 03FH , 06H , 5BH , 4FH , 66H , 6DH , 7DH , 07H , 7FH , 6FH ;七段码表DELAY: MOV TMOD , #01H ;0.05s延时子程序MOV TL0 , #0B0HMOV TH0 , #3CHSETB TR0WAIT: JNB TF0 , WAITCLR TF0CLR TR0RETEND单片机的T1口计数,T0口定时,P1口输出段码,P2口位选,三位数码管显示 ORG 0000HAJMP MAINORG 000BHAJMP COUNTORG 0100HMAIN: MOV TMOD,#51HMOV TH1,#00HMOV TL1,#00HMOV TL0,#0B0HMOV TH0,#3CHSETB PT0SETB ET0SETB EASETB TR0SETB TR1WAIT: AJMP WAITCOUNT: MOV 30H,TL1MOV 31H,TH1LCALL BCDLCALL WFRETIBCD: MOV R1,30HMOV A,R1MOV B,#100DIV ABMOV 33H,AMOV A,BMOV B,#10DIV ABMOV 34H,AMOV 35H,BPLAY: MOV A,33HMOV DPTR,#TABMOVC A,@A+DPTRMOV P1,ASETB P2.2LCALL DELAYCLR P2.2MOV A,34HMOVC A,@A+DPTRMOV P1,ASETB P2.1LCALL DELAYCLR P2.1MOV A,35HMOVC A,@A+DPTRMOV P1,ASETB 2.0LCALL DELAYCLR P2.0RETTAB: DB 3FH,06H,5BH,4FH,66F,6DH,7DH,07H,7FH,6FHDELAY: MOV R5,#10HDE1: MOV R7,#5DE2: MOV R6,#20DE3: DJNZ R6,DE3DJNZ R7,DE2DJNZ R5,DE1RETWF: MOV TH1,#00HMOV TL1,#00HMOV TH0,#0B0HMOV TL0,#3CHSETB TR1SETB TR0RETENDCOUNT: CLR TR1CLR TR0MOV 30H,TL1MOV 31H,TH1LCALL BCDLCALL WFRETORG 0000HAJMP MAINORG 000BHAJMP COUNTORG 0100HMAIN: MOV TMOD,#51HMOV TH1,#00HMOV TL1,#00HMOV TL0,#0B0HSETB PT0SETB ET0SETB EASETB TR0SETB TR1WAIT: AJMP W AITCOUNT: MOV 30H,TL1MOV 31H,TH1LCALL BCDLCALL WFRETIBCD: MOV R1,30HMOV A,R1MOV B,#100DIV ABMOV 33H,AMOV A,BMOV B,#10DIV ABMOV 34H,AMOV 35H,BPLAY: MOV A,33HMOV DPTR,#TABMOVC A,@A+DPTRMOV P1,ASETB P2.2LCALL DELAYCLR P2.2MOV A,34HMOVC A,@A+DPTRMOV P1,ASETB P2.1LCALL DELAYCLR P2.1MOV A,35HMOVC A,@A+DPTRMOV P1,ASETB 2.0LCALL DELAYCLR P2.0RETTAB: DB 3FH,06H,5BH,4FH,66F,6DH,7DH,07H,7FH,6FHDE1: MOV R7,#5DE2: MOV R6,#20 DE3: DJNZ R6,DE3DJNZ R7,DE2DJNZ R5,DE1RETWF: MOV TH1,#00H MOV TL1,#00HMOV TH0,#0B0HMOV TL0,#3CHSETB TR1SETB TR0RETENDCOUNT: CLR TR1CLR TR0MOV 30H,TL1MOV 31H,TH1LCALL BCDLCALL WFRET。
单片机的定时及计数器实验-脉冲计数器

实验六单片机定时、计数器实验2——脉冲计数器一、实验目的1.AT89C51有两个定时/计数器,本实验中,定时/计数器1(T1)作定时器用,定时1s;定时/计数器0(T0)作计数器用。
被计数的外部输入脉冲信号从单片机的P3.4(T0)接入,单片机将在1s内对脉冲计数并送四位数码管实时显示,最大计数值为0FFFFH。
2.用proteus设计、仿真基于AT89C51单片机的脉冲计数器。
3.学会使用VSM虚拟计数/计时器。
二、电路设计1.从PROTEUS库中选取元件①AT89C51:单片机;②RES:电阻;③7SEG-BCD- GRN:七段BCD绿色数码管;④CAP、CAP-ELEC:电容、电解电容;⑤CRYSTAL:晶振;SEG-COM- GRN为带段译码器的数码管,其引脚逻辑状态如图所示。
对着显示的正方向,从左到右各引脚的权码为8、4、2、1。
2.放置元器件3.放置电源和地4.连线5.元器件属性设置6.电气检测7.虚拟检测仪器(1)VSM虚拟示波器单击小工具栏中的按钮,在对象选择器列表中单击COUNTER(计数/计时器),打开其属性编辑框,单击运行模式的下拉菜单,如图所示,可选择计时、频率、计数模式,当前设置其为频率计工作方式。
(2)数字时钟DCLOCK单击按钮,在对象选择器中选择DCLOCK(数字时钟)。
在需要添加信号的线或终端单击即可完成添加DCLOCK输入信号。
当前信号设置为DIGITAL型的时钟CLOCK,频率为50K。
三、源程序设计、生成目标代码文件1.流程图2.源程序设计通过菜单“sourc e→Add/Remove Source Files…”新建源程序文件:DZC36.ASM。
通过菜单“sourc e→DZC36.ASM”,打开PROTEUS提供的文本编辑器SRCEDIT,在其中编辑源程序。
程序编辑好后,单击按钮存入文件DZC32.ASM。
3.源程序编译汇编、生成目标代码文件通过菜单“sourc e→Build All”编译汇编源程序,生成目标代码文件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
南昌航空大学实验报告二0一一年九月二十九日课程名称:单片微型机实验名称:脉冲计数和电脑时钟程序班级: 080611 学生姓名:学号: 08061108 指导教师评定:签名:一、实验目的1、熟悉8031定时/计数功能,掌握定时/计数初始化编程方法;2、熟悉MCS—51定时器、串行口和中断初始化编程方法,了解定时器应用在实时控制中程序的设计技巧;3、编写程序,从DVCC系列单片机实验仪键盘上输入时间初值,用定时器产生0.1S定时中断,对时钟计数器计数,并将数值实时地送数码管显示。
二、实验内容及要求1、脉冲计数对定时器0外部输入的脉冲进行计数,并送显示器显示。
程序框图如下:图1 二进制转换子程序2、电脑时钟程序程序程序框图如下:图2 定时中断服务程序三、实验步骤及操作结果1、脉冲计数程序(1) 当DVCC 单片机仿真实验系统独立工作时1) 把8032CPU 的P3.4插孔接T0—T7任一根信号线或单脉冲输出空“SP ”。
2)用连续方式从起始地址02A0H 开始运行程序(按02A0后按EXEC 键)。
3)观察数码管显示的内容应为脉冲个数。
(2) 脉冲计数程序(源文件名:Cont .Asm )。
汇编程序代码如下: ORG 02A0H CONT: MOV SP,#53H MOV TMOD,#05H;初始化定时/计数器MOV TH0,#00H MOV TL0,#00H SETB TR0 ;允许定时/计数中断CONT1: MOV R2,TH0 ;取计数值MOV R3,TL0 LCALL CONT2 ;调二转十进制子程序MOV R0,#79H MOV A,R6 LCALL PWOR MOV A,R5 LCALL PWOR MOV A,R4 LCALL PWORLCALL DISP ;调显示子程序 SJMP CONT1 ;循环CONT2: CLR A ;清R4、R5、R6MOV R4,A MOV R5,A MOV R6,AMOV R7,#10H CONT3: CLR C ;R2、R3左移,移出的位送CY MOV A,R3 RLC AMOV R3,AMOV A,R2RLC AMOV R2,AMOV A,R6ADDC A,R6;R4、R5、R6×2 + CY送R4、R5、R6DA AMOV R6,A;十进制调整MOV A,R5ADDC A,R5DA AMOV R5,AMOV A,R4ADDC A,R4DA AMOV R4,ADJNZ R7,CONT3;循环16次RETPWOR: MOV R1,A ;CDATA: DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H ,80H,90HDB88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,8 9H,0DEH;拆送显示缓冲区LCALL PWOR1MOV A,R1SWAP APWOR1: ANL A,#0FHMOV @R0,AINC R0RETDISP: SETB 0D4H;显示子程序MOV R1,#7EHMOV R2,#20HMOV R3,#00HDISP1: MOV DPTR,#0FF21HMOV A,R2MOVX @DPTR,AMOV DPTR,#CDA TAMOV A,@R1MOVC A,@A+DPTRMOV DPTR,#0FF22HMOVX @DPTR,A DISP2: DJNZ R3,DISP2DEC R1CLR CMOV A,R2RRC AMOV R2,AJNZ DISP1MOV A,#0FFHMOV DPTR,#0FF22HMOVX @DPTR,ACLR 0D4HRET2、电脑时钟程序(1)用连续方式从起始地址0340H开始执行程序(输入0340后按EXEC键)。
(2)连续运行程序,在键盘上输入时间初值。
如果输入时分秒初值超范围,则显示000000后要求重新设置初值,初值的默认值为000000。
(3)再次按EXEC键时钟开始工作,数码管上实时显示时间值。
(4)电脑时钟程序(源文件名:Cock.Asm)。
汇编程序代码如下。
ORG 000BHLJMP TINTRUPORG 0340hCLOCK0: MOV SP,#50HMOV R0,#7EH;清显示缓冲区MOV R4,#06HCLR ACLOCK1:MOV @R0,ADEC R0DJNZ R4,CLOCK1MOV A,#7EHMOV DPTR,#1FFFHMOVX @DPTR,AMOV 76H,#00H;初始化定时/计数器MOV 77H,#00HLCALL KEYDISP0;调显示键扫子程序LCALL DISDA0;调显示缓冲区放数程序MOV TMOD,#01HORL IE,#82HMOV TL0,#0B7HMOV TH0,#3CHMOV 23H,#00HSETB TR0 ;开定时中断CLOCK2: LCALL DISP;调显示子程序LCALL DISDA0;调显示缓冲区放数子程序SJMP CLOCK2 ;循环DISDA0: MOV R0,#79H;显示缓冲区放数子程序MOV A,22HACALL DISDAMOV A,21HACALL DISDAMOV A,20HACALL DISDARETDISDA: MOV R1,AACALL DISDA1MOV A,R1SWAP ADISDA1: ANL A,#0FHMOV @R0,AINC R0RETTINTRUP: MOV TL0,#0B7H;定时器中断服务程序MOV TH0,#3CH;重新置初值PUSH PSWPUSH ACC;保护当前值SETB 0D3HINC 23H;0.1秒单元加1MOV A,23HCJNE A,#0AH,TINTRUP1;判1秒到否,未到继续MOV 23H,#00H;清0.1秒单元MOV A,22HINC A;秒单元加1DA AMOV 22H,ACJNE A,#60H,TINTRUP1;判60秒到否,未到继续MOV 22H,#00H;清秒计数单元MOV A,21HINC A;分单元加1DA AMOV 21H,ACJNE A,#60H,TINTRUP1;判60分到否,未到继续MOV 21H,#00H;清分计数单元MOV A,20HINC A;时单元加1DA AMOV 20H,ACJNE A,#24H,TINTRUP1;判24小时到否,未到继续MOV 20H,#00H;清时计数单元TINTRUP1:POP ACCPOP PSWRETI;返回主程序KEYDISP0:LCALL KEY;调显示键扫子程序JNC FANCKEY;转功能键处理DA TAKEY: LCALL DATAKEY1;数值键处理DB 79H,7EHSJMP KEYDISP0 FANCKEY: CJNE A,#16H,KEYDISP0 ;是执行键,判输入的秒初值是否超限MOV A,7AHSWAP AORL A,79HMOV 22H,ACJNE A,#60H,FANCKEY1 FANCKEY1: JNC FANCKEY4;判输入的分初值是否超限MOV A,7CHSWAP AORL A,7BHMOV 21H,ACJNE A,#60H,FANCKEY2 FANCKEY2: JNC FANCKEY4;判输入的时初值是否超限MOV A,7EHSWAP AORL A,7DHMOV 20H,ACJNE A,#24H,FANCKEY3 FANCKEY3:JNC FANCKEY4RETFANCKEY4:CLR TR0LJMP CLOCK0DA TAKEY1:MOV R4,A;数字键处理子程序MOV DPTR,#1FFFHMOVX A,@DPTRMOV R1,AMOV A,R4MOV @R1,ACLR APOP 83HPOP 82HMOVC A,@A+DPTRINC DPTRCJNE A,01H,DATAKEY3DEC R1CLR AMOVC A,@A+DPTR DATAKEY2: PUSH 82HPUSH 83HMOV DPTR,#1FFFHMOVX @DPTR,APOP 83HPOP 82HINC DPTRPUSH 82HPUSH 83HRETDATAKEY3: DEC R1MOV A,R1SJMP DATAKEY2KEY0: MOV R6,#20H;数字键闪动程序MOV DPTR,#1FFFHMOVX A,@DPTRMOV R0,AMOV A,@R0MOV R7,AMOV A,#10HMOV @R0,AKEY3: LCALL KEYDISPJNB 0E5H,KEY2DJNZ R6,KEY3MOV DPTR,#1FFFHMOVX A,@DPTRMOV R0,AMOV A,R7MOV @R0,AKEY: MOV R6,#50HKEY1: LCALL KEYDISPJNB 0E5H,KEY2DJNZ R6,KEY1SJMP KEY0KEY2: MOV R6,AMOV A,R7MOV @R0,AMOV A,R6;A = 键值KEYEND: RETKEYDISP:LCALL DISP;调用显示子程序LCALL KEYSM;调用键扫子程序MOV R4,A;键值存R4MOV R1,#76HMOV A,@R1MOV R2,AINC R1MOV A,@R1MOV R3,AXRL A,R4MOV R3,04HMOV R4,02HJZ KEYDISP1MOV R2,#88HMOV R4,#88H KEYDISP1: DEC R4MOV A,R4XRL A,#82HJZ KEYDISP2MOV A,R4XRL A,#0EHJZ KEYDISP2MOV A,R4ORL A,R4JZ KEYDISP3MOV R4,#20HDEC R2LJMP KEYDISP5 KEYDISP3: MOV R4,#0FH KEYDISP2: MOV R2,04HMOV R4,03HKEYDISP5: MOV R1,#76HMOV A,R2MOV @R1,AINC R1MOV A,R3MOV @R1,AMOV A,R4CJNE R3,#10H,KEYDISP4 KEYDISP4: RETDISP: SETB 0D4H ;显示子程序MOV R1,#7EHMOV R2,#20HMOV R3,#00HDISP1: MOV DPTR,#0FF21HMOV A,R2MOVX @DPTR,AMOV DPTR,#DATACOMOV A,@R1MOVC A,@A+DPTRMOV DPTR,#0FF22HMOVX @DPTR,ADISP2: DJNZ R3,DISP2DEC R1CLR CMOV A,R2RRC AMOV R2,AJNZ DISP1MOV A,#0FFHMOV DPTR,#0FF22HMOVX @DPTR,ACLR 0D4HRETDA TACO: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90HDB 88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,89H,0DEH 键扫子程序KEYSM:SETB 0D4HMOV A,#0FFHMOV DPTR,#0FF22HMOVX @DPTR,A KEYSM0: MOV R2,#0FEHMOV R3,#08HMOV R0,#00H KEYSM1: MOV A,R2 MOV DPTR,#0FF21H MOVX @DPTR,A;键矩阵中第1列置0 NOPRL AMOV R2,AMOV DPTR,#0FF23H ;读键的行值MOVX A,@DPTRCPL ANOPNOPNOPANL A,#0FHJNZ KEYSM2INC R0;无键且未到最后一列继续DJNZ R3,KEYSM1SJMP KEYSM10 KEYSM2: ;有键,计算键值CPL AJB 0E0H,KEYSM3MOV A,#00HSJMP KEYSM7 KEYSM3: JB 0E1H,KEYSM4MOV A,#08HSJMP KEYSM7 KEYSM4: JB 0E2H,KEYSM5MOV A,#10HSJMP KEYSM7 KEYSM5: JB 0E3H,KEYSM10MOV A,#18HKEYSM7: ADD A,R0CLR 0D4HCJNE A,#10H,KEYSM9 KEYSM9: JNC KEYSM10MOV DPTR,#KEYDATAMOVC A,@A+DPTR KEYSM10: RET ;返回KEYDATA: DB 07H,04H,08H,05H,09H,06H,0AH,0BH ;键值表(0—F)DB 01H,00H,02H,0FH,03H,0EH,0CH,0DH3、实验编译、调试及联接点击编译程序,如果编译正确,则点击联接按钮,显示联接成功后,点击窗口显示反汇编窗口、数显示据窗口、显示寄存器窗口等具体信息,再观察联接的硬件显示情况,并进行分析。