#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
评论列表(0条)