单片机数字时钟程序

单片机数字时钟程序,第1张

#include <reg51.h>#include <intrins.h>sbit SCL2=P1^3//SCL2定义为P1口的第3位脚,连接DS1302SCL和ADC0831SCL脚 sbit SDA2=P1^4//SDA2定义为P1口的第4位脚,连接DS1302SCL和ADC0831SDA脚 //sbit CS2=P1^6//CS2定义为P1口的第4位脚,连接ADC0831CS脚 sbit RST = P1^5// DS1302片选脚 unsigned char l_tmpdate[8]={0x00,0x06,0x03,0x18,0x0c,0x07,0x06,0}unsigned char l_tmpdisplay[8]={0x40,0x40,0x40,0x40,0x40,0x40,0x40,0}code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}//地址为:秒分小时月日年 code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}code unsigned char table[]= {0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f, 0x40,0x00} //共阴数码管 0-9 '-' '熄灭‘表 void delay()//延时子函数,5个空指令 void display(unsigned char *lp,unsigned char lc)//数字的显示函数;lp为指向数组的地址,lc为显示的个数 void Write_Ds1302_byte(unsigned char temp) void Write_Ds1302( unsigned char address,unsigned char dat )unsigned char Read_Ds1302 ( unsigned char address )void Read_RTC(void)//read RTC void Set_RTC(void)//set RTC void main(void) //入口函数 { Set_RTC()while(1){ Read_RTC()switch (l_tmpdate[0]/5) //设计每个5秒 交替显示 年月日 时分秒 { case 0: case 2: case 4: case 6: case 8: case 10: l_tmpdisplay[0]=l_tmpdate[2]/16//数据的转换,因我们采用数码管0~9的显示,将数据分开 l_tmpdisplay[1]=l_tmpdate[2]&0x0fl_tmpdisplay[2]=10//加入"-" l_tmpdisplay[3]=l_tmpdate[1]/16l_tmpdisplay[4]=l_tmpdate[1]&0x0fl_tmpdisplay[5]=10l_tmpdisplay[6]=l_tmpdate[0]/16l_tmpdisplay[7]=l_tmpdate[0]&0x0f breakcase 1: case 3: case 5: case 7: case 9: case 11: l_tmpdisplay[0]=l_tmpdate[6]/16l_tmpdisplay[1]=l_tmpdate[6]&0x0fl_tmpdisplay[2]=10l_tmpdisplay[3]=l_tmpdate[4]/16l_tmpdisplay[4]=l_tmpdate[4]&0x0fl_tmpdisplay[5]=10l_tmpdisplay[6]=l_tmpdate[3]/16l_tmpdisplay[7]=l_tmpdate[3]&0x0fbreakdefault: break} display(l_tmpdisplay,8)} } void display(unsigned char *lp,unsigned char lc)//显示 { unsigned char i//定义变量 P2=0//端口2为输出 P1=P1&0xF8//将P1口的前3位输出0,对应138译门输入脚,全0为第一位数码管 for(i=0i<lci++){ //循环显示 P2=table[lp[i]]//查表法得到要显示数字的数码段 delay()//延时 P2=0//清0端口,准备显示下位 if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据 break P1++//下一位数码管 } } void delay(void) //空5个指令 { unsigned char i=10while(i) i--} void Write_Ds1302_Byte(unsigned char temp) { unsigned char ifor (i=0i<8i++) //循环8次 写入数据 { SCL2=0SDA2=temp&0x01//每次传输低字节 temp>>=1//右移一位 SCL2=1} } /****************************************************************************/ void Write_Ds1302( unsigned char address,unsigned char dat ) { RST=0_nop_()SCL2=0_nop_()RST=1 _nop_()//启动 Write_Ds1302_Byte(address)//发送地址 Write_Ds1302_Byte(dat)//发送数据 RST=0//恢复 } /****************************************************************************/ unsigned char Read_Ds1302 ( unsigned char address ) { unsigned char i,temp=0x00RST=0_nop_()SCL2=0_nop_()RST=1_nop_()Write_Ds1302_Byte(address)for (i=0i<8i++) //循环8次 读取数据 { if(SDA2) temp|=0x80//每次传输低字节 SCL2=0temp>>=1//右移一位 SCL2=1} RST=0_nop_()//以下为DS1302复位的稳定时间 RST=0SCL2=0_nop_()SCL2=1_nop_()SDA2=0_nop_()SDA2=1_nop_()return (temp)//返回 } /****************************************************************************/ void Read_RTC(void) //读取 日历 { unsigned char i,*pp=read_rtc_address//地址传递 for(i=0i<7i++) //分7次读取 年月日时分秒星期 { l_tmpdate[i]=Read_Ds1302(*p)p++} } /***********************************************************************/ void Set_RTC(void) //设定 日历 { unsigned char i,*p,tmpfor(i=0i<7i++){ tmp=l_tmpdate[i]/10l_tmpdate[i]=l_tmpdate[i]%10l_tmpdate[i]=l_tmpdate[i]+tmp*16} Write_Ds1302(0x8E,0X00) p=write_rtc_address//传地址 for(i=0i<7i++) //7次写入 年月日时分秒星期 { Write_Ds1302(*p,l_tmpdate[i])p++ } Write_Ds1302(0x8E,0x80)} 希望对你有所帮助 本程序采用外元件DS1302

