求一个简单的单片机时钟程序

求一个简单的单片机时钟程序,第1张

#include<reg51h>

#define uchar unsigned char

uchar code ledtab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0-9

unsigned char sec=0,min=0,hour=0,scanled;

unsigned char key,time; 

unsigned char disdat[6];

sbit K=P1^0;

void dischg()

{

disdat[0]=sec%10;

disdat[1]=sec/10;

disdat[2]=min%10;

disdat[3]=min/10;

disdat[4]=hour%10;

disdat[5]=hour/10;

}

void t0isr() interrupt 1 //秒计时

{

TR0=0;

TH0=0x3c;

TL0=0xb0;

TR0=1;

time++;

if(time==20)

{

time=0;

sec++;

if(sec>59)

{

sec=0;

min++;

if(min>59)

{

min=0;

hour++;

if(hour>23)hour=0;

}

}

}

dischg();

}

void t1isr() interrupt 3 //显示

{

TH1=0xec;

TL1=0x78;

switch(scanled)

{

case 0:

P2=0x01;

P0=~ledtab[disdat[5]];

break;

case 1:

P2=0x02;

P0=~ledtab[disdat[4]]&0x7f;

break;

case 2:

P2=0x04;

P0=~ledtab[disdat[3]];

break;

case 3:

P2=0x08;

P0=~ledtab[disdat[2]]&0x7f;

break;

case 4:

P2=0x10;

P0=~ledtab[disdat[1]];

break;

case 5:

P2=0x20;

P0=~ledtab[disdat[0]];

break;

default:break;

}

scanled++;

scanled%=6;

}

main()

{

TMOD=0x11;

TH0=0x3c;

TL0=0xb0;

TH1=0xec;

TL1=0x78;

EA=1;

TR1=1;

ET0=1;

ET1=1;

sec=0;

min=0;

hour=0;

scanled=0;

time=0;

key=0;

dischg();

while(1)

{

if(K==0)

{

while(K==0);

key++;

key%=2;

}

switch(key)

{

case 0:

TR0=1;

break;

case 1:

TR0=0;

break;

}

}

}

带万年历的LCD显示多功能数字钟

程序清单:

;                    SMC1602接口程序(MCS51模拟口线方式)

;

;连线图: LCM---8031 LCM---8031 LCM------------8031

;        DB0---P00 DB4---P04 RS-------------P20

;        DB1---P01 DB5---P05 RW-------------P21

;        DB2---P02 DB6---P06 E--------------P22

;        DB3---P03 DB7---P07 VLCD接10K可调电阻到GND

;注:8051的晶振频率为110592MHz R0设置数据存放 S8为设置键 S7为加键 S4为确认键

;

;P0口液晶显示

; P24位选键P23加一键P22返回键及报时功能键闹钟设置P20控制显示键

;寄存器 clr rs0 setb rs1 R0 R4 R5在按键中用到  延时中用到 SETB RS0   SETB RS1的R0 R1 R2

;SETB RS0  CLR RS1显示中用到  CLR  RS0  CLR  RS1 在闹钟调整子程序中用到R1

;

;

;报时功能P26    和闹钟功能P25  闹钟调整时间功能已经可以设置     显示的切换方式变了   再关闭的情况下一切正常运行

;

RSPIN   BIT     P12

RWPIN   BIT     P11

EPIN    BIT     P10

WEIXUAN BIT P24 ;位选键设置键

JIAJIAN BIT P23 ;加一键

JIANJIAN BIT P22 ;减一键

FANHUI BIT P21 ;返回键

NZKG BIT P20 ;闹钟设置键

SECONTL EQU 30H ;秒

SECONTH EQU 31H ;秒

MAOHAOL EQU 32H ;:

MINIUTL EQU 33H ;分

MINIUTH EQU 34H ;分

MAOHAOH EQU 35H ;:

HOURL EQU 36H ;时

HOURH EQU 37H ;时

;日期部分

DAYL EQU 40H ;日个

DAYH EQU 41H ;日十

HENL EQU 42H ;-

MONTHL EQU 43H ;yue

MONTHH EQU 44H ;yue

HENH EQU 45H ;-

YEARO EQU 46H ;年

YEART EQU 47H

YEARS EQU 48H

YEARF EQU 49H

TEMP EQU 50H   ;用做存储单元显示子程序(DISPLAY)里用到

BIJIAO EQU 51H ;加一子程序(JIAYI)中用到

ZDRQO EQU 55H ;中断加一程序中用到

ZDRQT EQU 56H ;中断加一程序中用到

ZDRQS EQU 57H ;中断加一程序中用到

