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
#define uchar unsigned char // (先定义一下方便使用)
#define uint unsigned int
#define ulong unsigned long
#include <reg52.h>//包括一个52标准内核的头文件
uchar code zixing[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}
uchar code ziwei[]={0x10,0x20,0x40,0x80}
uchar *h,*m
uchar hour=12,min=0,sec=0,h_ding,m_ding,count=0,ms_50,ms_10,miaobiao_sec
sbit dp=P0^7
sbit k1=P3^2
sbit k2=P3^3
sbit k3=P3^4
sbit sound=P2^3
sfr ZIXING=0x80//p0口输出字形
sfr ZIWEI=0xa0//P2口输出字位
typedef enum //枚举类型:4种状态//
{
CLOCK,
SET_RING1,
SET_RING2,
MIAOBIAO_RUN,
}STATE
STATE status
typedef struct //定时时间的数据结构//
{
uchar hour
uchar min
}DINGSHI_TIME
DINGSHI_TIME dingshi_time[2]
#define NO_KEY -1 //定义一下方便使用
#define KEY_1 1
#define KEY_2 2
#define KEY_3 3
bit show_on_flag
//#######定时器T0中断服务程序########//
Timer0() interrupt 1
{
TH0=0x3cTL0=0xb4//50ms
ms_50++
if(ms_50==20) {sec++ms_50=0}
if(sec==60) {sec=0min++}
if(min==60) {min=0hour++}
if(hour==24) {hour=0}
}
//#######定时器T1中断服务程序########//
Timer1() interrupt 3
{
TH1=0xd8TL1=0xf4//10ms
ms_10++
if(ms_10==100)
{
miaobiao_sec++
ms_10=0
}
if(miaobiao_sec==60)
miaobiao_sec=0
}
//##############数码管显示#####################//
show(uchar time_high,uchar time_low)
{
uchar m
uint n,k
k=time_high*1000/10+time_low
for(m=0m<4m++)
{
ZIXING=zixing[k%10]
if(ms_50<10)
dp=0
ZIWEI=~ziwei[m]
for(n=0n<500n++)
ZIXING=0xff
for(n=0n<100n++)
k=k/10
}
}
//显示 on 定时编号//
show_on(uchar id) //id:定时编号//
{
uchar m
uint n
for(m=0m<2m++)
{
ZIXING=zixing[id%10]
dp=0
ZIWEI=~ziwei[m]
for(n=0n<500n++)
ZIXING=0xff
for(n=0n<80n++)
id=id/10
}
ZIXING=0xc8//字母n//
ZIWEI=~ziwei[2]
for(n=0n<500n++)
ZIXING=0xff
for(n=0n<200n++)
ZIXING=0xc0//字母0//
ZIWEI=~ziwei[3]
for(n=0n<500n++)
ZIXING=0xff
for(n=0n<200n++)
}
/*************启动秒表***************/
void run_miaobiao()
{
ms_10=0
miaobiao_sec=0
TH1=0xd8//标准是0xd8e4
TL1=0xf4
// TR1=1//启动定时器1
}
显示秒表:
void show_miaobiao()
{
show(miaobiao_sec,ms_10)
}
以下是四位数码管可调时带秒闪烁的c51单片机电子钟程序(c语言)。/**** 本程序中,晶振为12MHz, ****/
/**** 时间控制采用定时中断控制方式。 ****/
/**** 模式和时间调整采用查询方式。 ****/
#include<reg52.h>
sbit P20=P2^0 //分个位控制端
sbit P21=P2^1 //分十位控制端
sbit P22=P2^2 //时个位控制端
sbit P23=P2^3 //时十位控制端
sbit led=P2^7 //second display led
sbit key0=P3^0 //模式设置
sbit key1=P3^1 //加
sbit key2=P3^2 //减
unsigned char hour,min,sec,T50ms
unsigned char modstate //模式状态
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}//段码
void init() //初始化子程序声明
void delay500us(unsigned char X) //延时子程序声明
void display() //显示子程序声明
void display001() //显示子程序声明
void display002() //显示子程序声明
void keyscan() //按键识别子程序声明
void main()
{
init()
while(1)
{
keyscan()
}
}
void init() //初始化子程序
{
TMOD=0x01
TH0=(65536-49990)/256
TL0=(65536-49990)%256
ET0=1
EA=1
TR0=1
}
void delay500us(unsigned char X)
{
unsigned char i,j
for(i=Xi>0i--)
for(j=248j>0j--)
}
void timer0() interrupt 1 //timer0中断服务子程序,定时时间为50ms,本程序加了10us的时间修正量
{
TMOD=0x01
TH0=(65536-49990)/256
TL0=(65536-49990)%256
T50ms++
if(T50ms>=20)
{
T50ms=0
sec++
if(sec>=60)
{
sec=0
min++
if(min>=60)
{
min=0
hour++
if(hour>=24)hour=0
}
}
}
}
void display()
{
P20=1
P21=1
P22=1
P23=1
P0=table[hour/10]
P23=0
delay500us(5)
P20=1
P21=1
P22=1
P23=1
P0=table[hour%10]
P22=0
delay500us(5)
P20=1
P21=1
P22=1
P23=1
P0=table[min/10]
P21=0
delay500us(5)
P20=1
P21=1
P22=1
P23=1
P0=table[min%10]
P20=0
delay500us(5)
if(T50ms<=10)led=0
if(T50ms>10)led=1
}
void display001()
{
P20=1
P21=1
P22=1
P23=1
P0=table[hour/10]
P23=0
delay500us(10)
P20=1
P21=1
P22=1
P23=1
P0=table[hour%10]
P22=0
delay500us(10)
}
void display002()
{
P20=1
P21=1
P22=1
P23=1
P0=table[min/10]
P21=0
delay500us(10)
P20=1
P21=1
P22=1
P23=1
P0=table[min%10]
P20=0
delay500us(10)
}
void keyscan() //按键识别钟程序
{
while(modstate==0)
{
display()
if(key0==0)
{
display()
if(key0==0)modstate++ //这两句加在一起为延时10ms软件防抖设计。
while(key0==0)display001() //等待按键释放。
}
}
//****************************************************************************//
while(modstate==1)
{
display001()
if(key0==0)
{
display001()
if(key0==0)modstate++ //这两句加在一起为延时10ms软件防抖设计。
while(key0==0)display002() //等待按键释放。
}
if(key1==0)
{
display001()
if(key1==0)
{
hour++
if(hour>=24)hour=0
while(key1==0)display001()
}
}
if(key2==0)
{
display001()
if(key2==0)
{
hour--
if(hour>=24)hour=0
while(key2==0)display001()
}
}
}
//****************************************************************************//
while(modstate==2)
{
display002()
if(key0==0)
{
display002()
if(key0==0)modstate=0 //这两句加在一起为延时10ms软件防抖设计。
while(key0==0)display() //等待按键释放。
}
if(key1==0)
{
display002()
if(key1==0)
{
min++
if(min>=60)min=0
while(key1==0)display002()
}
}
if(key2==0)
{
display002()
if(key2==0)
{
min--
if(min>=60)min=0
while(key2==0)display002()
}
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)