#include <REG51.H>#include <intrins.h>#define uint unsigned int#define uchar unsigned charsbit DS1302_CLK = P1^7//实时时钟时钟线引脚 sbit DS1302_IO = P1^6//实时时钟数据线引脚 sbit DS1302_RST = P1^5//实时时钟复位线引脚sbit wireless_1 = P3^0sbit wireless_2 = P3^1sbit wireless_3 = P3^2sbit wireless_4 = P3^3//无线控制sbit ACC0 = ACC^0sbit ACC7 = ACC^7char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year//秒,分,时到日,月,年位闪的计数sbit Set = P2^0//模式切换键sbit Up = P2^1//加法按钮sbit Down = P2^2//减法按钮sbit out = P2^3//立刻跳出调整模式按钮sbit DQ = P1^0//温度传送数据IO口char done,count,temp,flag,up_flag,down_flaguchar temp_value//温度值uchar TempBuffer[5],week_value[2]void show_time()//液晶显示程序/***********1602液晶显示部分子程序****************///Port Definitions**********************************************************sbit LcdRs = P2^5sbit LcdRw = P2^6sbit LcdEn = P2^7sfr DBPort = 0x80//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口 //内部等待函数**************************************************************************unsigned char LCD_Wait(void){ LcdRs=0LcdRw=1_nop_()LcdEn=1_nop_()LcdEn=0return DBPort}//向LCD写入命令或数据************************************************************#define LCD_COMMAND 0 // Command#define LCD_DATA 1 // Data#define LCD_CLEAR_SCREEN 0x01 // 清屏#define LCD_HOMING 0x02 // 光标返回原点void LCD_Write(bit style, unsigned char input){ LcdEn=0LcdRs=styleLcdRw=0_nop_()DBPort=input_nop_()//注意顺序 LcdEn=1_nop_()//注意顺序 LcdEn=0_nop_()LCD_Wait()} //设置显示模式************************************************************#define LCD_SHOW 0x04 //显示开#define LCD_HIDE 0x00 //显示关 #define LCD_CURSOR 0x02 //显示光标#define LCD_NO_CURSOR 0x00 //无光标 #define LCD_FLASH 0x01 //光标闪动#define LCD_NO_FLASH 0x00 //光标不闪动 void LCD_SetDisplay(unsigned char DisplayMode){ LCD_Write(LCD_COMMAND, 0x08|DisplayMode)} //设置输入模式************************************************************#define LCD_AC_UP 0x02#define LCD_AC_DOWN 0x00 // default #define LCD_MOVE 0x01 // 画面可平移#define LCD_NO_MOVE 0x00 //default void LCD_SetInput(unsigned char InputMode){ LCD_Write(LCD_COMMAND, 0x04|InputMode)} //初始化LCD************************************void LCD_Initial(){ LcdEn=0LCD_Write(LCD_COMMAND,0x38)//8位数据端口,2行显示,5*7点阵 LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR)//开启显示, 无光标 LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN)//清屏 LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE)//AC递增, 画面不动} //液晶字符输入的位置************************void GotoXY(unsigned char x, unsigned char y){ if(y==0) LCD_Write(LCD_COMMAND,0x80|x)if(y==1) LCD_Write(LCD_COMMAND,0x80|(x-0x40))} //将字符输出到液晶显示void Print(unsigned char *str){ while(*str!='\0') { LCD_Write(LCD_DATA,*str)str++}} /***********DS1302时钟部分子程序******************/typedef struct __SYSTEMTIME__{ unsigned char Secondunsigned char Minuteunsigned char Hourunsigned char Weekunsigned char Dayunsigned char Monthunsigned char Yearunsigned char DateString[11]unsigned char TimeString[9]}SYSTEMTIME//定义的时间类型SYSTEMTIME CurrentTime#define AM(X) X#define PM(X) (X+12) // 转成24小时制#define DS1302_SECOND 0x80 //时钟芯片的寄存器位置,存放时间#define DS1302_MINUTE 0x82#define DS1302_HOUR 0x84 #define DS1302_WEEK 0x8A#define DS1302_DAY 0x86#define DS1302_MONTH 0x88#define DS1302_YEAR 0x8C void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数){ unsigned char iACC = dfor(i=8i>0i--) { DS1302_IO = ACC0//相当于汇编中的 RRC DS1302_CLK = 1DS1302_CLK = 0ACC = ACC >>1} } unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数){ unsigned char ifor(i=8i>0i--) { ACC = ACC >>1//相当于汇编中的 RRC ACC7 = DS1302_IODS1302_CLK = 1DS1302_CLK = 0} return(ACC)} void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据{ DS1302_RST = 0DS1302_CLK = 0DS1302_RST = 1DS1302InputByte(ucAddr)// 地址,命令 DS1302InputByte(ucDa)// 写1Byte数据 DS1302_CLK = 1DS1302_RST = 0} unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据{ unsigned char ucDataDS1302_RST = 0DS1302_CLK = 0DS1302_RST = 1DS1302InputByte(ucAddr|0x01)// 地址,命令 ucData = DS1302OutputByte()// 读1Byte数据 DS1302_CLK = 1DS1302_RST = 0return(ucData)} void DS1302_GetTime(SYSTEMTIME *Time) //获取时钟芯片的时钟数据到自定义的结构型数组{ unsigned char ReadValueReadValue = Read1302(DS1302_SECOND)Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)ReadValue = Read1302(DS1302_MINUTE)Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)ReadValue = Read1302(DS1302_HOUR)Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)ReadValue = Read1302(DS1302_DAY)Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)ReadValue = Read1302(DS1302_WEEK)Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)ReadValue = Read1302(DS1302_MONTH)Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)ReadValue = Read1302(DS1302_YEAR)Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)} void DateToStr(SYSTEMTIME *Time) //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]{ if(hide_year<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22 { Time->DateString[0] = '2'Time->DateString[1] = '0'Time->DateString[2] = Time->Year/10 + '0'Time->DateString[3] = Time->Year%10 + '0'} else { Time->DateString[0] = ' 'Time->DateString[1] = ' 'Time->DateString[2] = ' 'Time->DateString[3] = ' '} Time->DateString[4] = '/'if(hide_month<2) { Time->DateString[5] = Time->Month/10 + '0'Time->DateString[6] = Time->Month%10 + '0'} else { Time->DateString[5] = ' 'Time->DateString[6] = ' '} Time->DateString[7] = '/'if(hide_day<2) { Time->DateString[8] = Time->Day/10 + '0'Time->DateString[9] = Time->Day%10 + '0'} else { Time->DateString[8] = ' 'Time->DateString[9] = ' '} if(hide_week<2) { week_value[0] = Time->Week%10 + '0'//星期的数据另外放到 week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示 } else { week_value[0] = ' '} week_value[1] = '\0'Time->DateString[10] = '\0'//字符串末尾加 '\0' ,判断结束字符} void TimeToStr(SYSTEMTIME *Time) //将时,分,秒数据转换成液晶显示字符放到数组 TimeString[]{ if(hide_hour<2) { Time->TimeString[0] = Time->Hour/10 + '0'Time->TimeString[1] = Time->Hour%10 + '0'} else { Time->TimeString[0] = ' 'Time->TimeString[1] = ' '} Time->TimeString[2] = ':'if(hide_min<2) { Time->TimeString[3] = Time->Minute/10 + '0'Time->TimeString[4] = Time->Minute%10 + '0'} else { Time->TimeString[3] = ' 'Time->TimeString[4] = ' '} Time->TimeString[5] = ':'if(hide_sec<2) { Time->TimeString[6] = Time->Second/10 + '0'Time->TimeString[7] = Time->Second%10 + '0'} else { Time->TimeString[6] = ' 'Time->TimeString[7] = ' '} Time->DateString[8] = '\0'} void Initial_DS1302(void) //时钟芯片初始化{ unsigned char Second=Read1302(DS1302_SECOND)if(Second&0x80) //判断时钟芯片是否关闭 { Write1302(0x8e,0x00)//写入允许 Write1302(0x8c,0x07)//以下写入初始化时间 日期:07/07/25.星期: 3. 时间: 23:59:55 Write1302(0x88,0x07)Write1302(0x86,0x25)Write1302(0x8a,0x07)Write1302(0x84,0x23)Write1302(0x82,0x59)Write1302(0x80,0x55)Write1302(0x8e,0x80)//禁止写入 } } /***********ds18b20子程序*************************/ /***********ds18b20延迟子函数(晶振12MHz )*******/ void delay_18B20(unsigned int i){ while(i--)} /**********ds18b20初始化函数**********************/ void Init_DS18B20(void) { unsigned char x=0DQ = 1//DQ复位 delay_18B20(8)//稍做延时 DQ = 0//单片机将DQ拉低 delay_18B20(80)//精确延时 大于 480us DQ = 1//拉高总线 delay_18B20(14)x=DQ//稍做延时后 如果x=0则初始化成功 x=1则初始化失败 delay_18B20(20)} /***********ds18b20读一个字节**************/ unsigned char ReadOneChar(void){ uchar i=0uchar dat = 0for (i=8i>0i--) { DQ = 0// 给脉冲信号 dat>>=1DQ = 1// 给脉冲信号 if(DQ) dat|=0x80delay_18B20(4)} return(dat)} /*************ds18b20写一个字节****************/ void WriteOneChar(uchar dat){ unsigned char i=0for (i=8i>0i--) { DQ = 0DQ = dat&0x01delay_18B20(5)DQ = 1dat>>=1}} /**************读取ds18b20当前温度************/ void ReadTemp(void){ unsigned char a=0unsigned char b=0unsigned char t=0Init_DS18B20()WriteOneChar(0xCC)// 跳过读序号列号的 *** 作 WriteOneChar(0x44)// 启动温度转换 delay_18B20(100)// this message is wery important Init_DS18B20()WriteOneChar(0xCC)//跳过读序号列号的 *** 作 WriteOneChar(0xBE)//读取温度寄存器等(共可读9个寄存器) 前两个就是温度 delay_18B20(100)a=ReadOneChar()//读取温度值低位 b=ReadOneChar()//读取温度值高位 temp_value=b<<4temp_value+=(a&0xf0)>>4}void temp_to_str() //温度数据转换成液晶字符显示{ TempBuffer[0]=temp_value/10+'0'//十位 TempBuffer[1]=temp_value%10+'0'//个位 TempBuffer[2]=0xdf//温度符号 TempBuffer[3]='C'TempBuffer[4]='\0'}void Delay1ms(unsigned int count){ unsigned int i,jfor(i=0i<counti++) for(j=0j<120j++)} /*延时子程序*/void mdelay(uint delay){ uint ifor(delay>0delay--) {for(i=0i<62i++) //1ms延时. {} }}