ZDRQF EQU 58H ;中断加一程序中用到

DIZHI EQU 59H ;键盘(JIANPAN)子程序里用到

NZBZ BIT 60H ;定时标志位在(闹钟开关部分)

;38H到3FH没用到

BSCSBZ BIT 39H ;报时次数转换标志    (BSCS)里用到

BSCSCC EQU 3AH ;报时次数存储  (BSCS)里用到

ZDBSBZ BIT 3BH ;整点报时标志  (SSBS)里用到

ZMBSBZ BIT 3CH ;整秒闪烁标志  (SSBS)里用到

BSKGBZ BIT 3DH ;报时开启标志  (BSKG)里用到

XKQHBZ BIT 3EH ;显示开启关闭标志 (XIANKONG)里用到

ORG 0000H

AJMP MAIN

ORG 000BH

AJMP ZD

ORG 0030H

MAIN:  MOV SP,#60H  ;给堆栈指针赋初值

MOV 30H,#05H ;秒

MOV 31H,#05H ;秒

MOV 32H,#3AH ;:

MOV 33H,#09H ;分

MOV 34H,#05H ;分

MOV 35H,#3AH ;:

MOV 36H,#03H ;时

MOV 37H,#01H ;时

;日期部分

MOV 40H,#09H ;日个

MOV 41H,#02H ;日十

MOV 42H,#2DH ;-

MOV 43H,#09H ;yue

MOV 44H,#00H ;yue

MOV 45H,#2DH ;-

MOV 46H,#09H ;年

MOV 47H,#09H

MOV 48H,#09H

MOV 49H,#02H

CLR  P25  ;闹钟

CLR P26  ;整点报时

MOV 03H,#00H  ;闹钟分个位

MOV 04H,#00H  ;闹钟分十位

MOV 06H,#04H  ;闹钟时个位

MOV 07H,#01H  ;闹钟时十位

;CLR  P15

;CLR P14

MOV    B,#20

MOV    TMOD,#01H     ;定时器工作方式1

MOV TH0,#4CH

MOV TL0,#08H

SETB ET0                 ;允许T0中断

SETB EA                  ;总中断开放

LCALL    LCDRESET    ;初始化LCD

LCALL DISPSTART ;调用显示初始状态

SETB TR0   ;开启定时器

CLR NZBZ  ;闹钟开启关闭标志

CLR BSKGBZ  ;报时开启关闭标志

CLR XKQHBZ  ;显示开启关闭标志

LOOP: LCALL JIANPAN  ;按键子程序

LCALL DISPLAY  ;显示子程序

LCALL NZBF  ;NAOZHONG  BUFENG

LCALL NZBJ  ;NAOZHONG BIJIAO

LCALL BSKG  ;BAOSHIKAIGUAN

LCALL BSCS  ;BAOSHICISHU

LCALL SSBS  ;闪烁报时

SJMP LOOP

;==============================中断加一程序===================================

ZD: PUSH ACC

MOV TH0,#4CH

MOV TL0,#08H

DJNZ B,ZDEND

MOV    B,#20

INC SECONTL

SETB ZMBSBZ

MOV A,SECONTL

CJNE A,#0AH,ZDEND

MOV SECONTL,#00H

INC  SECONTH

MOV A,SECONTH

CJNE A,#06H,ZDEND

MOV SECONTH,#00H

INC MINIUTL

MOV A,MINIUTL

CJNE A,#0AH,ZDEND

MOV MINIUTL,#00H

INC  MINIUTH

MOV A,MINIUTH

CJNE A,#06H,ZDEND

MOV MINIUTH,#00H

INC  HOURL

SETB BSCSBZ

SETB ZDBSBZ

MOV A,HOURL   ;24小时的判断

CJNE A,#04H,ZDF

MOV A,HOURH

CJNE A,#02H,ZDEND

MOV HOURL,#00H

MOV HOURH,#00H

LCALL ZDRQ

SJMP ZDEND

ZDF: CJNE A,#0AH,ZDEND

MOV HOURL,#00H

INC  HOURH

ZDEND: POP ACC

RETI

;日期部分

ZDRQ: PUSH ACC

INC DAYL

;判断天数28,30,31部分

MOV A,MONTHH  ;用于判断月份时为31天30天28天

CJNE A,#01H,LL

MOV 55H,#0AH  ;存放月份的十位转化为个位是0AH

MOV A,MONTHL

ADD A,55H   ;月分高低相加用于查表

SJMP LL3

LL: MOV A,MONTHL

ADD A,MONTHH

LL3: MOV 56H,A   ;存放相加后的月份数据

MOV DPTR,#TAB5

