单片机—实时时钟实验(汇编版)
单片机数字时钟实验报告

数字时钟实验报告一、实验目的:通过实验进一步深刻理解单片机最小系统的工作原理。
着重掌握中断和定时器的使用,以及读键盘和LED显示程序的设计(具体设计在后面会涉及到)。
培养动手能力。
二、实验内容:使用单片机最小系统设计一个12小时制自动报时的数字时钟。
三、功能描述:★使用低六位数码管显示时、分、秒、使用第七位表示上午和下午。
符号A表示上午;符号P表示下午。
★通过按键分别调整小时位和分钟位。
★到达整点时以第八位数码管闪烁的方式报时,使用8作为显示内容。
★考虑整点报时功能。
四、设计整体思路以及个别重点部分的具体实现方式:下面这幅图展示主函数的流程下面描述的是调用T0中断时所进行的动作显示更新的函数具体见下面这幅图我们还一个对键盘进行扫描以获得有效键盘值,其具体的实现见下面这幅图● 要实现时钟的运行和时间的调整,我的设计思路是这样的:由于T0中断的时间间隔是4ms,那么我可以设置一个计数器i,在每次进入中断时进行加一调整,当i计满面250时就将时钟我秒的低位加一。
然后根据进位规则,对其后的各位依次进行调整。
●要实现整点报时功能,则可以根据时位是否为0判断是否要闪烁显示字符8。
至于闪烁的具体实现方式,见源程序。
至此,本实验的设计思路己基本介绍完毕。
下面就是本次实验的源程序代码。
/*********************************************************//** 数字时钟程序**//** **//*********************************************************/#include <absacc.h>#include <reg51.h>#define uchar unsigned char#define uint8 unsigned char#define uint16 unsigned int#define LED1 XBYTE [0xA000] //数码管地址#define LED2 XBYTE [0xA001]#define LED3 XBYTE [0xA002]#define LED4 XBYTE [0xA003]#define LED5 XBYTE [0xA004]#define LED6 XBYTE [0xA005]#define LED7 XBYTE [0xA006]#define LED8 XBYTE [0xA007]#define KEY XBYTE [0xA100] //键盘地址bit ap=0;//上下午int i=0;//计数器uchar data clock[7]={0,0,0,0,0,0,0};/*扫描键盘使用的变量 */sbit first_row = P1^4; //键盘第一行控制sbit second_row = P1^3; //键盘第二行控制bit first_getkey = 0,control_readkey = 0; //读键盘过程中的标志位bit getkey = 0; //获得有效键值标志位等于1时代表得到一个有效键值bit keyon = 0; //防止按键冲突标志位uchar keynum = 0; //获得的有效按键值寄存器/*数码管显示使用的变量和常量*/uchar lednum = 0; //数码管显示位控制寄存器uchar led[8] = {0,0,0,0,0,0,0,0}; //数码管显示内容寄存器uchar code segtab[18] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x8c,0xff}; //七段码段码表// "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D","E", "F", "P" ,"black"void leddisp(void); //数码管显示函数void readkey(void); //读键盘函数void intT0() interrupt 1 //T0 定时中断处理函数{TH0 = -2720/256; //定时器中断时间间隔 4msTL0 = -2720%256;if((clock[2]==0)&&(clock[3]==0)&&(i==125)&&(clock[5]<=5)&&(clock[4]==0))led[7]=17;if((clock[2]==0)&&(clock[3]==0)&&(i==0)&&(clock[5]<=5)&&(clock[4]==0))led[7]=8;i=i+1;if(i==250){if((clock[2]==0)&&(clock[3]==0)&&(clock[4]==0)&&(clock[5]==0)&&(clock[6]==0)){ap=!ap;if(ap==0)led[6]=10;if(ap==1)led[6]=16;}clock[5]=clock[5]+1;i=0;}if(clock[5]==10){clock[5]=0;clock[4]=clock[4]+1;}if(clock[4]==6){clock[4]=0;clock[3]=clock[3]+1;}if(clock[3]==10){clock[3]=0;clock[2]=clock[2]+1;}if(clock[2]==6){clock[2]=0;clock[6]=clock[6]+1;}if(clock[6]==12){clock[6]=0;}clock[0]=clock[6]/10;clock[1]=clock[6]%10;led[5]=clock[0];led[4]=clock[1];led[3]=clock[2];led[2]=clock[3];led[1]=clock[4];led[0]=clock[5];leddisp(); //每次定时中断显示更新一次if(control_readkey == 1) //每两次定时中断扫描一次键盘{readkey();}c ontrol_readkey = !control_readkey;}void main(void){TMOD = 0x01; //TH0 = -2720/256; //定时器中断时间间隔 4msTL0 = -2720%256;TCON = 0x10;ET0 = 1;EA = 1;while(1){if(getkey == 1) //判断是否获得有效按键{getkey = 0;switch(keynum) //判断键值,对不同键值采取相应的用户定义处理方式{case 0x01: //当按下第一行第二列键时,分加一clock[3]=clock[3]+1;break;case 0x02: ////当按下第一行的第三列键时,分减一clock[3]=clock[3]-1;break;case 0x03://当按下第一行的第四列时,时加一clock[6]=clock[6]+1;break;case 0x04:clock[6]=clock[6]-1; //当按下第一行的第五列时,时减一break;default:break;}}}}/***************************************************键盘扫描函数原型: void readkey(void);功能: 当获得有效按键时,令getkey=1,keynum为按键值****************************************************/void readkey(void){uchar M_key = 0;second_row = 0;M_key = KEY;if(M_key != 0xff) //如果有连续两次按键按下,认为有有效按键按下。
单片机的实时时钟设计》

单片机的实时时钟设计》引言:实时时钟是嵌入式系统中常用的功能之一,可以实现对时间的准确计时和显示功能。
本文将以数码管显示为例,介绍单片机实时时钟的设计过程。
一、硬件设计1.单片机选择实时时钟通常需要较强的计算能力和丰富的IO口,方便与其他外设进行通信。
常用的单片机有STC89C52、AT89C51等。
本设计选择STC89C52单片机。
2.数码管显示选择常用的共阴极数码管进行显示。
数码管可以通过74HC595芯片进行驱动,将单片机的IO口扩展为8位,方便控制多个数码管的显示。
3.时钟芯片本设计选择DS1302时钟芯片作为实时时钟的核心。
DS1302芯片具有低功耗、精度高、抗干扰能力强等特点。
二、软件设计1.引入头文件#include <reg52.h> // 引入单片机头文件#include "DS1302.h" // 引入DS1302头文件,包含了DS1302芯片的驱动函数2.数码管显示函数void display(unsigned char *t)unsigned char i;unsigned char code table[] = { // 0-9的显示码0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};for(i = 0; i < 6; i++) // 依次显示年、月、日、时、分、秒P0=0xFF;//所有数码管熄灭P2=0x01<<i;//选择一些数码管P0 = table[t[i]]; // 数码管显示对应的数字Delay(1); // 延时一段时间}3.主函数void mainwhile(1)Delay(100); // 延时一段时间,例如100ms}4.初始化函数void InitDS1302_Init(; // DS1302芯片初始化5.主函数调用void mainInit(; // 调用初始化函数while(1)Display(; // 显示函数Count(; // 计数函数}结论:通过以上的硬件设计和软件编写,我们可以实现单片机的实时时钟功能,并通过数码管进行显示。
单片机电子时钟课程设计实验报告(1)

单片机电子时钟课程设计实验报告(1)单片机电子时钟课程设计实验报告一、实验内容本次实验的主要内容是使用单片机设计一个电子时钟,通过编程控制单片机,实现时钟的显示、报时、闹钟等功能。
二、实验步骤1.硬件设计根据实验要求,搭建电子时钟的硬件电路,包括单片机、时钟模块、显示模块、按键模块等。
2.软件设计通过C语言编写单片机程序,用于实现时钟功能。
3.程序实现(1)时钟显示功能通过读取时钟模块的时间信息,在显示模块上显示当前时间。
(2)报时功能设置定时器,在每个整点时,通过发出对应的蜂鸣声,提示时间到达整点。
(3)闹钟功能设置闹钟时间和闹铃时间,在闹钟时间到达时,发出提示蜂鸣,并在屏幕上显示“闹钟时间到了”。
(4)时间设置功能通过按键模块实现时间的设置,包括设置小时数、分钟数、秒数等。
(5)年月日设置功能通过按键模块实现年月日的设置,包括设置年份、月份、日期等。
三、实验结果经过调试,电子时钟的各项功能都能够正常实现。
在运行过程中,时钟能够准确、稳定地显示当前时间,并在整点时提示时间到达整点。
在设定的闹铃时间到达时,能够发出提示蜂鸣,并在屏幕上显示“闹钟时间到了”。
同时,在需要设置时间和年月日信息时,也能够通过按键进行相应的设置操作。
四、实验感悟通过本次实验,我深刻体会到了单片机在电子设备中的广泛应用以及C 语言在程序设计中的重要性。
通过实验,我不仅掌握了单片机的硬件设计与编程技术,还学会了在设计电子设备时,应重视系统的稳定性与可靠性,并善于寻找调试过程中的问题并解决。
在今后的学习和工作中,我将继续加强对单片机及其应用的学习与掌握,努力提升自己的实践能力,为未来的科研与工作做好充分准备。
单片机电子时钟报告及汇编代码