源程序如下: ORG 0000H 程序开始入口

LJMP START

ORG 0003H 外中断0中断程序入口

RETI

ORG 000BH 定时器T0中断程序入口

LJMP INTT0 跳至INTTO执行

ORG 0013H 外中断1中断程序入口

RETI

ORG 001BH 定时器T1中断程序入口

LJMP INTT1

ORG 0023H 串行中断程序入口地址

RETI

---------------主程序----------------------

START:MOV R0,#70H 70给R0,清70-7FH显示内存

MOV R7,#0FH

CLEARDISP:MOV @R0,#00H0给R0中的数为地址的内存中存放(70H)

INC R0

DJNZR7,CLEARDISP

MOV 78H,#2 默认时间为12:00,闹钟5:00

MOV 79H,#1

MOV 74H,#2 防止上电时数码管显示00小时

MOV 75H,#1

MOV 66H,#1 中断退出时66H为1时,分、时计时单元数据移入显存标志

MOV 68H,#1 上电默认闹钟开状态

MOV 7DH,#6 闹钟时十位

MOV 7CH,#3

MOV 69H,#0

MOV 7AH,#0AH放入"熄灭符"数据

MOV TMOD,#11H 设T0、T1为16位定时器

MOV TL0,#0B0H 50MS定时初值(T0计时用)