MOVC A,@A+DPTR  ;查十位和天数的十位比较

MOV 57H,A

MOV A,56H

MOV DPTR,#TAB6  ;查个位和天数的个位比较

MOVC A,@A+DPTR

MOV 58H,A

MOV A,DAYH

CJNE A,57H,LL2

MOV A,DAYL

CJNE A,58H,LL2

MOV DAYH,#00H

MOV DAYL,#01H

SJMP LL4

LL2: MOV A,DAYL

CJNE A,#0AH,ZDRQEND

MOV DAYL,#00H

INC DAYH

MOV A,DAYH   ;比较天数是否要进位

CJNE A,57H,ZDRQEND

MOV A,DAYL

CJNE A,58H,ZDRQEND

MOV DAYH,#00H

MOV DAYL,#01H

;月份和年份

LL4: INC MONTHL

MOV A,MONTHL

CJNE A,#03H,ZDRQ1  ;用于判断月份时为12月时进位

MOV A,MONTHH

CJNE A,#01H,ZDRQ1

MOV MONTHL,#01H  ;天数符合要求

MOV MONTHH,#00H

SJMP ZDRQ2

ZDRQ1: CJNE A,#0AH,ZDRQEND

MOV MONTHL,#00H

INC MONTHH

SJMP ZDRQEND

ZDRQ2: INC YEARO   ;年的加一

MOV A,YEARO

CJNE A,#0AH,ZDRQEND

MOV YEARO,#00H

INC YEART   ;年的进位

MOV A,YEART

CJNE A,#0AH,ZDRQEND

MOV YEART,#00H

INC YEARS

MOV A,YEARS

CJNE A,#0AH,ZDRQEND

MOV YEARS,#00H

INC YEARF

MOV A,YEARF

CJNE A,#0AH,ZDRQEND

MOV YEARF,#00H

ZDRQEND:

POP ACC

RET

;液晶初始化

;========================初始化程序=======================================

LCDRESET:                       ;初始化程序

LCALL    DELAY5MS        ;延时15MS

LCALL    DELAY5MS

LCALL    DELAY5MS

MOV A,#38H          ;显示模式设置(不检测忙信号)

LCALL    LCDWCN          ;共三次

LCALL    DELAY5MS

MOV     A,#38H

LCALL    LCDWCN

LCALL    DELAY5MS

MOV     A,#38H

LCALL    LCDWCN

MOV     A,#38H          ;显示模式设置(以后均检测忙信号)

LCALL    LCDWC

MOV     A,#08H          ;显示关闭

LCALL    LCDWC

MOV     A,#01H          ;显示清屏

LCALL    LCDWC

MOV     A,#06H          ;显示光标移动设置

LCALL    LCDWC

MOV     A,#0CH          ;显示开及光标设置

LCALL    LCDWC

RET

;==============================写指令===================================

LCDWC:                          ;送控制字子程序(检测忙信号)

LCALL    WAITIDLE

;写指令;送控制字子程序(不检测忙信号)

LCDWCN: CLR     RSPIN           ;RS=0 RW=0 E=高脉冲

CLR     RWPIN

MOV     P0,A

SETB    EPIN  ;(

NOP   ;给高电平脉冲

CLR     EPIN  ;)

RET

;==========================写数据=======================================

LCDWD:                              ;写字符子程序

LCALL    WAITIDLE

SETB    RSPIN               ;RS=1 RW=0 E=高脉冲

CLR     RWPIN

MOV     P0,A

SETB    EPIN

NOP

CLR     EPIN

RET

;===============================等待控制器空闲==================================

WAITIDLE:

PUSH    ACC                 ;正常读写 *** 作之前必须检测LCD控制器状态

MOV     P0,#0FFH

lcall DELAY5MS  ;4566666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666

CLR     RSPIN               ;RS=0 RW=1 E=高电平

SETB    RWPIN

SETB    EPIN

lcall DELAY5MS  ;465555546465464654648791313848946113134849845461313579641613131354649498

WTD_PA: NOP                         ;DB7:    0  LCD控制器空闲

JB      P07,WTD_PA         ;        1  LCD控制器忙

CLR     EPIN

POP     ACC

RET

;初始状态子程序

DISPSTART:   ;显示初始状态子程序

PUSH ACC

MOV A,#80H

LCALL LCDWC

MOV     DPTR,#TAB ;显示字符

DISP1: CLR A

MOVC A,@A+DPTR

JZ DISP2

LCALL LCDWD

INC DPTR

SJMP DISP1

DISP2: MOV A,#0C0H

LCALL LCDWC

MOV DPTR,#TAB1

DISP3: CLR A