单片机电子日历时钟设计一、设计的目的及其意义(1)巩固、加深和扩大51系列单片机应用的知识面,提高综合及灵活运用所学知识解决工业控制的能力;(2)培养针对课题需要,选择和查阅有关手册、图表及文献资料的自学能力,提高组成系统、编程、调试的动手能力;(3)对课题设计方案的分析、选择、比较、熟悉用51单片机做系统开发、研制的过程,软硬件设计的方法、内容及步骤。
二、本实验设计的功能2.1 基本功能1)显示北京时间2)校准时间;3)使用汇编语言4)时、分、秒之间或年、月、日间以小数点分隔;2.2 扩展功能(1)显示公历日期(2)校准日期(3)运动秒表(4)闹钟功能三、总体设计方案本实验使用汇编语言设计,程序的流程图大致如下:主程序流程图:显示闹钟子程序流程图:运动秒表子程序流程图:校准闹钟,日期和时间的子程序流程图:四、源程序ORG 0000HAJMP BEGINORG 000BHLJMP TINTOYEARH EQU 30H ;年高位存放地址YEARL EQU 31H ;年低位存放地址MONTH EQU 32H ;月存放地址DAY EQU 33H ;日存放地址HOUR EQU 34H ;时存放地址MIN EQU 35H ;分存放地址SEC EQU 36H ;秒存放地址MSEC EQU 37H ;10ms存放地址SECM EQU 38HYDMSEC EQU 39H ;运动秒针存放地址YDSECM EQU 40HBEEP BIT P1^3 ;蜂鸣器AHOUR EQU 41H ;闹钟时存放地址AMIN EQU 42H ;闹钟分存放地址DEDA EQU 43H ;5ms计数值PFOUR BIT P0.4PFIVE BIT P0.5PSIX BIT P0.6PSEVEN BIT P0.7BEGIN:CALL INITIALLOOP:CALL SHOW_TIME1 ;默认为显示时间CALL RINGCALL SCAN_KEY ;键盘扫描CJNE A,#0EEH,JUDGE1 ;如果A=EEH,则显示日期年和月CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE1CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2CALL SHOW_DATE2JUDGE1:CJNE A,#0DEH,JUDGE2 ;如果A=DEH,则显示闹钟SA:CALL SHOW_ALARMCALL SCAN_KEYCJNE A,#0EEH,SA ;在显示闹钟时按下EEH键则是返回时间模式JUDGE2:CJNE A,#0EDH,JUDGE3 ;如果A=EDH,则依次调闹钟,日期和时间CALL ADJUSTJUDGE3:CJNE A,#0DDH,JUDGE4 ;如果A=DDH,则显示时间分,秒ST2:CALL SHOW_TIME2CALL SCAN_KEYCJNE A,#0EDH,OTHER ;在显示分,秒时按下EDH 键则是运动秒表模式CLRYD:MOV MSEC,#0MOV SECM,#0AJMP ST3OTHER:CJNE A,#0EEH,ST2 ;按下EEH键则是返回时间模式AJMP JUDGE4ST3: ;运动秒表计时开始MOV YDMSEC,MSECMOV YDSECM,SECMCALL SHOW_TIME3CALL SCAN_KEYCJNE A,#0DEH,ST3 ;按下DEH键则是停止秒表STOP:CALL SHOW_TIME3CALL SCAN_KEYCJNE A,#0DDH,OW ;按下DDH键,运动秒表则从零从新开始计时AJMP CLRYDOW: CJNE A,#0EDH,OTHERWISE ;按下EDH键则继续运动秒表的计时,仍按DEH停止秒表MOV MSEC,YDMSECMOV SECM,YDSECMAJMP ST3OTHERWISE:CJNE A,#0EEH,STOP ;按下EEH键返回时间模式JUDGE4:AJMP LOOPRING: ;若闹钟时钟为24,则闹钟为关闭状态MOV A,HOURCJNE A,AHOUR,RTMOV A,MINCJNE A,AMIN,RTCLR BEEPRT:RETSHOW_TIME1: ;显示时间(时和分)MOV DPTR,#TABLE ;数字编码表基址MOV A,MIN ;显示分,minMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#04H ;点亮第三个数码管CALL SHOW ;显示数值CALL DELAYMOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#08H ;点亮第四个数码管CALL SHOWCALL DELAYMOV A,HOUR ;显示小时,hourMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#01H ;点亮第一个数码管CALL SHOWCALL DELAYMOV DPTR,#TABLE2MOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#02H ;点亮第二个数码管CALL SHOWCALL DELAYMOV P0,#00HRETSHOW_TIME2: ;显示时间(分和秒)MOV DPTR,#TABLE ;数字编码表基址MOV A,SEC ;显示秒,secMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#04H ;点亮第三个数码管CALL SHOWCALL DELAYMOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#08H ;点亮第四个数码管CALL SHOWCALL DELAYMOV A,MIN ;显示分钟minMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#01H ;点亮第一个数码管CALL SHOWCALL DELAYMOV DPTR,#TABLE2MOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#02H ;点亮第二个数码管CALL SHOWCALL DELAYMOV P0,#00H ;P0置零,熄灭数码管RETSHOW_TIME3: ;显示运动秒针(s和10ms) MOV DPTR,#TABLE ;数字编码表基址MOV A,YDMSEC ;显示10msMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#04H ;点亮第三个数码管CALL SHOWCALL DELAYMOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#08H ;点亮第四个数码管CALL SHOWCALL DELAYMOV A,YDSECM ;显示秒MOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#01H ;点亮第一个数码管CALL SHOWCALL DELAYMOV DPTR,#TABLE2MOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#02H ;点亮第二个数码管CALL SHOWCALL DELAYMOV P0,#00H ;P0置零,熄灭数码管RETSHOW_DATE1: ;显示日期(年)MOV DPTR,#TABLE ;数字编码表基址MOV A,YEARHMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#01HCALL SHOWCALL DELAYMOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#02HCALL SHOWCALL DELAYMOV A,YEARLMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#04HCALL SHOWCALL DELAYMOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#08HCALL SHOWCALL DELAYRETSHOW_DATE2: ;显示日期(月和日)MOV DPTR,#TABLE ;数字编码表基址MOV A,DAYMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#04H ;点亮第3个数码管CALL SHOWCALL DELAYMOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#08H ;点亮第4个数码管CALL SHOWCALL DELAYMOV A,MONTHMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#01H ;点亮第1个数码管CALL SHOWCALL DELAYMOV DPTR,#TABLE2MOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#02H ;点亮第2个数码管CALL SHOWCALL DELAYMOV P0,#00HRETADJUST: ;调整闹钟,日期和时间ALARM1: ;调整闹钟的小时数MOV DPTR,#TABLEMOV A,AHOURMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#01H ;点亮第一个数码管CALL SHOWCALL DELAYMOV DPTR,#TABLE2MOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#02H ;点亮第二个数码管CALL SHOWCALL DELAYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCJNE A,#0DEH,CHECK1 ;如果A=DEH,则闹钟小时加1MOV A,AHOURCJNE A,#24,INC1MOV AHOUR,#0CALL LDELAYAJMP ALARM1INC1:INC AMOV AHOUR,ACALL LDELAYAJMP ALARM1CHECK1:CJNE A,#0EEH,CHECK2 ;如果A=EEH,则闹钟小时减1MOV A,AHOURCJNE A,#0,DEC1MOV AHOUR,#24 ;当闹钟时钟调到24的时候,则相当于关闭闹钟CALL LDELAYAJMP ALARM1DEC1:DEC AMOV AHOUR,ACALL LDELAYAL1:AJMP ALARM1CHECK2:CJNE A,#0DDH,CHECK3 ;如果A=DDH,则返回RETCHECK3:CJNE A,#0EDH,AL1 ;如果A=EDH,则调整闹钟的分钟数ALARM2: ;调整闹钟的分钟数MOV DPTR,#TABLEMOV A,AMINMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#04H ;点亮第三个数码管CALL SHOW ;显示数值CALL DELAYMOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#08H ;点亮第四个数码管CALL SHOWCALL DELAYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCJNE A,#0DEH,CHECK4 ;如果A=DEH,则闹钟分钟加1 MOV A,AMINCJNE A,#59,INC2MOV AMIN,#0CALL LDELAYAJMP ALARM2INC2:INC AMOV AMIN,ACALL LDELAYAJMP ALARM2CHECK4:CJNE A,#0EEH,CHECK5 ;如果A=EEH,则闹钟小时减1 MOV A,AMINCJNE A,#0,DEC2MOV AMIN,#59CALL LDELAYAJMP ALARM2DEC2:DEC AMOV AMIN,ACALL LDELAYAL2:AJMP ALARM2CHECK5:CJNE A,#0DDH,CHECK6 ;如果A=DDH,则返回RETCHECK6:CJNE A,#0EDH,AL2 ;如果A=EDH,则调整日期(年)DA TE1: ;调整年的高位MOV DPTR,#TABLEMOV A,YEARHMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#01H ;点亮第一个数码管CALL SHOWCALL DELAYMOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#02H ;点亮第二个数码管CALL SHOWCALL DELAYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCJNE A,#0DEH,CHECKYH1 ;如果A=DEH,则日期年高位加1MOV A,YEARHCJNE A,#99,INCYRH1MOV YEARH,#0CALL LDELAYAJMP DA TE1INCYRH1:INC AMOV YEARH,ACALL LDELAYAJMP DA TE1CHECKYH1:CJNE A,#0EEH,CHECKYH2 ;如果A=EEH,则日期年高位减1MOV A,YEARHCJNE A,#0,DECYRH1MOV YEARH,#99CALL LDELAYAD1:AJMP DA TE1DECYRH1:DEC AMOV YEARH,ACALL LDELAYAJMP DA TE1CHECKYH2:CJNE A,#0DDH,CHECKYH3 ;如果A=DDH,则返回RETCHECKYH3:CJNE A,#0EDH,AD1 ;如果A=EDH,则调整日期年的低位DA TE2: ;调整年的低位MOV DPTR,#TABLEMOV A,YEARLMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#04H ;点亮第3个数码管CALL SHOWCALL DELAYMOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#08H ;点亮第4个数码管CALL SHOWCALL DELAYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCJNE A,#0DEH,CHECKYL1MOV A,YEARLCJNE A,#99,INCYRL1MOV YEARL,#0CALL LDELAYAJMP DA TE2INCYRL1: ;年低位加1INC AMOV YEARL,ACALL LDELAYAJMP DA TE2CHECKYL1:CJNE A,#0EEH,CHECKYL2MOV A,YEARLCJNE A,#0,DECYRL1MOV YEARL,#99CALL LDELAYAD2: AJMP DA TE2DECYRL1: ;年低位减1DEC AMOV YEARL,ACALL LDELAYAJMP DA TE2CHECKYL2:CJNE A,#0DDH,CHECKYL3 ;返回RETCHECKYL3:CJNE A,#0EDH,AD2 ;跳到调整月,日MON:MOV DPTR,#TABLEMOV A,MONTHMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#01H ;点亮第一个数码管CALL SHOWCALL DELAYMOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#02H ;点亮第二个数码管CALL SHOWCALL DELAYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCJNE A,#0DEH,CHECKM1 ;如果A=DEH,则月份加1MOV A,MONTHCJNE A,#12,INCM1MOV MONTH,#1CALL LDELAYAM: AJMP MONINCM1:INC AMOV MONTH,ACALL LDELAYAJMP MONCHECKM1:CJNE A,#0EEH,CHECKM2 ;如果A=EEH,则月份减1MOV A,MONTHCJNE A,#1,DECM1MOV MONTH,#12CALL LDELAYAJMP MONDECM1:DEC AMOV MONTH,ACALL LDELAYAJMP MONCHECKM2:CJNE A,#0DDH,CHECKM3 ;如果A=DDH,则返回RETCHECKM3:CJNE A,#0EDH,AM ;如果A=EDH,则调整日ADAY:MOV DPTR,#TABLEMOV A,DAYMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#04H ;点亮第3个数码管CALL SHOWCALL DELAYMOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#08H ;点亮第4个数码管CALL SHOWCALL DELAYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCJNE A,#0DEH,CH1 //如果A=DEH,判断月份MOV A,MONTHCJNE A,#1,N2AJMP T31N2:CJNE A,#2,N3AJMP T2N3:CJNE A,#3,N4AJMP T31N4:CJNE A,#4,N5AJMP T30N5:CJNE A,#5,N6AJMP T31N6:CJNE A,#6,N7AJMP T30N7:CJNE A,#7,N8AJMP T31N8:CJNE A,#8,N9AJMP T31N9:CJNE A,#9,N10AJMP T30N10:CJNE A,#10,N11AJMP T31N11:CJNE A,#11,T31AJMP T30CH1:AJMP CHECKD1T31: //该月份有31天MOV A,DAYCJNE A,#31,INCD1 //判断是否为31号MOV DAY,#0CALL LDELAYAJMP ADAYINCD1:INC AMOV DAY,ACALL LDELAYAJMP ADAYT30: //该月份有30天MOV A,DAYCJNE A,#30,INCDD1 //判断是否为30号MOV DAY,#0CALL LDELAYAJMP ADAYINCDD1:INC AMOV DAY,ACALL LDELAYAJMP ADAYT2: ;特殊的2月MOV B,#4MOV A,YEARLCJNE A,#0,NORMAL1AJMP CENTURY1NORMAL1:DIV ABMOV A,BCJNE A,#0,COMMON1BISSEXTILE1:MOV A,DAY ;闰年CJNE A,#29,INC2DAY ;未够29天MOV DAY,#1CALL DELAYAJMP ADAYINC2DAY:INC DAYCALL LDELAYAJMP ADAYCOMMON1:MOV A,DAY ;平年CJNE A,#28,INC2DAY2 ;未够28天MOV DAY,#1CALL DELAYAJMP ADAYINC2DAY2:INC DAYCALL LDELAYAJMP ADAYCENTURY1: ;世纪年MOV A,YEARHDIV ABMOV A,BCJNE A,#0,COMMON1AJMP BISSEXTILE1CHECKD1:CJNE A,#0EEH,CH2MOV A,MONTHCJNE A,#1,NN2AJMP U31NN2:CJNE A,#2,NN3AJMP U2NN3:CJNE A,#3,NN4AJMP U31NN4:CJNE A,#4,NN5AJMP U30NN5:CJNE A,#5,NN6AJMP U31NN6:CJNE A,#6,NN7AJMP U30NN7:CJNE A,#7,NN8AJMP U31NN8:CJNE A,#8,NN9AJMP U31NN9:CJNE A,#9,NN10AJMP U30NN10:CJNE A,#10,NN11AJMP U31NN11:CJNE A,#11,U31AJMP U30CH2:AJMP CHECKD2U31:MOV A,DAYCJNE A,#0,DECD1MOV DAY,#31CALL LDELAYAJMP ADAYDECD1:DEC AMOV DAY,ACALL LDELAYAJMP ADAYU30:MOV A,DAYCJNE A,#0,DECDD1MOV DAY,#30CALL LDELAYAJMP ADAYDECDD1:DEC AMOV DAY,ACALL LDELAYAJMP ADAYU2: ;特殊的2月MOV A,YEARLCJNE A,#0,NORMAL2AJMP CENTURY2NORMAL2:DIV ABMOV A,BCJNE A,#0,COMMON2BISSEXTILE2:MOV A,DAY ;闰年CJNE A,#1,DEC2DAY ;未够29天MOV DAY,#29CALL DELAYAJMP ADAYDEC2DAY:DEC DAYCALL LDELAYAJMP ADAYCOMMON2:MOV A,DAY ;平年CJNE A,#1,DEC2DAY2 ;未够28天MOV DAY,#28CALL DELAYAJMP ADAYDEC2DAY2:DEC DAYCALL LDELAYADA:AJMP ADAYCENTURY2: ;世纪年MOV A,YEARHDIV ABMOV A,BCJNE A,#0,COMMON2AJMP BISSEXTILE2CHECKD2:CJNE A,#0DDH,CHECKD3 ;如果A=DDH,则返回RETCHECKD3:CJNE A,#0EDH,ADA ;如果A=EDH,则调整时间;跳到调整月,日TIME1: ;调整时间的小时数MOV DPTR,#TABLEMOV A,HOURMOV B,#10MOVC A,@A+DPTRANL P0,#0F0HORL P0,#01H ;点亮第一个数码管CALL SHOWCALL DELAYMOV DPTR,#TABLE2MOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#02H ;点亮第二个数码管CALL SHOWCALL DELAYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCJNE A,#0DEH,CHECKT1 ;时间小时数加1 MOV A,HOURCJNE A,#23,INCT1MOV HOUR,#0CALL LDELAYAJMP TIME1INCT1:INC AMOV HOUR,ACALL LDELAYAJMP TIME1CHECKT1:CJNE A,#0EEH,CHECKT2MOV A,HOURCJNE A,#0,DECT1MOV HOUR,#23CALL LDELAYTI1:AJMP TIME1DECT1: ;时间小时数减1 DEC AMOV HOUR,ACALL LDELAYAJMP TIME1CHECKT2:CJNE A,#0DDH,CHECKT3RETCHECKT3:CJNE A,#0EDH,TI1 ;调整时间的分钟数TIME2:MOV DPTR,#TABLE ;数字编码表基址MOV A,MINMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#04H ;点亮第三个数码管CALL SHOW ;显示数值CALL DELAYMOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#08H ;点亮第四个数码管CALL SHOWCALL DELAYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCALL SCAN_KEYCJNE A,#0DEH,CHECKT4MOV A,MINCJNE A,#59,INCT2MOV MIN,#0CALL LDELAYLJMP TIME2INCT2: ;时间分钟数加1 INC AMOV MIN,ACALL LDELAYLJMP TIME2CHECKT4:CJNE A,#0EEH,CHECKT5MOV A,MINCJNE A,#0,DECT2MOV MIN,#59CALL LDELAYLJMP TIME2DECT2: ;时间分钟数减1 DEC AMOV MIN,ACALL LDELAYTI2:LJMP TIME2CHECKT5:CJNE A,#0DDH,CHECKT6RETCHECKT6:CJNE A,#0EDH,TI2RETSHOW_ALARM: ;显示闹钟MOV DPTR,#TABLE ;数字编码表基址MOV A,AMINMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#04H ;点亮第三个数码管CALL SHOWCALL DELAYMOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#08H ;点亮第四个数码管CALL SHOWCALL DELAYMOV A,AHOURMOV B,#10DIV ABMOVC A,@A+DPTRANL P0,#0F0HORL P0,#01H ;点亮第一个数码管CALL SHOWCALL DELAYMOV DPTR,#TABLE2MOV A,BMOVC A,@A+DPTRANL P0,#0F0HORL P0,#02H ;点亮第二个数码管CALL SHOWCALL DELAYMOV P0,#00HRETSCAN_KEY: ;P2低4位控制行,高4位控制列MOV P2,#0FH ;行扫描MOV A,P2CJNE A,#0FH,KEY1 ;A不等于#0F,表示当前有键按下KEY1:CALL DELAYMOV A,P2CJNE A,#0FH,SCAN1 ;延时排除按键抖动情况MOV A,#0FFHRETSCAN1:MOV A,P2 ;记录行状态SCAN2:MOV P2,#0F0H ;列扫描MOV R6,P2ORL A,R6 ;行列读取结果相或得出键值,由A存放键值:RETINITIAL:MOV YEARH,#20 ;初始化控制变量MOV YEARL,#13MOV MONTH,#09MOV DAY,#20MOV HOUR,#10MOV MIN,#30MOV SEC,#46MOV MSEC,#00MOV SECM,#00MOV DEDA,#00MOV AHOUR,#10MOV AMIN,#31;对涉及到的中断,进行设置SETB EA ;开总中断SETB ES ;使能串口中断SETB ET0 ;使能定时器0中断SETB TR0 ;启动定时0CLR ET1 ;关定时器1中断CLR EX0 ;关外部中断0CLR EX1 ;关外部中断1MOV SCON,#50H ;SM0/SM1=0/1,设置成串口1方式,10位通用异步接发, ;8位数据,可变波特率,接收允许MOV TMOD,#21H ;T1: M1/M0=1/0 波特率发生器T1工作在模式2,8位自动重装初值定时计数;T0: M1/M0=0/1 工作在模式1,作16位定时器MOV PCON,#80H ;SMOD置1,使得波特率翻倍为2400x2=4800BPSMOV TH1,#0F3H ;预置初值(按照波特率2400BPS预置初值)MOV TL1,#0F3H ;预置初值(按照波特率2400BPS预置初值)SETB TR1 ;启动定时器T1SETB BEEP ;关闭蜂鸣器MOV TH0,#0ECHMOV TL0,#78HMOV P0,#00HRETDELAY: ;延迟子程序,延时10msMOV 05H,#100DE0: MOV 06H,#100DE1: DJNZ 06H,DE1DJNZ 05H,DE0RETLDELAY: ;延迟子程序,延时500ms MOV 07H,#50LDE0: MOV 05H,#100LDE1: MOV 06H,#100LDE2: DJNZ 06H,LDE2DJNZ 05H,LDE1LDE3: DJNZ 07H,LDE0RET;在数码管上显示数字SHOW: ;数码管显示函数MOV R6,AMOV R7,#01HS1:ANL A,R7 ;取出A的一位JNZ S3S2:CLR PSEVENAJMP S4S3:SETB PSEVENS4:SETB PFOUR ;将数据寄存器PSEVEN值移进移位寄存器NOPCLR PFOURNOPMOV A,R7RL AMOV R7,AMOV A,R6CJNE R7,#01H,S1 ;判断A的8位是否全部取出CLR PFIVENOPSETB PFIVERETTINTO: ;定时器0计时中断程序每隔5ms中断一次INC DEDAMOV 55H,DEDA ;运动秒针,低位MSEC每10ms计数ANL 55H,#01HMOV R6,55HCJNE R6,#0,POPACMOV R6,MSECCJNE R6,#99,INCMMOV MSEC,#00MOV R6,SECMCJNE R6,#59,INCSMOV SECM,#00AJMP POPACINCM:INC MSECAJMP POPACINCS:INC SECMPOPAC:MOV A,DEDACJNE A,#200,AGAIN ;判断是否1S到了MOV DEDA,#0SECOND:INC SECMOV A,SECCJNE A,#60,AGAIN ;判断是否1min到了MINUTE:MOV SEC,#0INC MINMOV A,MINCJNE A,#60,AGAIN ;判断是否1h到了HOURS:MOV MIN,#0MOV A,HOURCJNE A,#24,AGAINMOV A,MONTH ;辨别大月和小月CJNE A,#1,MONTH2AJMP THIRTY_ONE_DAYSMONTH2:CJNE A,#2,MONTH3AJMP FEBRUARYMONTH3:CJNE A,#3,MONTH4AJMP THIRTY_ONE_DAYSMONTH4:CJNE A,#4,MONTH5AJMP THIRTY_DAYSMONTH5:AJMP THIRTY_ONE_DAYSMONTH6:CJNE A,#6,MONTH7AJMP THIRTY_DAYSMONTH7:CJNE A,#7,MONTH8AJMP THIRTY_ONE_DAYSMONTH8:CJNE A,#8,MONTH9AJMP THIRTY_ONE_DAYSMONTH9:CJNE A,#9,MONTH10MONTH10:CJNE A,#10,MONTH11AJMP THIRTY_ONE_DAYSMONTH11:CJNE A,#11,MONTH12AJMP THIRTY_DAYSMONTH12:AJMP THIRTY_ONE_DAYSAGAIN:MOV TL0,#078HSETB TR0 ;启动定时器RETITHIRTY_ONE_DAYS: ;大月31天MOV HOUR,#0 ;时归0MOV A,DAYCJNE A,#31,INCDAY ;未够31天AJMP MONTHSAJMP AGAINTHIRTY_DAYS: ;小月30天MOV HOUR,#0 ;时归0MOV A,DAYCJNE A,#30,INCDAY2 ;未够30天AJMP MONTHSAJMP AGAINFEBRUARY: ;特殊的2月MOV B,#4MOV A,YEARLCJNE A,#0,NORMALAJMP CENTURYNORMAL:DIV ABCJNE A,#0,COMMONBISSEXTILE: ;闰年MOV HOUR,#0 ;时归0MOV A,DAYCJNE A,#29,INCDAY ;未够29天AJMP MONTHSCOMMON: ;平年MOV HOUR,#0 ;时归0CJNE A,#28,INCDAY ;未够28天AJMP MONTHSCENTURY: ;世纪年MOV A,YEARHMOV A,BCJNE A,#0,COMMONAJMP BISSEXTILEMONTHS:MOV DAY,#01CJNE A,#12,INCMONTHAJMP INCYEARINCMONTH:INC MONTHAJMP AGAININCYEAR: ;判断数字是否超出显示管显示范围MOV MONTH,#01MOV A,YEARLCJNE A,#99,INCYLAJMP GO_ONINCYL:INC YEARLGO_ON:MOV YEARL,#0MOV A,YEARHCJNE A,#99,INCYHAJMP ZEROINCYH:INC YEARHLJMP AGAINZERO:MOV YEARH,#0LJMP AGAINTABLE:DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,0FEH,0F6H ;0 1 2 34 5 6 7 8 9 ,不带小数点TABLE2:DB 0FDH,61H,0DBH,0F3H,67H,0B7H,0BFH,0E1H,0FFH,0F7H ;带小数点END五、系统的使用和操作说明按下开关,如下图所示显示初始设定的时间10:30分。
单片机电子时钟汇编程序