MOV TH0,#3CH

SETBEA 总中断开放

SETBET0 允许T0中断

SETBTR0 T0定时器开始计时

MOV R4,#14H 1秒定时用初值(50MS×20)

START1:LCALL DISPLAY 显示子程序

LCALL BEEP闹钟查询

JNB P1.7,SETTIMEP1.7口为0时转时间调整程序

JMP START1 P1.7口为1时跳回START1

-----------------------时间闹钟调整系统--------------------------

NFLAG:MOV A,68H 设置闹钟开关状态

CJNE A,#1,BEE68

MOV 68H,#0

JMP E6

BEE68:MOV 68H,#1

E6:MOV 66H,#8 中断退出66H不为1时分、时计时单元数据移入显存标志

MOV 72H,7BH

MOV 73H,7CH

MOV 74H,7DH

MOV 75H,7EH

LCALLDDL

LCALLDDL

MOV 72H,68H

MOV 73H,69H

MOV 74H,7AH

MOV 75H,7AH

LCALLDDL

LCALLDDL

MOV 66H,#1

LJMP START1

SETTIME:LCALLDDL

JB P1.7,NFLAG 键按下时间小于1秒,设置闹钟开关状态并查看闹钟时间,不关走时,确保准确,大于1秒调时

MOV TL1,#0B0H T1闪烁定时初值