MOVC A,@A+DPTR

JZ DISP_END

LCALL LCDWD

INC DPTR

SJMP DISP3

DISP_END:

POP ACC

RET

;==========================显示子程序=======================================

DISPLAY:PUSH PSW

PUSH ACC

SETB RS0

CLR RS1

MOV A,#85H

LCALL LCDWC

MOV R1,#38H   ;第一行显示数据存储单元的启始地址

MOV TEMP,#30H  ;第一行显示数据存储单元的结束地址

MOV R6,#2

PLAY: DEC R1

CJNE R1,#32H,PLY  ;判断是否为冒号位

MOV A,MAOHAOL  ;是者送冒号的ACSI码

SJMP PLAY1

PLY: CJNE R1,#35H,PLY1

MOV A,MAOHAOH

SJMP PLAY1

PLY1: CJNE R1,#42H,PLY2  ;判断是否为横杠的位置

MOV A,HENL   ;是者送横杠的ACSI码

SJMP PLAY1

PLY2: CJNE R1,#45H,PLY3

MOV A,HENH

SJMP PLAY1

PLY3: MOV A,@R1   ;用查表法送要显示的数据

MOV DPTR,#TAB2

MOVC A,@A+DPTR

PLAY1: LCALL LCDWD

MOV A,R1

CJNE A,TEMP,PLAY  ;判断第一行是否显示好了

MOV A,#0C5H

LCALL LCDWC

MOV R1,#4AH   ;第二行显示数据存储单元的启始地址

MOV TEMP,#40H  ;第二行的结束地址

DJNZ R6,PLAY   ;R6为0时两行显示结束

POP ACC

POP PSW

RET

;按键子程序

JIANPAN:clr rs0      ;键盘子程序

setb rs1  ;键盘子程序

JB WEIXUAN,JIAN_ZEND ;设置键的判断

LCALL DELAY5MS

JB WEIXUAN,JIAN_ZEND

PUSH ACC

JNB WEIXUAN,$

;MOV A,#0FH  ;开启光标闪烁设置

;LCALL LCDWCN

fah: JNB NZBZ,JPNZSJ ;为“1”闹钟   为“0”时钟

LCALL JPXS

MOV R4,#86H  ;闹钟设定时间R4存放显示位地址

MOV R5,#2  ;闹钟设定时间第一行第二行•••••位置改变次数

MOV DIZHI,#8CH ;闹钟设定时间第一行结束地址

MOV R0,#06H

SJMP GIVED

JPNZSJ: CLR TR0

MOV R4,#86H  ;R4存放显示位地址

MOV R5,#2  ;第一行第二行•••••位置改变次数

MOV DIZHI,#8DH ;第一行结束地址

MOV R0,#36H

GIVED: MOV A,#0FH  ;开启光标闪烁设置555555555555555555555555555555555555555555555

LCALL LCDWCN

MOV A,R4

LCALL LCDWC

UPONE: JB FANHUI,UPtwo ;返回键的判断

LCALL DELAY5MS

JB FANHUI,UPtwo

JNB FANHUI,$

SJMP GOBACK

JIAN_ZEND:SJMP JIAN_END ;中继跳转6666666666666666666666666666666666666666666666666666666666666666

UPtwo: JB JIAJIAN,IAM ;加一键的判断

LCALL DELAY5MS

JB JIAJIAN,IAM

JNB JIAJIAN,$

LCALL JIAYI  ;调用按键加一子程序

;MOV A,#0FH  ;开启光标闪烁设置555555555555555555555555555555555555555555555

;LCALL LCDWCN

IAM: JB JIANJIAN,IAM22 ;减一键的判断

LCALL DELAY5MS

JB JIANJIAN,IAM22

JNB JIANJIAN,$

LCALL JIANYI ;调用按键减一子程序

AJMP GIVED

IAM22:  JB WEIXUAN,UPONE ;位选键的判断

LCALL   DELAY5MS

JB WEIXUAN,UPONE

JNB WEIXUAN,$

DEC R0

INC R4

LCALL JIAN  ;调用位选比较程序

CJNE r4,#88H,JJ11

DEC R0

INC R4

SJMP    JJ22

JJ11: CJNE r4,#8BH,JJ22

DEC R0

INC R4

JJ22: MOV A,R4

CJNE A,DIZHI,GIVED

JB NZBZ,fah  ;为“1”闹钟   为“0”时钟

MOV R4,#0C5H

MOV DIZHI,#0CFH

MOV R0,#49H

DJNZ R5,GIVED

LJMP fah

GOBACK: MOV A,#0CH  ;关闭光标闪烁设置

LCALL LCDWCN

