单片机时钟程序

单片机时钟程序,第1张

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秒的程序,用汇编!!、单片机数字时钟汇编程序设计分析等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址:https://54852.com/zz/9276761.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存