MOV TH1,#3CH

MOV R2,#06H进入调时状态,赋闪烁定时初值

MOV 66H,#8 调闹钟时保持走时,关闭时钟显示数据

SETB ET1允许T1中断

SETB TR1开启定时器T1

SET1:LCALLDISPLAY调用显示,防止键按下无显示

JNB P1.7,SET1 P1.7口为0等待键释放

MOV R5,#00H清设置类型闪烁标志

SETN1:INC R5 闹钟分调整

SET5:LCALLDISPLAY

JB P1.7,SET5

SEETN1:LCALLDDL有键按下大于1秒分时间连续加(0.5秒加1),小于1秒转调时状态

JB P1.7,SET6 键释放查询,键释放自动转调时

MOV R0,#7CH

LCALL ADD1

MOV A,R3

CLR C

CJNEA,#60H,HHN1

HHN1:JCSEETN1

LCALL CLR0

JMP SEETN1

SET6:INC R5 闹钟时调整

SEET6:LCALLDISPLAY

JB P1.7,SEET6

SEETNH1:LCALLDDL

JB P1.7,SETF

MOV R0,#7EH

LCALLADD1

MOV A,R3

CLR C

CJNEA,#24H,HOUU1

HOUU1:JC SEETNH1

LCALL CLR0

JMP SEETNH1