POP ACC

JIAN_END:

SETB TR0

RET

;1111111111111111111111111111111111111111111111111111111111111111111111111111

;11111111111111111111111111111111111111111111111111111111111111111111111111

JPXS: MOV A,#85H

LCALL LCDWC

MOV R1,#08H   ;第一行显示数据存储单元的启始地址

JPXS_LL:DEC R1

CJNE R1,#05H,JPXS_LP

MOV A,#3AH

SJMP JPXS_LY

JPXS_LP:MOV A,@R1   ;用查表法送要显示的数据

MOV DPTR,#TAB2

MOVC A,@A+DPTR

JPXS_LY:LCALL LCDWD

CJNE R1,#03H,JPXS_LL

RET

;111111111111111111111111111111111111111111111111111111111111111111111

;111111111111111111111111111111111111111111111111111111111111111111111

;位选比较控制程序

; 在调整时间时这几位是符号冒号和横杠的数据

;在这几位时跳过到下一位

JIAN: CJNE R4,#87H,JIAN5

DEC R0

INC R4

SJMP JIANEND

JIAN5: CJNE R4,#8AH,JIAN1

DEC R0

INC R4

SJMP JIANEND

JIAN1: CJNE R4,#0C9H,JIAN2

DEC R0

INC R4

SJMP JIANEND

JIAN2: CJNE R4,#0CCH,JIANEND

DEC R0

INC R4

JIANEND:RET

;按键加一子程序

JIAYI: INC @R0

CJNE @R0,#0AH,JIAYI_END

MOV @R0,#0

CJNE R4,#86H,JIAYI55

SJMP JIAYI33

JIAYI55:CJNE r4,#89H,JIAYI11

SJMP JIAYI33

JIAYI11:CJNE r4,#8CH,JIAYI22

SJMP JIAYI33

JIAYI22:CJNE R0,#30H,JIAYI_END

JIAYI33:INC R0

INC @R0

CJNE @R0,#06H,JIAYI44

MOV @R0,#0

JIAYI44:DEC R0

JIAYI_END:MOV A,#0CH  ;开启光标闪烁设置

LCALL LCDWCN

JNB NZBZ,JIAYI88 ;为“1”闹钟   为“0”时钟

LCALL JPXS

SJMP JIAYI99

JIAYI88:LCALL DISPLAY  ;显示子程序

JIAYI99: RET

;%%%%%%%%%%%%%%%%%%减一%%%%%%%%%%%%%%%%%%%%%%%%

JIANYI: DEC @R0

CJNE @R0,#00H,JIANYI_END

MOV @R0,#9

CJNE R4,#86H,JIANYI55

SJMP JIANYI33

JIANYI55:CJNE r4,#89H,JIANYI11

SJMP JIANYI33

JIANYI11:CJNE r4,#8CH,JIANYI22

SJMP JIANYI33

JIANYI22:CJNE R0,#30H,JIANYI_END

JIANYI33:INC R0

DEC @R0

CJNE @R0,#0FFH,JIANYI44

MOV @R0,#5

JIANYI44:DEC R0

JIANYI_END:MOV A,#0CH  ;开启光标闪烁设置

LCALL LCDWCN

JNB NZBZ,JIANYI88 ;为“1”闹钟   为“0”时钟

LCALL JPXS

SJMP JIANYI99

JIANYI88: LCALL DISPLAY  ;显示子程序

JIANYI99: RET

;闹钟开关部分

NZBF: JB NZKG,NZBF_END

LCALL DELAY5MS

JB NZKG,NZBF_END

JNB NZKG,$

CPL NZBZ

JB NZBZ,NZBF_LL

MOV     A,#01H          ;显示清屏

LCALL   LCDWC

CLR P25

LCALL DISPSTART ;调用显示初始状态

LCALL DISPLAY  ;调用显示初始状态

JB BSKGBZ,NZBF_LP    ; |

SJMP NZBF_END    ; |

NZBF_LP:MOV     A,#8FH          ;报时标志显示位置 ;  |

LCALL   LCDWC     ;  |保护报时标志在清屏是不被误清

MOV A,#25H  ;显示报时标志  ;  |

LCALL LCDWD          ; |

SJMP NZBF_END    ; |

NZBF_LL:MOV     A,#8EH          ;闹钟标志显示位置

LCALL   LCDWC

MOV A,#26H  ;显示闹钟标志

LCALL LCDWD

NZBF_END:RET

;闹钟比较部分

NZBJ: JB NZBZ,NZBJ_LL

SJMP NZBJ_END

NZBJ_LL:MOV A,07H

CJNE A,37H,NZBJ_END