;==============================================================; 文件名称: KeyScan.Asm; 功能描述: 8255扩展IO, 完成键盘及数码管显示实验.; 按下按键, 数码管显示相应键值.;通过第一列按键改变时分秒的值,在按下第一个按键时,停止计数器,并将秒的值30h单元的内容加一。
;在按下第二个按键时,停止计数器,并将分的值31h单元的内容加一?;在按下第三个按键时,停止计数器,并将分的值32h单元的内容加一?;在按下第四个按键时,重新启动定时器开始计时。
;为什么要加34h(I don't know),如果没有将会出现一个非常奇异的现象,小时只能加到8,然后单片机死机了。
;==============================================================A_8255 EQU 7F00H ;8255端口定义B_8255 EQU 7F01HC_8255 EQU 7F02HCON_8255 EQU 7F03HCOUNT DATA 20HORG 0000HLJMP MAINORG 000BHLJMP TIME0MAIN:MOV A, #81HMOV DPTR, #CON_8255 ;8255控制端口MOVX @DPTR, A ;写入控制字MOV A,#0FFH ;关闭显示MOV DPTR,#A_8255MOVX @DPTR,A ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;定时器初始化MOV SP,#4FHMOV TMOD,#01HMOV TH0,#4CHMOV TL0,#00HSETB ET0SETB EASETB TR0MOV COUNT,#14HMOV 30H,#00H ;30H~32H SA VE SECOND,MINUTE,HOUR MOV 31H,#00H ;MOV 32H,#00H ;MOV 33H,#00H ;SA VE KEY V ALUEMOV 34H,#00H ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;BEGIN: LCALL DIS ;调用显示子程序LCALL CCSCAN ;判是否有键按下MOV A,33H ;MODIFY TIMERJZ BEGINLCALL KEYXAJMP BEGIN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KEYX:MOV A,33HCJNE A,#01H,KEY1 ;STOP TIMERCLR EACLR ET0CLR TR0INC 30H ;SELECT LEDMOV A,30HCJNE A,#60,KEY00MOV 30H,#00HKEY00:MOV 33H,#00HAJMP OVERKEY1: CJNE A,#04H,KEY2 ;ADD V ALUEMOV 33H,#00HCLR EACLR ET0CLR TR0INC 31HMOV A,31HCJNE A,#60,KEY11MOV 31H,#00HKEY11:AJMP OVERKEY2: CJNE A,#08H,KEY3 ;MOV 33H,#00HCLR EACLR ET0CLR TR0INC 32HMOV A,32HCJNE A,#24,KEY22MOV 32H,#00HKEY22:AJMP OVERKEY3: CJNE A,#0CH,OVER ;START TIMER MOV 33H,#00HACALL START_TIME0OVER:RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;START_TIME0:MOV TMOD,#01HMOV TH0,#4CHMOV TL0,#00HSETB ET0SETB EASETB TR0MOV COUNT,#14HRET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KEYSCANCCSCAN:;PUSH ACCMOV DPTR,#A_8255 ;按键扫描MOV A,#00HMOVX @DPTR,AMOV DPTR,#C_8255MOVX A,@DPTRCPL A ;取反ANL A,#0FHJNZ INK2 ;KEY DOWN AJMP EXITINK2:;LCALL DLNMS ;消除按键抖动MOV DPTR,#A_8255 ;按键扫描MOV A,#00HMOVX @DPTR,AMOV DPTR,#C_8255MOVX A,@DPTRCPL A ;取反ANL A,#0FHJNZ INK3 ;KEY DOWNAJMP EXITINK3:MOV R2,#0FEHMOV R4,#00H ;从第0列开始扫描COLUM: MOV DPTR,#A_8255MOV A,R2MOVX @DPTR,A ;写入列扫描值MOV DPTR, #C_8255MOVX A,@DPTRJB ACC.0,LINE1 ;判第0行的值MOV 33H,#01H ;第0行AJMP EXITLINE1: JB ACC.1,LINE2MOV 33H,#04H ;第1行AJMP EXITLINE2: JB ACC.2,LINE3MOV 33H,#08H ;第2行AJMP EXITLINE3: JB ACC.3,EXITMOV 33H, #0CH ;第3行EXIT:;POP ACCRET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;DIS: PUSH ACC ;显示子程序PUSH 00HPUSH 03HAGAIN:;;DISPLAY SECOND ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;FIRST SECOND SEG DISPLAYMOV A,30H ;a存放表内偏移地址MOV B,#10DIV AB;MOV A,BMOV DPTR,#DSEGS ;数码管段表地址,dptr存放表的首地址MOVC A,@A+DPTR ;查表MOV DPTR,#B_8255 ;送段显示MOVX @DPTR,AMOV A,#0EFH ;SELECT FIRST SEGMOV DPTR,#A_8255MOVX @DPTR,AACALL DL1MSMOV A,BMOV DPTR,#DSEGS ;数码管段表地址,dptr存放表的首地址MOVC A,@A+DPTR ;查表MOV DPTR,#B_8255 ;送段显示MOVX @DPTR,AMOV A,#0DFH ;SELECT FIRST SEGMOV DPTR,#A_8255MOVX @DPTR,AACALL DL1MS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MINUTE SEG DISPLAYMOV A,31H ;a存放表内偏移地址MOV B,#10DIV AB;MOV A,BMOV DPTR,#DSEGS ;数码管段表地址,dptr存放表的首地址MOVC A,@A+DPTR ;查表MOV DPTR,#B_8255 ;送段显示MOVX @DPTR,AMOV A,#0FBH ;SELECT FIRST SEGMOV DPTR,#A_8255MOVX @DPTR,AACALL DL1MSMOV A,BMOV DPTR,#DSEGS ;数码管段表地址,dptr存放表的首地址MOVC A,@A+DPTR ;查表MOV DPTR,#B_8255 ;送段显示MOVX @DPTR,AMOV A,#0F7H ;SELECT FIRST SEGMOV DPTR,#A_8255MOVX @DPTR,AACALL DL1MS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; HOUR SEG DISPLAYMOV A,32H ;a存放表内偏移地址MOV B,#10DIV AB;MOV A,BMOV DPTR,#DSEGS ;数码管段表地址,dptr存放表的首地址MOVC A,@A+DPTR ;查表MOV DPTR,#B_8255 ;送段显示MOVX @DPTR,AMOV A,#0FEH ;SELECT FIRST SEGMOV DPTR,#A_8255MOVX @DPTR,AACALL DL1MSMOV A,BMOV DPTR,#DSEGS ;数码管段表地址,dptr存放表的首地址MOVC A,@A+DPTR ;查表MOV DPTR,#B_8255 ;送段显示MOVX @DPTR,AMOV A,#0FDH ;SELECT FIRST SEGMOV DPTR,#A_8255MOVX @DPTR,AACALL DL1MS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; HOUR SEG DISPLAYMOV A,34H ;a存放表内偏移地址MOV B,#10DIV AB;MOV A,BMOV DPTR,#DSEGS ;数码管段表地址,dptr存放表的首地址MOVC A,@A+DPTR ;查表MOV DPTR,#B_8255 ;送段显示MOVX @DPTR,AMOV A,#07FH ;SELECT FIRST SEGMOV DPTR,#A_8255MOVX @DPTR,AACALL DL1MSMOV A,BMOV DPTR,#DSEGS ;数码管段表地址,dptr存放表的首地址MOVC A,@A+DPTR ;查表MOV DPTR,#B_8255 ;送段显示MOVX @DPTR,AMOV A,#0BFH ;SELECT FIRST SEGMOV DPTR,#A_8255MOVX @DPTR,AACALL DL1MS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OUT: POP 03HPOP 00HPOP ACCRET;数码管段显示值DSEGS: DB 03FH, 06H,05BH,04FH,066H,06DH,07DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71HDL1MS: MOV R7,#05HDL0: MOV R6,#080HDL1: DJNZ R6,DL1DJNZ R7,DL0RETDLNMS: MOV R7,#0F0HDL03: MOV R6,#0F0HDL13: DJNZ R6,DL13DJNZ R7,DL03RET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TIME0:PUSH ACCMOV TH0,#04CHMOV TL0,#00HDJNZ COUNT,NEXT1MOV COUNT,#14HINC 30HMOV A,30HCJNE A,#60,NEXT1MOV 30H,#00HINC 31HMOV A,31HCJNE A,#60,NEXT1MOV 31H,#00HINC 32HMOV A,32HCJNE A,#24,NEXT1MOV 32H,#00HNEXT1:POP ACCRETIEND。
实时时钟设计试验报告

实时时钟设计试验报告一、实验目的本实验的目的是设计一个实时时钟系统,具有实时显示时间、日期和闹钟功能。
通过该实验,我们可以了解实时时钟的设计原理、硬件电路连接及软件程序编写方法。
二、实验原理实时时钟系统由时钟芯片、显示模块、按键模块和控制模块组成。
时钟芯片负责计时和日期的记录,显示模块用于显示时间和日期,按键模块用于设置时间和日期,控制模块用于控制各模块之间的协作。
三、实验器材1.STM32开发板2.DS3231时钟模块3.数码管显示模块4.按键模块5.连接线四、实验步骤1.连接硬件电路。
将STM32开发板与DS3231时钟模块、数码管显示模块和按键模块进行连接,确保电路连接正确无误。
2.编写程序。
使用C语言编写程序,通过读取DS3231时钟模块的寄存器获取时间和日期数据,并将其显示在数码管模块上。
同时,设置按键模块的功能,使其可以进行时间和日期的设置。
3.烧录程序。
使用烧录器将编写好的程序烧录到STM32开发板上,并进行调试。
4.运行实验。
接通电源,启动实时时钟系统,观察数码管是否正确显示时间和日期,按下按键模块进行时间和日期的设置,并观察设置是否生效。
五、实验结果经过实验,我们成功设计出了一个实时时钟系统。
系统能够实时地显示当前的时间和日期,并且可以通过按键进行时间和日期的设置。
在设置新的时间和日期后,系统能够正确地更新并显示。
六、实验总结通过本次实验,我们深入地了解了实时时钟系统的设计原理和实现方法。
我们熟悉了DS3231时钟模块的使用方法,并学会了通过C语言编写程序来实现实时时钟系统的功能。
同时,我们也发现了实时时钟系统的一些问题,并加以解决。
我们对实时时钟系统的稳定性和精确性进行了测试,发现系统的计时精度较高,能够达到亚秒级的准确度。
然而,在用户进行时间和日期的设置时,可能由于误操作导致时间和日期出错。
需要在后续的工作中进一步优化系统的操作界面,提高用户设置的便捷性和准确性。
总而言之,实时时钟系统是一种非常有实用价值的设计,可以广泛应用于各种计时需求的场合,如办公室、实验室、车载设备等。
单片机数字时钟实验报告
单片机数字时钟实验报告引言:数字时钟是现代人们生活中不可或缺的物品之一。
现代数字时钟的核心是单片机,而且数字时钟的制作也是单片机初学者的必备实验之一。
本文将详细介绍单片机数字时钟的制作过程和原理。
实验原理:数字时钟的原理非常简单,它由单片机、时钟芯片、LED数码管等元件组成。
单片机通过时钟芯片来获取时间信息,并将时间信息通过端口输出给LED数码管,从而显示当前时间。
单片机的主要作用是控制时钟芯片的读取和LED数码管的显示。
实验材料:1. 单片机:STC89C522. 时钟芯片:DS13023. LED数码管:共阳极4位LED数码管4. 电路板、电阻、电容、晶体振荡器、按键、排针等元件实验步骤:1. 确定电路原理图:根据实验原理,确定单片机、时钟芯片和LED 数码管之间的电路连接方式。
2. 绘制电路布局图:将电路原理图转换为真实的电路布局图,并根据元件大小和数量选择合适的电路板。
3. 焊接电路:根据电路布局图进行电路的焊接,并进行电路的检查和修正。
4. 编写程序:根据实验原理编写单片机程序,并将程序下载到单片机中。
5. 测试程序:将电路接通电源后,通过按键和LED数码管来测试程序的正确性和稳定性。
实验结果:经过实验,我们成功制作了一款单片机数字时钟。
该数字时钟具有以下功能:1. 显示当前的小时、分钟和秒钟。
2. 可以通过按键进行时间的调整。
3. 每隔一秒钟左右,LED数码管上的数据会刷新一次,以显示最新的时间信息。
4. 当电源断开后,时钟芯片会自动保存当前时间信息,重新通电后,显示的时间信息仍然是正确的。
结论:通过本次实验,我们了解了单片机数字时钟的制作原理和步骤,并成功制作了一款数字时钟。
通过实验,我们深入了解了单片机的应用,也为我们今后的电子设计和制作提供了很好的基础。
单片机实验报告(闹钟)
单片机实验(闹钟部分修改版)注:第一个是利用延时程序做的定时,循环太多定时不够精确;这一个用的是出栈和入栈的算法进行的定时,可以增加定时的精度。
程序目的说明:这是一个闹钟程序,当按下K1的时候,开始计时(说明:为了方便观察,我以10s 中作为基本定时进行演示,如果需要其他定时可以通过修改部分程序得到),时间达到后,7段显示器和LED 灯同时闪烁,若序号归零,则按下K2计时则停止。
然后再按下K1计时又从新开始,以此类推。
电路图:LED6位七段码显示灯,从左到往右两位一组,分别显示HOUR, MINUTE,SECOND.因为P0口内部没有上拉电阻,不能输出高电平,所以要接上拉电阻。
排阻就是好多电阻连载一起,他们有一个公共端.由于是上拉电阻,所以1接VCC 。
晶振电路,帮助减小计时过程中产生的误差。
K1开关和P1.1口相连,K2和P2.2口相连,分别用于控制计时的开启和关闭LED 灯,计时到达的时候LED 灯闪烁,计时t 停止时LED 灯熄灭。
程序段:程序说明:1.直接将开关定义为各个接口,可以方便之后程序中利用各个开光的状态进行跳转。
2.利用了计数/定时器0作为外部中断,当中断产生,自动跳入计时状态;3.此段定义的是而二进制的时间存储单元。
4.此段定义的是需要计时(亮灯)的时间,我设定的10s亮灯,所以s为0ah,其他的均为00h5.此段定义的是BCD码得时间,为了可以在七段显示器上面显示6.主程序中要调用闹钟程序timebear检测设定时间是否到达和显示时间的子程序display1.7.timebear程序段用于检测闹铃设定的时间是否达到,依次从second(s),minute(m),hour (h)检测,出现不匹配的就不再向下执行,若时间匹配就跳转至timecome。
8.timecome程序段主要控制P3.7口,时间达到的时候,使LED灯和7短码显示器点亮并闪烁,如果要不要灯和七段码显示器闪烁则删除:mov r7,#250t2:mov r6,#124t3:djnz r6,t3djnz r7,t2setb p3.7这一段程序即可,这一段相当于机器周期,是灯的闪亮延时,就出现了闪烁的状态。
电子实时时钟万年日历系统-单片机课程设计(含电路图、流程图、汇编语言)
一、题目:电子实时时钟/万年日历系统二、功能要求:1.基本要求:⑴显示准确的北京时间(时、分、秒),可用24小时制式;⑵随时可以调校时间。
2.发挥要求:⑴增加公历日期显示功能(年、月、日),年号只显示最后两位;⑵随时可以调校年、月、日;⑶允许通过转换功能键转换显示时间或日期。
三、方案考虑:1、硬件方案:⑴显示器采用6位LED数码管(共阳),可分别显示时间或日期。
⑵显示器的驱动采用动态扫描电路形式,以达到简化电路的目的。
但要注意所需的驱动电流比静态驱动时要大,因此要增加驱动电路。
可采用74LS244或者晶体管;其中74ls244是用来驱动段选码,晶体管是驱动位选码。
⑶采用“一键多用方案”,以减少按键数目。
本方案采用了4按键。
⑷整体上要考虑:结构简单、布局美观、操作方便、成本低廉。
2、设计电路图如下:3、元件清单:(我们使用的是TX-1C开发板)⑴ 89C52 1个⑵IC座(40脚) 3个(其中1个用于接插89C51、2个用于接插LED段数码管)。
⑶ 74LS244 1个(用于驱动6个共阳的LED段数码管)。
⑷ IC座(20脚) 1个(用于接插74LS244)。
(5)显示器:LED_8段数码管(共阳型)6个三极管:(6)PNP(8550)6个(用于驱动6个共阳型LED段数码管)。
(7)微型开关:3个(其中1个用于复位电路、其它用于键盘)。
(8)晶体振荡器(12MHz):1个(用于振荡电路)。
(9)电阻器:⑴ 3KΩ 1个(用于系统复位电路)。
⑵ 1KΩ 6个(用作PNP三极管基极电阻)。
⑶ 100Ω 7个(驱动器用作74LS244输出限流电阻)。
(10)电容器:⑴ 10μF1个(用于系统复位电路)。
⑵ 30 pF 2个(用于系统振荡电路)。
(11)其它:⑴万能电路板(10×15):1块⑵焊锡条: 2米⑶带插头、座的电源端子: 1条⑷各种颜色外皮的导线:各1米(12)工具:1.电烙铁:1把2.剪钳:1把3.镊子:1把4.万用表:1个(13)设备:编程器(MEP300或TOP851)6个4、软件方案:(1)使用全汇编编写(2)时钟基准时间由单片机内部定时中断来提供,定时时间应该乘以一个整数得到,且不宜太长或太短,最长不能超过16位定时器的最长定时时间,最短不能少于定时中断服务程序的执行时间。
单片机汇编程序51电子时钟.doc
单片机汇编程序 51电子时钟电子钟设计实验报告一)实验目的:1、进一步掌握定时器的使用和编程方法。
2、进一步掌握中断处理程序的编程方法。
3、进一步掌握数码显示电路的驱动方法。
4、进一步掌握键盘电路的驱动方法。
5、进一步掌握软件数据处理的方法。
二)内容要求:1、利用CPU的定时器和数码显示电路,设计一个电子时钟。
格式如下:XX XX XX 由左向右分别为:时、分、秒。
2、电子时钟有秒表功能。
3、并能用键盘调整时钟时间。
4、电子时钟能整点报时、整点对时功能。
5、能设定电子时钟的闹铃。
三)主要元件:电阻4.7K 10个 2K 1个四位共阳数码管1个二位共阳数码管1个按钮开关4个万用板(中板)1个 9012PNP 7个排线排阵若干电线一捆蜂鸣器1个最小系统一个四)系统说明:按P1.0键,如果按下的时间小于1秒进入省电模式(数码管不显示,开T0计时器),如果按下的时间大于1秒则进入时间调整.。
在时间调整状态:再按P1.0,如果按下时间大于0.5秒转调小时状态,按下时间小于0.5秒加1分钟操作。
在小时调整状态再按P1.0键,如果按下时间大于0.5秒退出时间调整,如果按下时间小于0.5秒加1小时操作。
按P1.1键,进入闹铃调分状态,按P1.2分加1,按P1.0分减1。
若再按P1.3,则进入调整状态,按P1.2时加1,按P1.0分时。
按P1.1键,闹铃有效,显示式样变为00:00:—0;再按P1.1键,闹铃无效,显示式样变为00:00:—。
按P1.3键,调整闹钟时间结束。
按P1.2键,进入秒表计时功能,按P1.2键暂停或清零,按P1.1键退出秒表回到时钟状态。
而且本系统还有整点报时功能,以及按键伴有声音提示。
五)程序流程图:开始 TO中断初始化保护现场进入功能调用显示定时初值校正程序子程序N Y键按下, 1S到,Y N加1S处理整点到NY恢复现场,中断返回按时间鸣叫次数主程序流程图 T0中断计时程序流程图T1中断保护现场T1中断服务程序流程图秒表/闪烁,时钟调时闪烁加10MS处理闪烁处理恢复现场,中断返回六)电路图七)程序清单:中断入口程序 ;; DISPFIRST EQU 30H BELL EQU P1.4CONBS EQU 2FHOUTPX EQU P2 ;P2位选OUTPY EQU P0 ;P0段选INP0 BIT P1.0INP1 BIT P1.1INP2 BIT P1.2ORG 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 ;串行中断程序返回;QQQQ:MOV A,#10HMOV B,79HMUL ABADD A,78HMOV CONBS,ABSLOOP:LCALL DS20MSLCALL DL1SLCALL DL1SLCALL DL1SDJNZ CONBS,BSLOOPCLR 08HAJMP START;; 主程序 ;;START:MOV R0,#00H ;清70H-7AH共11个内存单元MOV R7,#80H ;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秒定时用初值(50MS×20)MOV DISPFIRST ,#70HSTART1: LCALL DISPLAY ;调用显示子程序JNB INP0,SETMM1 ;P1.0口为0时转时间调整程序JNB INP1,FUNSS ; 秒表功能,P1.1按键调时时作减1加能JNB INP2,FUNPT ;STOP,PUSE,CLRJNB P1.3,TSFUNSJMP START1 ;P1.0口为1时跳回START1SETMM1: LJMP SETMM ;转到时间调整程序SETMM FUNSS: LCALL DS20MSJB INP1,START1WAIT11: JNB INP1,WAIT11CPL 03HMOV DISPFIRST,#00H :显示秒表数据单元MOV 70H,#00HMOV 71H,#00HMOV 76H,#00HMOV 77H,#00HMOV 78H,#00HMOV 79H,#00HAJMP START1FUNPT: LCALL DS20MSJB INP2,START1WAIT22: JNB INP2,WAIT21CLR ET0CLR TR0WAIT33: JB INP2,WAIT31 LCALL DS20MSJB INP2,WAIT33WAIT66: JNB INP2,WAIT61 MOV R0,#70H ;清70H-79H共10 个内存单元MOV R7,#0AH ;CLEARP: MOV @R0,#00H ;INC R0 ;DJNZ R7,CLEARP ;WAIT44: JB INP2,WAIT41 LCALL DS20MSJB INP2,WAIT44WAIT55: JNB INP2,WAIT51 SETB ET0SETB TR0AJMP START1WAIT21: LCALL DISPLAY AJMP WAIT22WAIT31: LCALL DISPLAY AJMP WAIT33WAIT41: LCALL DISPLAYAJMP WAIT44WAIT51: LCALL DISPLAYAJMP WAIT55WAIT61: LCALL DISPLAYAJMP WAIT66 TSFUN:LCALL DS20MSWAIT113:JNB P1.3,WAIT113JB 05H,CLOSESPMOV DISPFIRST,#50HMOV 50H,#0CHMOV 51H,#0AHDSWAIT:SETB EALCALL DISPLAYJNB P1.2,DSFINCJNB P1.0,DSDECJNB P1.3,DSSFU AJMP DSWAITCLOSESP:CLR 05HCLR BELLAJMP START1 DSSFU:LCALL DS20MS JB P1.3,DSWAIT LJMP DSSFUNN DSFINC:LCALL DS20MS JB P1.2,DSWAIT DSWAIT12:LCALL DISPLAY JNB P1.2,DSWAIT12 CLR EAMOV R0,#53H LCALL ADD1MOV A,R3CLR CCJNE A,#60H,ADDHH22ADDHH22:JC DSWAITACALL CLR0AJMP DSWAITDSDEC:LCALL DS20MSLCALL DISPLAYDSWAITEE:LCALL DISPLAYJNB P1.0,DSWAITEECLR EAMOV R0,#53HLCALL SUB1LJMP DSWAIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1秒计时程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;T0中断服务程序INTT0: PUSH ACC ;累加器入栈保护PUSH PSW ;状态字入栈保护CLR ET0 ;关T0中断允许CLR TR0 ;关闭定时器T0JB 03H,FSSMOV 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秒时对秒计时单元清0 MOV 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 ;清进位标志JB 03H,OUTT0 ;秒表时最大数为99CJNE A,#24H,HOUR ;HOUR: JC OUTT0 ;小于24小时中断退出ACALL CLR0 ;大于或等于24小时小时计时单元清0OUTT0: MOV 72H,76H ;中断退出时将分、时计时单元数据移MOV 73H,77H ;入对应显示单元MOV 74H,78H ;MOV 75H,79H ;LCALL BAOJPOP PSW ;恢复状态字(出栈)POP ACC ;恢复累加器SETB ET0 ;开放T0中断RETI ;中断返回 ;秒表计时程序(10MS加1),低2位为0.1、0.01秒,中间2位为秒,最高位为分。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验二实时时钟实验一、实验目的1)数码管动态显示技术2)定时器的应用3)按键功能定义二、实验实现的功能实时时钟,可以设定当前时间,完成钟表功能(四位数码管分别显示分钟和秒)。
三、系统硬件设计四、系统软件设计说明:1键进入和退出设置模式,4键选择调分或秒,2键加,3键减。
P1M1 EQU 91HP1M0 EQU 92HSEC0 DA TA 30H ;秒显示SEC1 DA TA 31HMIN0 DA TA 32H ;分显示MIN1 DA TA 33HDELAY_1 DA TA 34H ;延时参数DELAY_2 DA TA 35H ;延时参数ORG 0000HLJMP 0030HORG 001BHLJMP INTR0ORG 0030HMAIN: MOV P1M1,#00000000BMOV P1M0,#11111111BMOV R7,#000 ;记中断次数,R7=100为1秒MOV R6,#000 ;记秒MOV R5,#000 ;记分MOV R4,#0FFH ;按键位置MOV R1,#000 ;确定是否有按键按下的参数MOV TMOD,#10H ;定时器初始化MOV TH1,#0D8H ;定时时间10msMOV TL1,#0F0HSETB EASETB ET1SETB TR1LOOP0: CJNE R4,#000H,LOOP01 ;实时时钟显示MOV R4,#0FFHLJMP LOOP1LOOP01: LCALL TIMELCALL KEY0LJMP LOOP0LOOP1: CJNE R4,#000H,LOOP11 ;调秒MOV R4,#0FFHLJMP LOOP0LOOP11: CJNE R4,#003H,LOOP12MOV R4,#0FFHLJMP LOOP2LOOP12: CJNE R4,#001H,LOOP13MOV R4,#0FFHINC R6LOOP13: CJNE R6,#060,LOOP14MOV R6,#000HLOOP14: CJNE R4,#002H,LOOP16MOV R4,#0FFHCJNE R6,#000,LOOP15MOV R6,#060LOOP15: DEC R6LOOP16: LCALL TIMELCALL KEY1LJMP LOOP1LOOP2: CJNE R4,#000H,LOOP21 ;调分MOV R4,#0FFHLJMP LOOP0LOOP21: CJNE R4,#003H,LOOP22MOV R4,#0FFHLJMP LOOP1LOOP22: CJNE R4,#001H,LOOP24MOV R4,#0FFHINC R5LOOP23: CJNE R5,#060,LOOP24MOV R5,#000HLOOP24: CJNE R4,#002H,LOOP26MOV R4,#0FFHCJNE R5,#000,LOOP25MOV R5,#060LOOP25: DEC R5LOOP26: LCALL TIMELCALL KEY2LJMP LOOP2/*********中断服务程序(原始时间分秒的确定)**********/INTR0: PUSH PSWMOV TH1,#0D8HMOV TL1,#0F0HINC R7MOV TH1,#0D8HMOV TL1,#0F0HCJNE R7,#100,INTR01MOV R7,#000HINC R6CJNE R6,#60,INTR01MOV R6,#000HINC R5CJNE R5,#60,INTR01MOV R5,#000HINTR01: POP PSWRETI/*****************时间分秒显示计算***************/TIME: MOV A,R6 ;计算秒MOV B,#10DIV ABMOV SEC1,AMOV SEC0,BMOV A,R5 ;计算分MOV B,#10DIV ABMOV MIN1,AMOV MIN0,BRET/*****************按键扫描消抖及确定***************/KEY0: LCALL KS ;扫描有无按键按下KEY01: LCALL DISPLAY0 ;CJNE R1,#000H,KEY02 ; 通过(控制数码管的扫描频率,LJMP KEY05 ; 延时进而控制其扫描周期,以KEY02: MOV R1,#000H ; 消抖达到所需摸延时时间)LCALL KS ;CJNE R1,#000H,KEY03 ;确定有按键按下?LJMP KEY05 ;KEY03: LCALL KS0 ;调用计算物理位置子函数KEY04: LCALL TIME ;LCALL DISPLAY0 ;LCALL KS ;检查按键是否松开CJNE R1,#000H,KEY04 ;KEY05: RET ;KEY1: LCALL KS ;同上KEY11: LCALL DISPLAY1 ;CJNE R1,#000H,KEY12 ;LJMP KEY15 ;KEY12: MOV R1,#000HLCALL KSCJNE R1,#000H,KEY13LJMP KEY15KEY13: LCALL KS0KEY14: LCALL TIMELCALL DISPLAY1LCALL KSCJNE R1,#000H,KEY14KEY15: RETKEY2: LCALL KS ;同上KEY21: LCALL DISPLAY2 ;CJNE R1,#000H,KEY22 ;LJMP KEY25 ;KEY22: MOV R1,#000HLCALL KSCJNE R1,#000H,KEY23LJMP KEY25KEY23: LCALL KS0KEY24: LCALL TIMELCALL DISPLAY2LCALL KSCJNE R1,#000H,KEY24KEY25: RET/*****检查有无按健闭合*****/KS: CLR P3.6CLR P3.7SETB P0.5SETB P0.6SETB P0.7MOV A,P0ORL A,#01FHCPL AMOV R1,ARET/****确定按键的物理位置****/KS0: MOV R4,#000H ;行号扫描初值SETB P3.7CLR P3.6 ;行扫描初值KS1: MOV A,P0ORL A,#01FHMOV R3,A ;保存列1CJNE A,#0FFH,KS2MOV R4,#003H ;行首值SETB P3.6CLR P3.7MOV A,P0ORL A,#01FHMOV R3,A ;保存列2CJNE A,#0FFH,KS2LJMP KS4KS2: MOV A,R3 ;计算按键的物理位置RRC ASWAP AKS3: RRC AJNC KS4INC R4SJMP KS3KS4: RET/******************数码管显示*****************/DP1: MOV A,MIN1 ;前两位数码管显示MOV DPTR,#TAB0MOVC A,@A+DPTRCLR P0.0MOV P1,ALCALL DL0MOV P1,#000HSETB P0.0MOV A,MIN0MOV DPTR,#TAB1MOVC A,@A+DPTRCLR P0.1MOV P1,ALCALL DL0MOV P1,#000HSETB P0.1RETDP2: MOV A,SEC1 ;后两位数码管显示MOV DPTR,#TAB0MOVC A,@A+DPTRCLR P0.2MOV P1,ALCALL DL0MOV P1,#000HSETB P0.2MOV A,SEC0MOV DPTR,#TAB0MOVC A,@A+DPTRCLR P0.3MOV P1,ALCALL DL0MOV P1,#000HSETB P0.3RET/******************显示方式函数*****************/DISPLAY0: LCALL DP1 ;实时时钟模式的显示函数LCALL DP2RETDISPLAY1: LCALL DP1 ;调秒模式的显示函数CJNE R7,#001H,DISPLAY11MOV R2,#000HDISPLAY11:CJNE R7,#032H,DISPLAY12MOV R2,#001HDISPLAY12:CJNE R2,#000H,DISPLAY13LCALL DP2LJMP DISPLAY14DISPLAY13:LCALL DL0LCALL DL0DISPLAY14:RETDISPLAY2: LCALL DP2 ;调分模式的显示函数CJNE R7,#001H,DISPLAY21MOV R2,#000HDISPLAY21:CJNE R7,#032H,DISPLAY22MOV R2,#001HDISPLAY22:CJNE R2,#000H,DISPLAY23LCALL DP1LJMP DISPLAY24DISPLAY23:LCALL DL0LCALL DL0DISPLAY24:RET/********************延时********************//*说明:延时所用的三条令,stc10f08xe中与常用的51单片机中的指令执行时间不同*/ DL0: MOV DELAY_1,#16 ;延时时间:[2+(2+250*4+4)×16+4] /11.0592DL01: MOV DELAY_2,#250 ; =16102/11.0592DJNZ DELAY_2,$ ; =1.456msDJNZ DELAY_1,DL01 ;RET ; ;TAB0: DB 03FH,006H,05BH,04FH,066H,06DH,07DH,007H,07FH,067H ;无小数点的LED字模表TAB1: DB 0BFH,086H,0DBH,0CFH,0E6H,0EDH,0FDH,087H,0FFH,0E7H ;有小数点的LED字模表END五、实验过程中遇到的问题及解决方法1、怎么让选中的数码管闪烁?通过记秒的参数,设置前半秒扫描相关数码管,后半秒不扫描。
2、怎么让按键按下时数码管不突然闪烁?通过计算改变数码管的扫描时间,让其作为按键延时间。
3、汇编中如果工作寄存器用完,怎么自定义变量?通过EQU或DATA指令进行定义。
4、STC单片机的定时器是否与51单片机兼容?兼容。
指导老师签字:日期:。