SETF:LCALLDISPLAY

JB P1.7,SETF

LCALLDDL

JNB P1.7,SETOUT 短按调时,长按退出

CLR ET0

CLR TR0

MOV 70H,#00H设定后的时间从00秒开始走时

MOV 71H,#00H

INC R5

SET3:LCALLDISPLAY

JB P1.7,SET3

SETMM:LCALLDDL

JB P1.7,SET4

MOV R0,#77H

LCALL ADD1

MOV A,R3

CLR C

CJNEA,#60H,MMH

MMH:JC SETMM

LCALL CLR0

AJMP SETMM

SET4:INC R5

SEET4:LCALLDISPLAY

JB P1.7,SEET4

SETHH:LCALLDDL

JB P1.7,SETOUT1

MOV R0,#79H

LCALLADD1

MOV A,R3

CLR C

CJNEA,#24H,HOUU

HOUU:JC SETHH

LCALL CLR0

AJMP SETHH

SETOUT1:SETB ET0

SETB TR0 计时开始

SETOUT:MOV R5,#00H 清设置类型闪烁标志

CLRTR1 关闭T1

CLRET1 关T1中断

MOV 66H,#1

SETOUT2:LCALLDISPLAY

JNB P1.7,SETOUT2

LJMPSTART1

--------------------------延时1秒钟-----------------------

DDL:MOV 18H,#36

DDL0:MOV 17H,#239

DDL1:LCALLDISPLAY

DJNZ 17H,DDL1

DJNZ 18H,DDL0

RET

----------------------------T0中断程序------------------------

INTT0: PUSH ACC 打包

PUSH PSW

CLR ET0

CLR TR0

MOV A,#0B7H

ADD A,TL0

MOV TL0,A

MOV A,#3CH

ADDC A,TH0

MOV TH0,A

SETB TR0

DJNZ R4, OUTT0 20次中断未到中断退出

ADDSS: MOV R4,#14H 20次中断到(1秒)重赋初值

MOV R0,#71H 指向秒计时单元(70-71H)

ACALL ADD1 调用加1程序(加1秒 *** 作)

MOV A,R3 秒数据放入A(R3为2位十进制数组合)

CLR C 清进位标志

CJNE A,#60H,ADDMM

ADDMM: JC OUTT01小于60秒退出

ACALL CLR0 等于或大于60秒清0

MOV R0,#77H 指向分计时单元(76H-77H)

ACALL ADD1

MOV A,R3

CLR C

CJNE A,#60H,ADDHH

ADDHH: JC OUTT0

ACALL CLR0

MOV R0,#79H 指向小时计时单元(78H-79H)

ACALL ADD1

MOV A,R3

CLR C

CJNE A,#24H,HOUR

HOUR: JCOUTT0

ACALL CLR0

OUTT0: MOV A,66H 查询标志

CJNE A,#1,OUTT01

MOV 72H,76H 中断退出时将分、时计时单元数据移入对应显示单元

MOV 73H,77H

MOV 74H,78H

MOV 75H,79H

OUTT01:POP PSW 出栈

POP ACC

SETB ET0 开放T0

RETI中断返回

---------------------------加1程序--------------------------

ADD1: MOV A,@R0 取当前计时单元数据到A

DEC R0 指向前一地址

SWAP A A中数据高四位与低四位交换

ORL A,@R0 前一地址中数据放入A中低四位

ADD A,#01H A加1 *** 作

DA A 十进制调整

MOV R3,A 移入R3寄存器

ANL A,#0FH 高四位变0

MOV@R0,A 放回前一地址单元

MOV A,R3 取回R3中暂存数据

INCR0 指向当前地址单元

SWAP A A中数据高四位与低四位交换

ANL A,#0FH 高四位变0

MOV @R0,A 数据放入当削地址单元中

RET

CLR0: CLR C

CLR A 清累加器

MOV @R0,A 清当前地址单元

DEC R0 指向前一地址

MOV @R0,A 前一地址单元清0

RET 子程序返回

-------------------------调时闪烁程序----------------------