MOV A,06H

CJNE A,36H,NZBJ_END

MOV A,04H

CJNE A,34H,NZBJ_END

MOV A,03H

CJNE A,33H,NZBJ_END

SETB P25

NZBJ_END:RET

;报时开关

BSKG: JB FANHUI,BSKG_END

LCALL DELAY5MS

JB FANHUI,BSKG_END

JNB FANHUI,$

CPL BSKGBZ

JB BSKGBZ,BSKG_LL

MOV     A,#01H          ;显示清屏

LCALL   LCDWC

CLR P26

LCALL DISPSTART ;调用显示初始状态

LCALL DISPLAY  ;调用显示

JB NZBZ,BSKG_LP ; |

SJMP BSKG_END ; |

BSKG_LP:MOV     A,#8EH          ;  |

LCALL   LCDWC  ;  |保护闹钟标志在清屏是不被误清

MOV A,#26H  ;  |

LCALL LCDWD  ; |

SJMP BSKG_END ; |

BSKG_LL:MOV     A,#8FH          ;报时标志显示位置

LCALL   LCDWC

MOV A,#25H  ;显示报时标志

LCALL LCDWD

BSKG_END:RET

;报时次数

BSCS: JNB BSKGBZ,BSCS_END

JNB BSCSBZ,BSCS_END

MOV A,37H

CJNE A,#01H,BSCS_LL

MOV A,#0AH

SJMP BSCS_LP

BSCS_LL:CJNE A,#02H,BSCS_LP

MOV A,#14H

BSCS_LP:ADD A,36H

RL A

MOV BSCSCC,A

CLR BSCSBZ

BSCS_END: RET

;闪烁报时

SSBS: JNB BSKGBZ,SSBS_END

JNB ZDBSBZ,SSBS_END

JNB ZMBSBZ,SSBS_END

CPL P26

CPL     P27

CLR ZMBSBZ

DJNZ BSCSCC,SSBS_END

CLR ZDBSBZ

CLR P26

SSBS_END:RET

;延时子程序(5MS)

DELAY5MS:

PUSH PSW

SETB RS0

SETB RS1

MOV     R1,#25              ;延时子程序(5MS)

DL5_PA: MOV     R2,#100

DJNZ    R2,$

DJNZ    R1,DL5_PA

POP PSW

RET

TAB: DB "TIME:",00h

TAB1: DB "DATE:",00h

TAB2: DB "01234567891"

TAB3: DB 0AH,06H,00H,0AH,06H,00H,0AH,03H ;用于比较调整时间时的比较

TAB4: DB 0AH,04H,00H,0AH,02H,00H,0AH,0AH,0AH,0AH;用于调整日期时的比较

TAB5: DB 00H,03H,02H,03H,03H,03H,03H,03H,03H,03H,03H,03H,03H;用于天数十位比较

TAB6: DB 00H,02H,09H,02H,01H,02H,01H,02H,02H,01H,02H,01H,02H;用于天数个位比较

END

给个我以前写的程序,你参考参考,我这个使用1602液晶写的,显示方式需要改改

#include "1602yejingh"

sbit key1=P3^2; //选择调整位置按钮

sbit key2=P3^3; //加一按钮

sbit key3=P3^4; //减一按钮

sbit key4=P3^5; //定时按钮

char shi,fen,miao,T_shi,T_fen,T_miao;

uchar count,keynum,flag;

uchar code table1[]=" 2011-12-26 1";

uchar code table2[]=" 10:30:30";

uchar code table3[]="input the timing";

uchar code table4[]=" 00:00:00";

void write_sfm(uchar add,uchar date)

{

uchar shi,ge;

shi=date/10;

ge=date%10;

write_com(0xc0+add);

write_date(shi+'0');

write_date(ge+'0');

}

void init()

{

uchar num;

shi=10;

fen=30;

miao=30;

P1=0xfe;

write_com(0x38);//显示模式

write_com(0x0c);//不显示光标,光标不闪烁

write_com(0x06);//地址指针加一,光标加一

write_com(0x01);//清屏

write_com(0x80);

for(num=0;num<16;num++)

{

write_date(table1[num]);

delay(5);

}

write_com(0xc0);

for(num=0;num<12;num++)

{

write_date(table2[num]);

delay(5);

}

TMOD=0x01;

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

EA=1;

ET0=1;

TR0=1;

}

void keyscan()

