高分求单片机时钟程序

高分求单片机时钟程序,第1张

系统名称: 数字钟

创健人:济南, 日期:2005.6.19

系统功能描述:

修改人: 修改日期:

修改原因:

蕊片型号:AT89C51 晶振:12MHZ

-------------硬件连接---------------------

-----------------------------------------------

程序名称: 声明区

功能描述: 声明各常量和变量

SECOND EQU 30H存储妙

MINITE EQU 31H存储分

HOUR EQU 32H 存储时

SPEAKER BIT P3.7

HOURK BIT P3.2时键

MINITEK BIT P3.3 分键

SECONDK BIT P3.0 妙键

FLAG BIT 00H

FLAG1S BIT 01H1S到标志位.

DISPBUF EQU 40H 段选标志

DISPBIT EQU 48H 位选通标志

T2SCNTA EQU 49H中断次数

T2SCNTB EQU 4AH 中断次数

TEMP EQU 4BH 初始化位

程序名称:主程序

功能描述

ORG 00H

LJMP START

ORG 0BH

LJMP INT_T0 T0中断入口

START: MOV SECOND,#00H 妙初始化0

MOV MINITE,#00H 分初始化0

MOV HOUR,#12 时始化送12

MOV DISPBIT,#00H 位选通标志

MOV T2SCNTA,#00H 标志

MOV T2SCNTB,#00H 标志

CLR FLAG

CLR FLAG1S

SETB SPEAKER

MOV TEMP,#07FH初始位,让第一个位选通

LCALL DISP调用显示处理程序

MOV TMOD,#01H 方式1

MOV TH0,#0F8H 赋值20MS

MOV TL0,#030H

SETB TR0 开中断启动

SETB ET0

SETB EA

程序名称:按键程序

功能描述调整分,时

WT: JNB FLAG,CC

LCALL SPEAKING

CC: JB SECONDK,NK1 妙末按下,转去判断分键

LCALL DELY10MS 按下,延时,消抖动

JB SECONDK,NK1 再次判断是否按下?

INC SECOND 按下,按下一次加1

MOV A,SECOND送A判断

CJNE A,#60,NS60 妙末到60转分

MOV SECOND,#00H 到了,回0

NS60: LCALL DISP

JNB SECONDK,$ 等待妙键释放

NK1:JB MINITEK,NK2 跟妙键分析相似

LCALL DELY10MS

JB MINITEK,NK2

INC MINITE

MOV A,MINITE

CJNE A,#60,NM60

MOV MINITE,#00H

NM60: LCALL DISP

JNB MINITEK,$

NK2:JB HOURK,NK3 时键

LCALL DELY10MS

JB HOURK,NK3

INC HOUR

MOV A,HOUR

CJNE A,#24,NH24

MOV HOUR,#00H

NH24: LCALL DISP

JNB HOURK,$ 等待时键释放

NK3:LJMP WT 返回

程序名称:显示处理程序

功能描述,该程序实现时,分,秒计时转换为BCD码并存储在以47H起始地址的显示

输出数据存储单元里,即显示缓冲区47H至40H单元

DISP:

MOV A,#DISPBUF 送40H

ADD A,#7 加8

DEC A

MOV R1,A 送47H

MOV A,HOUR 送时

MOV B,#10

DIV AB

MOV @R1,A 存储时十位

DEC R1 指向时个位

MOV A,B送时个位

MOV @R1,A 存储时个位

DEC R1

MOV A,#10

MOV @R1,A

DEC R1

MOV A,MINITE 送分,处理与时处理类似

MOV B,#10

DIV AB

MOV @R1,A

DEC R1

MOV A,B

MOV @R1,A

DEC R1

MOV A,#10

MOV @R1,A

DEC R1

MOV A,SECOND送秒

MOV B,#10

DIV AB

MOV @R1,A

DEC R1

MOV A,B

MOV @R1,A

DEC R1

RET

程序名称:显示程序

功能描述在LED上显示为12-12-12显示模式.

INT_T0:

MOV TH0,#0F8H 重赋值

MOV TL0,#030H

MOV A,#DISPBUF 段偏移存储

ADD A,DISPBIT 位偏移量

MOV R0,A段偏移存储

MOV A,@R0 段偏移量

MOV DPTR,#TABLE 指向字形表

MOVC A,@A+DPTR 取字形

MOV P0,#0 防闪烁

MOV P0,A字形选P1口显示

MOV A,DISPBIT 位移偏量

MOV DPTR,#TAB 指向位选

