
AJMP STRAT
ORG 0003H ;中断0入口地址
ACALL DEL
AJMP INTA ;跳转到中断0服务程序
ORG 0013H ;中断1入口地址
ACALL DEL
AJMP INTB ;跳转到中断1服务程序
STRAT:SETB EA
SETB EX0
SETB EX1
SETB IT0
SETB IT1
;
A8:MOV R6,#0 ;24进制计数器
MOV R5,#0
MOV 25H,#3FH ;时十位
A7:MOV R4,#0
MOV 24H,#3FH ;时个位
A6:MOV R3,#0
MOV 23H,#3FH ;分十位
A5:MOV R2,#0
MOV 22H,#3FH ;分个位
A4:MOV R1 ,#0
;MOV 21H,#3FH; ;秒十位
SETB 21H0
SETB 21H1
SETB 21H2
SETB 21H3
SETB 21H4
SETB 21H5
CLR 21H6
CLR 21H7
A3:MOV R0,#0
MOV 20H,#3FH ;秒个位
;
A2:MOV A,R0
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV 20H,A
MOV A,R1
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV 21H,A
MOV A,R2
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV 22H,A
MOV A,R3
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV 23H,A
MOV A,R4
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV 24H,A
MOV A,R5
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV 25H,A
;
MOV 31H,#21
B1:MOV 30H ,#0F0H
A1:MOV P0,20H ;点亮秒个位数码管
CLR P13
ACALL DEL
SETB P13
MOV P0,21H ;点亮秒十位数码管
CLR P12
ACALL DEL
SETB P12
MOV P0,22H ;点亮分个位数码管
CLR P11
ACALL DEL
SETB P11
MOV P0,23H ;点亮分十位数码管
CLR P10
ACALL DEL
SETB P10
MOV P0,24H ;点亮时个位数码管
CLR P27
ACALL DEL
SETB P27
MOV P0,25H ;点亮时十位数码管
CLR P26
ACALL DEL
SETB P26
DJNZ 30H,A1
DJNZ 31H,B1
;
INC R0
CJNE R0,#10,A2
INC R1
CJNE R1,#6,A3
INC R2
;
SETB P14 ;1分钟后关定时
CJNE R2,#0,A11;分个位定时
CJNE R3,#0,A11;分十位定时
CJNE R6,#19,A11;时位定时
CLR P14 ;开定时
;
A11:CJNE R2,#10,A44
INC R3
A12:CJNE R3,#6,A55
INC R6
CJNE R6,#24,A9
AJMP A8
A9:INC R4
CJNE R4,#10,A66
INC R5
CJNE R5,#3,A77
AJMP A8
A44:AJMP A4
A55:AJMP A5
A66:AJMP A6
A77:AJMP A7
;
DEL:MOV R7,#0AH ;延时子程序
AA:DJNZ R7,AA
RET
TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
INTA: INC R2 ;中断0服务程序
CJNE R2, #10,B2
MOV R2,#0
INC R3
CJNE R3,#6,B2
MOV R3,#0
B2:RETI
INTB:INC R6 ;中断1服务程序
CJNE R6,#24,B4
MOV R6,#0
MOV R4,#0
MOV R5,#0
AJMP B3
B4:INC R4
CJNE R4, #10,B3
MOV R4,#0
INC R5
CJNE R5,#3,B3
MOV R5,#0
B3:RETI
END
DEL1S:MOV R7,#10
D1: MOV R6,#200
D2: MOV R5,#250
DJNZ R5,$
DJNZ R6,D2
DJNZ R7,D1
RET
说明:1、如果不使用R5、R6、R7可以用别的单元替换,比如换成30H、31H、32H等等
2、这个程序是12M时钟,如果时钟不同,要修改数值。如6M时钟,要把MOV R7,#10 修改成:MOV R7,#5
时钟设计基本上就是通过电子 定时器定时 到1s给一个中断 让单片机去执行中断 跳转至相应的数码管位 然后修改当前显示值 再设置到10进位加一 之后就出来数字时钟的效果 弄懂定时器 一切就顺下来了
这是一个C得时钟程序 你看明白思想 就好说汇编的语句了
#include <reg52h>
#include <intrinsh>
#define uchar unsigned char
sbit dula=P3^7;
sbit L1=P2^0;
sbit L2=P2^1;
sbit L3=P2^2;
sbit key1=P3^0;
sbit key2=P3^1;
sbit key3=P3^2;
sbit key4=P3^3;
uchar aa;
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
uchar nummiao,numfen,numshi,t0;
void delayms(uchar xms)
{
uchar i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void init()
{
TMOD=0x11;
TH0=(65536-50000)%256;
TL0=(65536-50000)/256;
EA=1;
ET0=1;
}
void display(uchar nummiao,numfen,numshi)
{
uchar shishi,geshi,shifen,gefen,shimiao,gemiao;
shimiao=nummiao/10;
gemiao=nummiao%10;
shifen=numfen/10;
gefen=numfen%10;
shishi=numshi/10;
geshi=numshi%10;
dula=1;
P0=table[shimiao];
dula=0;
L1=0;
L2=1;
L3=1;
delayms(5);
dula=1;
P0=table[gemiao];
dula=0;
L1=1;
L2=1;
L3=1;
delayms(5);
dula=1;
P0=0x40;
dula=0;
L1=1;
L2=0;
L3=1;
delayms(5);
dula=1;
P0=table[gefen];
dula=0;
L1=0;
L2=0;
L3=1;
delayms(5);
dula=1;
P0=table[shifen];
dula=0;
L1=1;
L2=1;
L3=0;
delayms(5);
dula=1;
P0=0x40;
dula=0;
L1=0;
L2=1;
L3=0;
delayms(5);
dula=1;
P0=table[geshi];
dula=0;
L1=1;
L2=0;
L3=0;
delayms(5);
dula=1;
P0=table[shishi];
dula=0;
L1=0;
L2=0;
L3=0;
delayms(5);
}
void keyscan()
{
if(key1==0)
{
delayms(10);
if(key1==0)
{
numshi++;
if(numshi==24)
numshi=0;
while(!key1);
}
}
if(key2==0)
{
delayms(10);
if(key2==0)
{
if(numfen==60)
numfen=0;
numfen++;
while(!key2);
}
}
if(key3==0)
{
delayms(10);
if(key3==0)
{
nummiao=0;
while(!key3);
}
}
if(key4==0)
{
delayms(10);
if(key4==0)
{
while(!key4);
TR0=~TR0;
}
}
}
void main()
{
init();
aa=0xfe;
while(1)
{
P1=aa;
if(nummiao==60)
{
numfen++;
nummiao=0;}
if(numfen==60)
{ numshi++;
numfen=0;}
if(numshi==24)
numshi=0;
keyscan();
display(nummiao,numfen,numshi);
}
}
void t0time()interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
t0++;
if(t0==20)
{
t0=0;
nummiao++;}
aa=_crol_(aa,1);
}
;;时钟程序,计数器,定时器,键控,动态扫描显示,时、分、秒,第2,4 数码管加小数点,第4数码管小数点每秒闪烁一次。
110592Mhz。
HOU EQU 42H;时
MIN EQU 41H;分
SEC EQU 40H;秒
;4键方式,选择、加、减、确认键 起始时、分、秒值,每按一次,被修改数码管顺序移动并闪烁;确认键确定修改结束
K1 BIT P31;选择
K2 BIT P32;+
K3 BIT P33;-
K4 BIT P34;确认键
LED1 BIT P21;时
LED2 BIT P22;
LED3 BIT P23;
LED4 BIT P24;
LED5 BIT P25;
LED6 BIT P26;秒
;定时器T0设置为50MS溢出中断,为秒计数用,
;P0口为字符输出口P00接点,P01~07接ABCDEFG,P21-P26为位控制口-采用共阳显示管。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 中断入口程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
ORG 0000H
LJMP START
;---------------------------------
ORG 000BH ;;定时器0中断
LJMP INTT0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 主 程 序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
START:MOV 20H,#1
MOV 50H,#10
MOV 51H,#2
MOV DPTR,#TAB
MOV TMOD,#01H ;;定时器0-1方式1工作
MOV TH0,#4CH
MOV TL0,#00H
SETB EA ;;总中断允许
SETB ET0 ;;定时器0中断允许
SETB TR0 ;;启动定时器0
MAIN:
ACALL DISPLAY ;;调显示
ACALL KEY1 ;查询按键
ACALL KEY2 ;查询按键
ACALL KEY3 ;查询按键
ACALL KEY4 ;查询按键
SJMP MAIN ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;定时程 序 ;;定时中断0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
INTT0:
PUSH ACC
PUSH PSW
MOV TH0,#4CH
MOV TL0,#00H
DJNZ 50H,RETI1 ;;05秒到
MOV 50H,#10
CPL 0AH ;取反闪动位
DJNZ 51H,RETI1
MOV 51H,#2;1秒到
MOV A,SEC
ADD A,#01H
MOV SEC,A
CJNE A,#60,RETI1
MOV SEC,#00H ;一分钟时间到
MOV A,MIN
ADD A,#01H
MOV MIN,A
CJNE A,#60,RETI1
MOV MIN,#00H ;一小时时间到
MOV A,HOU
ADD A,#01H
MOV HOU,A
CJNE A,#24,RETI1
MOV HOU,#00H ;到时间达到24小时,清零
RETI1: POP PSW ;恢复现场
POP ACC
RETI ;中断返回
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 时钟调整程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
KEY1: JB K1,TTT;设置
ACALL DS20MS;延时消抖
JB K1,TTT
MOV A,20H
RL A
JNB ACC4,UUU
MOV A,#10B
UUU:MOV 20H,A
TTT:RET
KEY4: JB K4,TTT;退出
ACALL DS20MS;延时消抖
JB K4,TTT
MOV 20H,#1
RET
KEY2:JB K2,TTT;加
ACALL DS20MS;延时消抖
JB K2,TTT
JB 0H,TTT
JB 1H,ADDHOU
JB 2H,ADDMIN
JB 3H,ADDSEC
RET
KEY3:JB K3,TTT;减
ACALL DS20MS;延时消抖
JB K3,TTT
JB 0H,TTT
JB 1H,DECHOU
JB 2H,DECMIN
JB 3H,DECSEC
RET
ADDHOU:INC HOU
RET
ADDMIN:INC MIN
RET
ADDSEC:INC SEC
RET
DECHOU:DEC HOU
RET
DECMIN:DEC MIN
RET
DECSEC:DEC SEC
RET
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 显示程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DISPLAY:
JNB 1H,AA
JNB 0AH,BB
AA:
;显示小时
MOV A,HOU
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV P0,A
CLR LED1
ACALL DL1M
SETB LED1
MOV A,B
MOVC A,@A+DPTR
CLR ACC0;显示点
MOV P0,A
CLR LED2
ACALL DL1M
SETB LED2
JNB 2H,BB
JNB 0AH,CC
BB:
;
;显示分
MOV A,MIN
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV P0,A
CLR LED3
ACALL DL1M
SETB LED3
MOV A,B
MOVC A,@A+DPTR
MOV C,0AH
MOV ACC0,C ;闪动
MOV P0,A
CLR LED4
ACALL DL1M
SETB LED4
JNB 3H,CC
JNB 0AH,DD
CC:
;
;显示秒
MOV A,SEC
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV P0,A
CLR LED5
ACALL DL1M
SETB LED5
MOV A,B
MOVC A,@A+DPTR
MOV P0,A
CLR LED6
ACALL DL1M
SETB LED6
DD: RET
;
TAB: DB 7EH,42H,0B6H,0E6H,0CAH,0ECH,0FCH,46H,0FEH ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 延时程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DL1M: ;延时1MS
MOV R6,#66H
DL0:
MOV R5,#03H
DJNZ R5,$
DJNZ R6,DL0
RET
;-----------------------
DS20MS: MOV R4,#03 ;延时20MS
OOO:
ACALL DISPLAY
DJNZ R4,OOO
RET
END
基于c8051f020单片机最小系统的实时时钟显示程序
c8051f020 FYD12864-0402B LCD显示,按键电子时钟//
#include <c8051f020h>
#include<lcdh>
#include <intrinsh>
#define uchar unsigned char
void lcd_ini();
void DISPInitial();
void ascii_change(void);
void delay();
void wri_add(uchar com);
void wri_dat(uchar com1);
void shan(void);
void disp();
void tkey(void);
void PORT_Init (void);
sbit cs=P1^7;
sbit sid=P1^6;
sbit sclk=P1^5;
bit flag=1;
uchar dat,count,f=1;//f测试哪个单元为当前闪烁状态
uchar data clock[3]={24,00,00};
uchar code clockname[10]={"北京时间:"};
uchar data num[6];
/主程序/
void main()
{
lcd_ini();
count=10;//机器周期为1us,每次定时50ms,此变量用来控制循环次数,在下面赋值为20,共定时1秒
TMOD=0x01;
TL0=0XB0;
TH0=0X3C;
EA=1;
ET0=1;
IT0=1;
EX0=1;
TR0=1;
while(1)
{
back:ascii_change();
disp();
delay();
if(flag==1)
goto back;
tkey();
shan();
delay();
}
}
/lcd初始化/
/void lcd_ini()
{
wri_add(0x30);
delay();
wri_add(0x0c);
delay();
wri_add(0x01);
delay();
wri_add(0x06);
delay();
}/
void PORT_Init (void)
{
XBR0 = 0x00; //不让他连上IO口
XBR1 = 0x14; //允许外部中断连在端口上
XBR2 = 0x40; // Enable crossbar and weak pull-ups
P0MDOUT |= 0x00; // enable TX0 as a push-pull output
// P1MDOUT |= 0x07; // enable P16 (LED) as push-pull output
P2MDOUT=0xfe; //为了驱动步进电机的控制线
//P3MDOUT = 0xFF;
P74OUT=0x00; //配置成漏极方式可以让LCD显示成功 ,我试了配置成推挽方式不能正常显示
}
/定时程序/
void timer1() interrupt 1 using 2
{
TL0=0XB0;
TH0=0X3C;
count--;
if(count==0)
{
count=10;
clock[2]++;//秒//
}
else
goto out;
if(clock[2]==60)
{
clock[2]=0;
clock[1]++;//分//
}
if(clock[1]==60)
{
clock[1]=0;
clock[0]++;
}
if(clock[0]==24)//时//
clock[0]=0;
out:_nop_();
}
/十位个位转换成ASCII码/
void ascii_change(void)
{
num[5]=clock[2]-(clock[2]/10)10+0x30;
num[4]=clock[2]/10+0x30;
num[3]=clock[1]-(clock[1]/10)10+0x30;
num[2]=clock[1]/10+0x30;
num[1]=clock[0]-(clock[0]/10)10+0x30;
num[0]=clock[0]/10+0x30;
}
/廷时程序/
void delay()
{
uchar i,j;
for (i=250;i>0;i--)
for (j=250;j>0;j--);
}
/Write address/
void wri_add(uchar com)
{
uchar i,j,k;
cs=0;
cs=1;
dat=0xf8;
for(i=1;i<=8;i++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com;
dat=dat&0xf0;
for(j=1;j<=8;j++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com;
dat=_cror_(dat,4);// 此为高低四位交换
dat=dat&0xf0;
for(k=1;k<=8;k++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
}
/Write data/
void wri_dat(uchar com1)
{
uchar i,j,k;
cs=0;
cs=1;
dat=0xfa;
for(i=1;i<=8;i++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com1;
dat=dat&0xf0;
for(j=1;j<=8;j++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com1;
dat=_cror_(dat,4);// 此为高低四位交换
dat=dat&0xf0;
for(k=1;k<=8;k++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
}
/display program/ //显示时间
void disp()
{
uchar i,k=0;
wri_add(0x80);
for (i=1;i<=9;i++)
wri_dat(clockname[i-1]);
wri_add(0x90);
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//时间之间的冒号。
wri_dat(num[i-1]);
}
}
/闪烁程序/
void shan(void)
{
uchar i,k=0;
wri_add(0x90);
if(f==1)
{
num[0]=' ';
num[1]=' ';
}
else
goto next;
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//时间之间的冒号。
wri_dat(num[i-1]);
}
goto return1;
next: if(f==2)
{
num[2]=' ';
num[3]=' ';
}
else
goto next1;
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//时间之间的冒号。
wri_dat(num[i-1]);
}
goto return1;
next1: if(f==3)
{
num[4]=' ';
num[5]=' ';
}
else
goto return1;
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//时间之间的冒号。
wri_dat(num[i-1]);
}
return1:_nop_();
}
/外部中断/
void intr0() interrupt 0 using 2
{
flag=~flag;//判断是否闪烁位//
TR0=~TR0; //闪关定时否则开定时
f=1;
}
/按键程序/
void tkey(void)
{
uchar judcekey;
judcekey=P1&0x0f;
if(judcekey==0x0f)
goto return2;
/移位键/
if (judcekey==0x0e)
f++;
if (f==4)
f=1;
/加一键/
if(judcekey==0x0d)
{clock[f-1]++;}
if (f==1)
{ if (clock[f-1]==24){
clock[f-1]=0;}
}
else{ if (clock[f-1]==60)
clock[f-1]=0;
}
/减一键/
if(judcekey==0x0b)
{clock[f-1]--;}
if (f==1)
{ if (clock[f-1]==0xff){
clock[f-1]=23;}
}
else
{ if (clock[f-1]==0xff)
clock[f-1]=59;
}
return2:_nop_();
}
//本程序已经调试成功并能够正确执行
以上就是关于单片机时钟程序全部的内容,包括:单片机时钟程序、求一个51单片机延时1秒的程序,用汇编!!、单片机数字时钟汇编程序设计分析等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)