{

uchar i;

if(key4==0)

{

delay(5);

if(key4==0)

{

while(!key4);

flag=1;

write_com(0x80);

for(i=0;i<16;i++)

{

write_date(table3[i]);

delay(5);

}

write_com(0xc0);

for(i=0;i<12;i++)

{

write_date(table4[i]);

delay(5);

}

}

}

if(key1==0)

{

delay(5);

if(key1==0)

{

while(!key1);

keynum++;

if(keynum==1)

{

if(flag==0) TR0=0;

write_com(0xc0+11);

write_com(0x0f);

}

if(keynum==2)

{

write_com(0xc0+8);

write_com(0x0f);

}

if(keynum==3)

{

write_com(0xc0+5);

write_com(0x0f);

}

if(keynum==4)

{

write_com(0x0c);

TR0=1;

if(flag==0)

{

keynum=0;

}

if(flag==1)

{

flag=0;

write_com(0x80);

for(i=0;i<16;i++)

{

write_date(table1[i]);

delay(5);

}

write_sfm(4,shi);

write_sfm(7,fen);

write_sfm(10,miao);

}

}

}

}

if(keynum!=0)

{

if(key2==0)

{

delay(5);

if(key2==0)

{

// while(!key2);

if(keynum==1)

{

if(flag==0)

{

miao++;

if(miao==60) miao=0;

write_sfm(10,miao);

write_com(0xc0+10);

delay(300);

}

if(flag==1)

{

T_miao++;

if(T_miao==60) T_miao=0;

write_sfm(10,T_miao);

write_com(0xc0+10);

delay(300);

}

}

if(keynum==2)

{

if(flag==0)

{

fen++;

if(fen==60) fen=0;

write_sfm(7,fen);

write_com(0xc0+7);

delay(300);

}

if(flag==1)

{

T_fen++;

if(T_fen==60) T_fen=0;

write_sfm(7,T_fen);

write_com(0xc0+7);

delay(300);

}

}

if(keynum==3)

{

if(flag==0)

{

shi++;

if(shi==24) shi=0;

write_sfm(4,shi);

write_com(0xc0+4);

delay(300);

}

if(flag==1)

{

T_shi++;

if(T_shi==24) T_shi=0;

write_sfm(4,T_shi);

write_com(0xc0+4);

delay(300);

}

}

}

}

if(key3==0)

{

delay(5);

if(key3==0)

{

// while(!key3);

if(keynum==1)

{

if(flag==0)

{

miao--;

if(miao==-1) miao=59;

write_sfm(10,miao);

write_com(0xc0+10);

delay(300);

}

if(flag==1)

{

T_miao--;

if(T_miao==-1) T_miao=59;

write_sfm(10,T_miao);

write_com(0xc0+10);

delay(300);

}

}

if(keynum==2)

{

if(flag==0)

{

fen--;

if(fen==-1) fen=59;

write_sfm(7,fen);

write_com(0xc0+7);

delay(300);

}

if(flag==1)

{

T_fen--;

if(T_fen==-1) T_fen=59;

write_sfm(7,T_fen);

write_com(0xc0+7);

delay(300);

}

}

if(keynum==3)

{

if(flag==0)

{

shi--;

if(shi==-1) shi=23;

write_sfm(4,shi);

write_com(0xc0+4);

delay(300);

}

if(flag==1)

{

T_shi--;

if(T_shi==-1) T_shi=23;

write_sfm(4,T_shi);

write_com(0xc0+4);

delay(300);

}

}

}

}

}

}

void main()

{

init();

while(1)

{

keyscan();

if(miao==T_miao&&fen==T_fen&&shi==T_shi)

{

P1=0xff;

}

}

}

void timer0() interrupt 1

{

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

count++;

if(count==16)

{

count=0;

P1=0xfe;

miao++;

if(miao==60)

{

miao=0;

fen++;

if(fen==60)

{

fen=0;

shi++;

if(shi==24)

{

shi=0;

}

if(flag==0) write_sfm(4,shi);

}

if(flag==0) write_sfm(7,fen);

}

if(flag==0) write_sfm(10,miao);

}

}

头文件

#ifndef _1602yejing_H_

#define _1602yejing_H_

#include<reg52h>

#define uchar unsigned char

#define uint unsigned int

sbit E=P2^7;

sbit RW=P2^6;

sbit RS=P2^5;

void delay(uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=148;y>0;y--);

}

void write_com(uchar com)//写命令函数

{

P0=com;

RS=0;

RW=0;

E=0;

delay(5);

E=1;

delay(5);

}

void write_date(uchar date)//写数据函数

{

P0=date;

RS=1;

RW=0;

E=0;

delay(5);

E=1;

delay(5);

}

#endif

#include<reg52h>

#include<defineh>