MOVC A,@A+DPTR 取位选通

MOV P2,A位送P3口选通

INC DISPBIT 位偏移加1

MOV A,DISPBIT 位偏移送A

CJNE A,#08H,KNA 八个数管码扫描完不?

MOV DISPBIT,#00H描完重新开始

程序名称:1秒计时程序

功能描述

KNA: INC T2SCNTA

MOV A,T2SCNTA

CJNE A,#100,DONE

MOV T2SCNTA,#00H

INC T2SCNTB

MOV A,T2SCNTB

CJNE A,#05H,DONE

SETB FLAG1S

MOV T2SCNTB,#00H

INC SECOND 秒加1

MOV A,SECOND

CJNE A,#50,BB 50S到.

MOV A,MINITE

CJNE A,#59,BB 59分

SETB FLAG 打开正点响标志.

BB: MOV A,SECOND

CJNE A,#60,NEXT 秒超过60了没有? 没有,调用显示处理程序

MOV SECOND,#00H

INC MINITE 分加1

MOV A,MINITE

CJNE A,#60,NEXT

MOV MINITE,#00H 分超过60,清0

INC HOUR 并时加1

MOV A,HOUR

CJNE A,#24,NEXT 是否超过24小时?不是,则跳至NEXT

MOV HOUR,#00H

NEXT: LCALL DISP 调用显示处理程序

DONE: RETI 中断返回

TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H 0到9字形(40表示横扛)

TAB: DB 07FH,0BFH,0DFH,0EFH,0F7H,0FBH,0FDH,0FEH

程序名称:正点报时子程序

功能描述前十秒报第一声,每隔一秒报一声.

SPEAKING:MOV R5,#6

AA: CLR SPEAKER

JNB FLAG1S,$延时1S.

CLR FLAG1S

SETB SPEAKER

JNB FLAG1S,$

CLR FLAG1S

DJNZ R5,AA

CLR FLAG

RET

程序名称:延时子程序

功能描述按键消抖调用.

DELY10MS:MOV R6,#10

D1: MOV R7,#248

DJNZ R7,$

DJNZ R6,D1

RET

程序功能:单片机读出时钟芯片DS1302的数据,四位数码管显示当前时间

电路连接:P0口低四位分别连接74LS47的ABCD,高四位通过非门分别控制四个数码管的公共端,

低电平有效,数码管的小数点与P2.7相连。

*************************************************************************************/

#include<reg52.h>

#include"intrins.h" //_nop_()延时函数使用声明

#define uint unsigned int

#define uchar unsigned char

#define LED_data P0//P0口作为数码管显示的数据口

sbit RST_1302=P1^4//时钟复位信号线

sbit IO_1302=P1^3//时钟数据线

sbit SCLK_1302=P1^2 //时钟时钟线

sbit decimal=P2^7 //小数点

uchar LED_4[4]={0,0,0,0}//四位数码管显示的数据储存

/******************************************************************

//时钟1302各寄存器读/写标志

#define second_write 0x80 //秒寄存器 写

#define second_read 0x81 //秒寄存器 读

#define minute_write 0x82 //分 写

#define minute_read 0x83 //分 读

#define hour_write 0x84 //时 写

#define hour_read0x85 //时 读

#define day_write0x86 //日 写

#define day_read 0x87 //日 读

#define month_write 0x88 //月 写

#define month_read 0x89 //月 读

#define week_write 0x8A //周 写

#define week_read0x8B //周 读

#define year_write 0x8C //年 写

#define year_read0x8D //年 读

#define wri_protect_write0x8E //写保护寄存器 写

#define wri_protect_read 0x8F //写保护寄存器 读

#define clock_consecution_write 0xBE//时间寄存器连续写

#define clock_consecution_read 0xBF//时间寄存器连续读

****************************************************************************/

//秒 分 时 日 月 周 年 控制字

uchar start_time[]={0x00,0x00,0x21,0x01,0x01,0x02,0x08}//初始时间

// 2008-1-1 星期二 AM12:00:00

/********5ms延时函数*********/

void delay_5ms(uint i)

{ uint j

for(i>0i--)

for(j=450j>0j--)

}

/*******显示函数,i为显示次数,P0口为显示数据口**********/

void desplay(uchar i)