INTT1: PUSHACC

PUSHPSW

MOV TL1,#0B0H

MOV TH1,#3CH

DJNZR2,INTT1OUT0.3秒未到退出中断(50MS中断6次)

MOV R2,#06H 重装0.3秒定时用初值

CPL 02H0.3秒定时到对闪烁标志取反

JB 02H,FLASH1 02H位为1时显示单元"熄灭"

MOV A,R5

CJNEA,#01H,NL

JMP NNN1

NL:CJNEA,#02H,NL1

LJMPNNN1

NL1:CJNEA,#03H,NL2

LJMPNLL

NL2:CJNEA,#04H,INTT1OUT

LJMPNLL

NLL:MOV 72H,76H

MOV 73H,77H

MOV 74H,78H

MOV 75H,79H

AJMPINTT1OUT

NNN1:MOV 72H,7BH

MOV 73H,7CH

MOV 74H,7DH

MOV 75H,7EH

INTT1OUT:POP PSW 恢复现场

POP ACC

RETI 中断退出

FLASH1:MOV A,R5

CJNEA,#01H,ML

LJMPMNN1

ML:CJNEA,#02H,ML1

LJMPMNN2

ML1:CJNEA,#03H,MN

LJMPMLL

MN:CJNEA,#04H,INTT1OUT

LJMPMHL

MLL:MOV 72H,7AH

MOV 73H,7AH 显示单元(72-73H),将不显示分数据

MOV 74H,78H

MOV 75H,79H

AJMPINTT1OUT

MHL:MOV 72H,76H

MOV 73H,77H

MOV 74H,7AH 显示单元(74-75H),小时数据将不显示

MOV 75H,7AH

AJMPINTT1OUT

MNN1:MOV 72H,7AH

MOV 73H,7AH 显示单元(72-73H),将不显示闹钟分数据

MOV 74H,7DH

MOV 75H,7EH

AJMPINTT1OUT

MNN2:MOV 72H,7BH

MOV 73H,7CH

MOV 74H,7AH

MOV 75H,7AH 显示单元(74-75H),闹钟小时数据将不显示

AJMPINTT1OUT

-------------------------显示-------------------------------

DISPLAY:MOVDPTR,#DISDATA

MOVA,70H

MOVC A,@A+DPTR

MOVP3,A

CLRP1.0

NOP

NOP

NOP

SETB P1.0

MOVA,71H

MOVC A,@A+DPTR

MOVP3,A

CLRP1.1

NOP

NOP

NOP

SETB P1.1

MOVA,72H

MOVC A,@A+DPTR

MOVP3,A

CLRP1.2

NOP

NOP

NOP

SETB P1.2

MOVA,73H

MOVC A,@A+DPTR

MOVP3,A

CLRP1.3

NOP

NOP

NOP

SETB P1.3

MOVA,74H

MOVC A,@A+DPTR

MOVP3,A

CLRP1.4

NOP

NOP

NOP

SETB P1.4

MOVA,75H

MOVC A,@A+DPTR

MOVP3,A

CLRP1.5

NOP

NOP

NOP

SETB P1.5

RET

BEEP:MOV A,68H 查询标志

CJNE A,#1,BEERE

MOV A,78H 查询闹钟时个位

CJNE A,7DH,BEERE

MOV A,79H 查询闹钟时十位

CJNE A,7EH,BEERE

MOV A,76H 查询闹钟分个位

CJNE A,7BH,BEERE

MOV A,77H 查询闹钟分十位

CJNE A,7CH,BEERE

BB:CLR P1.6

LCALL DDL

SETB P1.6

LCALL DDL

JNB P1.7,BEERR

BEERE:RET

BEERR:SETB P1.6

MOV 68H,#0

LCALL DISPLAY

JNB P1.7,BEERR

JMP BEERE

DISDATA:DB 0C0H,0F9H,64H,70H,59H,52H,42H,0F8H,40H,50H,0FFH 0123456789空白

END


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11123791.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-13
下一篇 2023-05-13

发表评论

登录后才能评论

评论列表(0条)

保存