void delay(uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void didi()

{

beep=0;

delay(50);

beep=1;

delay(100);

beep=0;

delay(50);

beep=1;

}

void write_com(uchar com)

{

rs=0;

lcden=0;

P0=com;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void write_date(uchar date)

{

rs=1;

lcden=0;

P0=date;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void init()

{

uchar num;

EA=1;

EX0=1;

IT0=1;

dula=0;

wela=0;

lcden=0;

// set_time();

set_alarm(14,13,10);

write_ds(0x0B,0x26);

read_ds(0x0c);

// fen=59;

// miao=53;

// shi=23;

write_com(0x38);

write_com(0x0c);

write_com(0x06);

write_com(0x01);

write_com(0x80);

for(num=0;num<15;num++)

{

write_date(table[num]);

delay(5);

}

write_com(0x80+0x40);

for(num=0;num<12;num++)

{

write_date(table1[num]);

delay(5);

}

}

void write_sfm(uchar add,uchar date)

{

uchar shi,ge;

shi=date/10;

ge=date%10;

write_com(0x80+0x40+add);

write_date(0x30+shi);

write_date(0x30+ge);

}

void keyscan()

{

rd=0;

if(flag1==1)

{

if(s2==0)

{

delay(5);

if(s2==0)

{

while(!s2);

flag1=0;

}

}

if(s3==0)

{

delay(5);

if(s3==0)

{

while(!s3);

flag1=0;

}

}

}

if(s1==0)

{

delay(5);

if(s1==0)

{ s1num++;

flag=1;

flag1=0;

while(!s1);

if(s1num==1)

{

TR0=0;

write_com(0x80+0x40+10);

write_com(0x0f);

}

}

if(s1num==2)

{

write_com(0x80+0x40+7);

}

if(s1num==3)

{

write_com(0x80+0x40+4);

}

if(s1num==4)

{

s1num=0;

write_com(0x0c);

flag=0;

write_ds(0,miao);

write_ds(2,fen);

write_ds(4,shi);

}

}

if(s1num!=0)

{

if(s2==0)

{

delay(1);

if(s2==0)

{

while(!s2);

if(s1num==1)

{

miao++;

if(miao==60)

miao=0;

write_sfm(10,miao);

write_com(0x80+0x40+10);

}

if(s1num==2)

{

fen++;

if(fen==60)

fen=0;

write_sfm(7,fen);

write_com(0x80+0x40+7);

}

if(s1num==3)

{

shi++;

if(shi==24)

shi=0;

write_sfm(4,shi);

write_com(0x80+0x40+4);

}

}

}

if(s3==0)

{

delay(1);

if(s3==0)

{

while(!s3);

if(s1num==1)

{

/ if(miao==0)

{

miao=59;

write_sfm(10,miao);

write_com(0x80+0x40+10);

}/

miao--;

if(miao==-1)

miao=59;

write_sfm(10,miao);

write_com(0x80+0x40+10);

}

if(s1num==2)

{

fen--;

if(fen==-1)

fen=59;

write_sfm(7,fen);

write_com(0x80+0x40+7);

}

if(s1num==3)

{

shi--;

if(shi==-1)

shi=23;

write_sfm(4,shi);

write_com(0x80+0x40+4);

}

}

}

}

}

void write_ds(uchar add,uchar date)

{

dscs=0;

dsas=1;

dsds=1;

dsrw=1;

P0=add;

dsas=0;

dsrw=0;

P0=date;

dsrw=1;

dsas=1;

dscs=1;

}

uchar read_ds(uchar add)

{

uchar ds_date;

dsas=1;

dsds=1;

dsrw=1;

dscs=0;

P0=add;

dsas=0;

dsds=0;

P0=0xff;

ds_date=P0;

dsds=1;

dsas=1;

dscs=1;

return ds_date;

}

void set_time()

{

write_ds(4,10);

write_ds(2,32);

}

void set_alarm(uchar ashi,uchar afen,uchar amiao)

{

write_ds(1,amiao);

write_ds(3,afen);

write_ds(5,ashi);

}

void main()

{

init();

while(1)

{

keyscan();

if(flag1==1)

didi();

if(flag==0)

{

miao=read_ds(0);

fen=read_ds(2);

shi=read_ds(4);

write_sfm(10,miao);

write_sfm(7,fen);

write_sfm(4,shi);

}

}

}

void exter() interrupt 0

{ uchar c;

flag1=1;

c=read_ds(0x0c);

}

以上就是关于求一个简单的单片机时钟程序全部的内容,包括:求一个简单的单片机时钟程序、基于单片机多功能数字钟、C语言编程,数码管显示时钟跟设置闹钟的程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/9315676.html

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

发表评论

登录后才能评论

评论列表(0条)

保存