
系统名称: 数字钟
创健人:济南, 日期: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 STRATORG 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
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)