{ LED_4[0]=start_time[0]&0x0f

LED_4[1]=start_time[0]>>4

LED_4[2]=start_time[1]&0x0f

LED_4[3]=start_time[1]>>4

while(i--)

{ LED_data=0xe0|LED_4[0]delay_5ms(3)//右边第一位显示

decimal=0 //灭小数点

LED_data=0xd0|LED_4[1]delay_5ms(3)//第二位显示

decimal=1 //亮小数点

LED_data=0xb0|LED_4[2]delay_5ms(3)//第三位显示LED_data=0x70|LED_4[3]delay_5ms(3)//第四位显示}

}

/********1302写入一个字节************/

void write_1302byte(uchar dat)

{uchar i

RST_1302=1//_nop_() 启动数据传送

for(i=0i<8i++)

{

IO_1302=dat&0x01//_nop_()

SCLK_1302=0_nop_() //SCLK时钟的上升沿时数据被写入

SCLK_1302=1

dat=dat>>1

}

}

/*******1302读出一个字节数据**********/

uchar read_1302byte(void)

{ uchar i,dat=0

RST_1302=1//_nop_()//启动数据传送

for(i=0i<8i++)

{ IO_1302=1 //释放数据线

dat=dat>>1

SCLK_1302=1_nop_()//SCLK脉冲的下降沿读出数据

SCLK_1302=0

if(IO_1302)dat|=0x80

}

return(dat)

}

/********1302写入一个字节数据(dat)到指定寄存器中(adresss)************/

void write_1302(uchar address,uchar dat)

{RST_1302=0SCLK_1302=0_nop_()

RST_1302=1

write_1302byte(address)

write_1302byte(dat)

RST_1302=0

IO_1302=1

}

/*******1302在对应的寄存器中(dress)读出一个字节数据**********/

uchar read_1302(uchar address)

{uchar da=0

RST_1302=0SCLK_1302=0_nop_()

RST_1302=1

write_1302byte(address)

da=read_1302byte()

RST_1302=0

return(da)

}

/*************时钟DS1302初始化*********/

void start_1302(void)

{SCLK_1302=0

RST_1302=0_nop_()_nop_()

RST_1302=1_nop_()

write_1302(0x80,0x00)//秒寄存器,最高位写"0",时钟工作

write_1302(0x8e,0x00)//写保护寄存器,最高位写"0",时钟能够写入

write_1302(0x90,0xa5)//涓流充电寄存器,使用涓流充电、一个二极管、一个2k的电阻

write_1302(0x84,0x00)//24小时制

}/******设定时间初值***********/

void set_1302(void)

{uchar i,address=0x80

write_1302(0x8e,0x00)//将控制寄存器值设为"0",最高位WP=0允许写

for(i=0i<7i++)

{ start_time[i]=start_time[i]/10*16+start_time[i]%10

write_1302(address,start_time[i])

address+=2

}

write_1302(0x8e,0x80)//将控制寄存器值设为"1",最高位WP=1不允许写,防止干扰影响时间值}

/*******读取当前时间值***********/

void get_1302(void)

{uchar i,address=0x81

for(i=0i<7i++)

{ start_time[i]=read_1302(address)//读对应时钟寄存器的值

address+=2

}

}

void main(void)

{

start_1302() //1302时钟复位

write_1302(0x80,0x00)//秒寄存器,最高位写"0",时钟工作

write_1302(0x8e,0x00)//写保护寄存器,最高位写"0",时钟能够写入

set_1302()//设置时间初值while(1)

{ get_1302()

desplay(6)

}

}

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 21H.0

SETB 21H.1

SETB 21H.2

SETB 21H.3

SETB 21H.4

SETB 21H.5

CLR 21H.6

CLR 21H.7

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 P1.3

ACALL DEL

SETB P1.3

MOV P0,21H 点亮秒十位数码管

CLR P1.2

ACALL DEL

SETB P1.2

MOV P0,22H 点亮分个位数码管

CLR P1.1

ACALL DEL

SETB P1.1

MOV P0,23H 点亮分十位数码管

CLR P1.0

ACALL DEL

SETB P1.0

MOV P0,24H 点亮时个位数码管

CLR P2.7

ACALL DEL

SETB P2.7

MOV P0,25H 点亮时十位数码管

CLR P2.6

ACALL DEL

SETB P2.6

DJNZ 30H,A1

DJNZ 31H,B1

************************************

INC R0

CJNE R0,#10,A2

INC R1

CJNE R1,#6,A3

INC R2

****************************

SETB P1.4 1分钟后关定时

CJNE R2,#0,A11分个位定时

CJNE R3,#0,A11分十位定时

CJNE R6,#19,A11时位定时

CLR P1.4 开定时

****************************

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


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

原文地址:https://54852.com/yw/12127573.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存