这是我以前写的一段程序,希望对你能有帮助
我的程序,首先有一点,肯定是调试通过的,不像我以前找的一些网络程序,貌似可以,就是不能执行结果。
/DS1302时钟芯片显示设置
功能:显示 时间 日期 星期
引脚说明:DS1302三引脚 CLK = P1^5; IO=P1^6; RST=P1^7;
设计整理:创达科技 陈仲库
技术服务:kuzi00@163com QQ:86828048
整理时间:2007年5月26日
/
#define uchar unsigned char
#define uint unsigned int
sbit DS1302_CLK = P1^5; //实时时钟时钟线引脚
sbit DS1302_IO = P1^6; //实时时钟数据线引脚
sbit DS1302_RST = P1^7; //实时时钟复位线引脚
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
typedef struct __SYSTEMTIME__
{
uchar Second;
uchar Minute;
uchar Hour;
uchar Week;
uchar Day;
uchar Month;
uchar Year;
uchar DateString[9];
uchar TimeString[9];
}SYSTEMTIME; //定义的时间类型
void DS1302_WR_Byte(uchar d) //实时时钟写入一字节(内部函数)
{
uchar i;
ACC = d;
for(i=8; i>0; i--)
{
DS1302_IO = ACC0; //相当于汇编中的 RRC
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1;
}
}
uchar DS1302_RD_Byte(void) //实时时钟读取一字节(内部函数)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}
void DS1302_Write(uchar ucAddr, uchar ucDa) //ucAddr: DS1302地址, ucData: 要写的数据
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302_WR_Byte(ucAddr); // 地址,命令
DS1302_WR_Byte(ucDa); // 写1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
}
uchar DS1302_Read(uchar ucAddr) //读取DS1302某地址的数据
{
uchar ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302_WR_Byte(ucAddr|0x01); // 地址,命令
ucData = DS1302_RD_Byte(); // 读1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}
void DS1302_SetTime(uchar Address, uchar Value) // 设置时间函数
{
DS1302_Write(0x8E,0x00); //写保护
DS1302_Write(Address, ((Value/10)<<4 | (Value%10)));
}
void DS1302_GetTime(SYSTEMTIME Time)
{
uchar ReadValue;
ReadValue = DS1302_Read(0x80);
Time->Second = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);
ReadValue = DS1302_Read(0x82);
Time->Minute = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);
ReadValue = DS1302_Read(0x84);
Time->Hour = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);
ReadValue = DS1302_Read(0x86);
Time->Day = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);
ReadValue = DS1302_Read(0x8a);
Time->Week = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);
ReadValue = DS1302_Read(0x88);
Time->Month = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);
ReadValue = DS1302_Read(0x8c);
Time->Year = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);
}
void DateToStr(SYSTEMTIME Time)
{
Time->DateString[0] = Time->Year/10 + '0';
Time->DateString[1] = Time->Year%10 + '0';
Time->DateString[2] = '-';
Time->DateString[3] = Time->Month/10 + '0';
Time->DateString[4] = Time->Month%10 + '0';
Time->DateString[5] = '-';
Time->DateString[6] = Time->Day/10 + '0';
Time->DateString[7] = Time->Day%10 + '0';
Time->DateString[8] = '\0';
}
void TimeToStr(SYSTEMTIME Time)
{
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 + '0';
Time->TimeString[2] = ':';
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
Time->TimeString[5] = ':';
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second%10 + '0';
Time->DateString[8] = '\0';
}
void DS1302_Init(void)
{
uchar Second=DS1302_Read(0x80);
if(Second&0x80) DS1302_SetTime(0x80,0);
//时间设置初始化 秒 分 时
DS1302_SetTime(0x80,30);
DS1302_SetTime(0x82,59);
DS1302_SetTime(0x84,23);
DS1302_SetTime(0x8A,6); //周
DS1302_SetTime(0x86,26); //天
DS1302_SetTime(0x88,5); //月
DS1302_SetTime(0x8C,7); //年
}
/调用说明
DS1302_Init();初始化
DS1302_GetTime(&CurrentTime);//取得当前时间
DateToStr(&CurrentTime); //取得当前日期
TimeToStr(&CurrentTime); //取得当前时间
// 数据处理 CurrentTimeDateString 格式"07-05-26"
// CurrentTimeTimeString 格式"00;00;00"
/
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
A方案
--------------------------
外加一颗时钟芯片DS1302(非常准确)。
按键为单片机中断。
--------------------------
1、上电时自动显示时、分、秒;
实现方式:上电时单片机去启动DS1202,然后读取里面的时间值,自动显示时、分、秒;
2、设置一个控制按键,按下按键,则时钟以秒为单位开始计时;
实现方式:将DS1302此时的值暂时保存,最为计时开始的时间。
然后不停地读取DS1302里的新的时间值,
并将新的时间值 - 计时开始的时间 = 已计时数值
3、运行状态下可通过控制按键使时钟暂停,同时显示已计时数值;
实现方式:显示步骤2里的已计时数值。
4、停止状态下(已上电),按下复位按钮,时钟复位(清零),并进入下一次计时状态。
实现方式:计时开始的时间换成当前时间。
B方案
--------------------------
采用单片机内部定时器计时(不准)。
按键为单片机中断。
--------------------------
步骤类似,不用去读DS1302的时间,读自己内部的时间。
-------------------------------------------------------------------------------------------------------------------------------------------------------分割线。--------------------------------------------------------------------------
楼上的方案是当前比较常见的方案了。
没有给出程序
先给出A 方案程序如下。。。。//C语言编写。
头文件/
#include <reg52h>
#include <intrinsh>
#define uint unsigned int
#define uchar unsigned char
#define nop() _nop_()
sbit T_CLK = P1^4; /实时时钟时钟线引脚 /
sbit T_IO = P1^5; /实时时钟数据线引脚 /
sbit T_RST = P2^2; /实时时钟复位线引脚 /
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
sbit time_en_port = P3^7; /时间控制通道寄存器LE控制脚/
sbit sled_en_port = P3^6; /数码管控制通道寄存器LE控制脚/
#define sled_dm_port P0 /定义数码管段码的控制脚/
#define sled_wm_port P2 /定义数码管位码的控制脚/
/定义数码管显示字符跟数字的对应数组关系/
uchar code mun_to_char[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
/ 0 1 2 3 4 5 6 7 8 9 a b c d e f /
/定义需要点亮的数码管/
uchar code sled_bit_table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar data sled_data[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; /0-7号SLED缓冲值/
uchar data led_lighten_bit=0 ; /LED灯点亮标志位0-7/
uchar data time_data[8]={0x00,0x57,0x16,0x00,0x00,0x00,0x00,0x00};/格式为: 秒 分 时 日 月 星期 年 /
/-----------------------------------------------
显示部分程序,采用定时器0产生中断,1MS更新一次
------------------------------------------------/
void SLED_Disp() interrupt 1 using 3
{
TH0 = (65536-1000)/256;
TL0 = (65536-1000)/256;
time_en_port = 0; /关闭时钟控制通道/
sled_wm_port = sled_bit_table[led_lighten_bit]; /输出位码数据到数码管/
sled_dm_port = sled_data[led_lighten_bit]; /输出段码数据到数码管/
sled_en_port = 1; /打开数码管控制通道/
sled_en_port = 0; /关闭数码管控制通道/
sled_wm_port = 0xdf; / 释放P2端口,同时关闭发光二极管显示/
time_en_port = 1; /打开时钟控制通道/
led_lighten_bit++;
if(led_lighten_bit>=8) led_lighten_bit=0; /8位数码管全动态输出/
}
void T0_valueSet() /定义中断方式,中断时间/
{
TMOD = 0x01; /定时0,工作在方式1/
TH0 = (65536-1000)/256;
TL0 = (65536-1000)/256;
TR0 = 1; /启动计数/
EA = 1; /开总中断/
ET0 = 1; /开定时器0中断/
return;
}
/
函 数 名:RTInputByte()
功 能:实时时钟写入一字节
说 明:往DS1302写入1Byte数据 (内部函数)
入口参数:d 写入的数据
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
/
void RTInputByte(uchar d)
{
uchar i;
ACC = d;
for(i=8; i>0; i--)
{
T_IO = ACC0; /相当于汇编中的 RRC /
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/
函 数 名:RTOutputByte()
功 能:实时时钟读取一字节
说 明:从DS1302读取1Byte数据 (内部函数)
入口参数:无
返 回 值:ACC
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
/
uchar RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; /相当于汇编中的 RRC /
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
/
函 数 名:W1302()
功 能:往DS1302写入数据
说 明:先写地址,后写命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址, ucData: 要写的数据
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
/
void W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); / 地址,命令 /
RTInputByte(ucDa); / 写1Byte数据/
T_CLK = 1;
T_RST = 0;
}
/
函 数 名:R1302()
功 能:读取DS1302某地址的数据
说 明:先写地址,后读命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址
返 回 值:ucData :读取的数据
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
/
uchar R1302(uchar ucAddr)
{
uchar ucData;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); / 地址,命令 /
ucData = RTOutputByte(); / 读1Byte数据 /
T_CLK = 1;
T_RST = 0;
return(ucData);
}
/
函 数 名:BurstW1302T()
功 能:往DS1302写入时钟数据(多字节方式)
说 明:先写地址,后写命令/数据
调 用:RTInputByte()
入口参数:pWClock: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 控制
8Byte (BCD码)1B 1B 1B 1B 1B 1B 1B 1B
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
/
void BurstW1302T(uchar pWClock)
{
uchar i;
W1302(0x8e,0x00); / 控制命令,WP=0,写 *** 作/
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(0xbe); / 0xbe:时钟多字节写命令 /
for (i = 8; i>0; i--) /8Byte = 7Byte 时钟数据 + 1Byte 控制/
{
RTInputByte(pWClock); / 写1Byte数据/
pWClock++;
}
T_CLK = 1;
T_RST = 0;
}
/
函 数 名:BurstR1302T()
功 能:读取DS1302时钟数据
说 明:先写地址/命令,后读数据(时钟多字节方式)
调 用:RTInputByte() , RTOutputByte()
入口参数:pRClock: 读取时钟数据地址 格式为: 秒 分 时 日 月 星期 年
7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
/
void BurstR1302T(uchar pRClock)
{
uchar i;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(0xbf); / 0xbf:时钟多字节读命令 /
for (i=8; i>0; i--)
{
pRClock = RTOutputByte(); / 读1Byte数据 /
pRClock++;
}
T_CLK = 1;
T_RST = 0;
}
/
函 数 名:Set1302()
功 能:设置初始时间
说 明:先写地址,后读命令/数据(寄存器多字节方式)
调 用:W1302()
入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年
7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
/
void Set1302(uchar pClock)
{
uchar i;
uchar ucAddr = 0x80;
EA = 0;
W1302(0x8e,0x00); / 控制命令,WP=0,写 *** 作/
for(i =7; i>0; i--)
{
W1302(ucAddr,pClock); / 秒 分 时 日 月 星期 年 /
pClock++;
ucAddr +=2;
}
W1302(0x8e,0x80); / 控制命令,WP=1,写保护/
EA = 1;
}
/
函 数 名:Get1302()
功 能:读取DS1302当前时间
说 明:
调 用:R1302()
入口参数:ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
/
void Get1302(uchar ucCurtime[])
{
uchar i;
uchar ucAddr = 0x81;
EA = 0;
for (i=0; i<7; i++)
{
ucCurtime[i] = R1302(ucAddr);/格式为: 秒 分 时 日 月 星期 年 /
ucAddr += 2;
}
EA = 1;
}
void delay_1ms(uchar x)
/ 1MS为单位的延时程序 /
{
uchar j;
while(x--){
for(j=0;j<125;j++)
{;}
}
}
void main()
{
T0_valueSet();
Set1302(time_data);
while(1){
Get1302(time_data);
sled_data[0]=mun_to_char[time_data[2]/0x10];
sled_data[1]=mun_to_char[time_data[2]%0x10];
sled_data[3]=mun_to_char[time_data[1]/0x10];
sled_data[4]=mun_to_char[time_data[1]%0x10];
sled_data[6]=mun_to_char[time_data[0]/0x10];
sled_data[7]=mun_to_char[time_data[0]%0x10];
delay_1ms(200);
}
}
方案B
#include<reg52h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
sbit rs=P3^5;
sbit lcden=P3^4;
sbit s1=P3^0;
sbit s2=P3^1;
sbit s3=P3^2;
sbit rd=P3^7;
uchar count,s1num;
char miao,shi,fen;
uchar code table[]=" 2007-7-30 MON";
uchar code table1[]=" 00:00:00";
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
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;
dula=0;
wela=0;
lcden=0;
// 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);
}
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
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(s1==0)
{
delay(5);
if(s1==0)
{ s1num++;
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);
TR0=1;
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(5);
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(5);
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 main()
{
init();
while(1)
{
keyscan();
}
// while(1);
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==18)
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
write_sfm(4,shi);
}
write_sfm(7,fen);
}
write_sfm(10,miao);
}
}
以上的程序都是用C编写 如果是初学还是直接用C编写吧 虽然汇编也很好用 但是C已经是时代的趋势了。。
如果以上能帮到你 请给分哦。。 有什么不懂得也可以问我。
/ ch07-5-3c - 计时器实验3 -60秒计数器,每1分钟LED反相1次 /
//==声明区================================
#include // 定义8x51暂存器之标头档,P2-17~19
#define SEG P2 // 定义七节显示器接至Port 2
#define SCANP P1 // 定义扫瞄线接至Port 1
sbit LED=P0^7; // 声明LED接至P07
/声明T0计时相关声明/ // THx TLx 计算参考
#define count_M1 50000 // T0(MODE 1)之计量值,005s
#define TH_M1 (65636-count_M1)/256// T0(MODE 1)计量高8位元
#define TL_M1 (65636-count_M1)%256// T0(MODE 1)计量低8位元
int count_T0=0; // 计算 T0中断次数
/声明T1扫瞄相关声明/
#define count_M2 250 // T1(MODE 2)之计量值,025ms
#define TH_M2 (256-count_M2) // T1(MODE 2)自动载入计量
#define TL_M2 (256-count_M2) // T1(MODE 2)计数量
char count_T1=0; // 计算 T1中断次数
/ 声明七节显示器驱动信号阵列(共阳) /
char code TAB[10]={ 0xc0, 0xf9, 0xa4, 0xb0, 0x99, //数字0-4
0x92, 0x83, 0xf8, 0x80, 0x98 }; //数字5-9
char disp[2]={ 0xc0, 0xc0 }; // 声明显示区阵列初始显示00
/ 声明基本变量 /
char seconds=0; // 秒数
char scan=0; // 扫瞄信号
//==主程序================================
main() // 主程序开始
{ IE=0x8a; // 1000 1010,启用TF0、TF1中断(6-4页)
TMOD=0x21; // 0010 0001,T1采mode 2、T0采mode 1
TH0=TH_M1; TL0=TL_M1;// 设置T0计数量高8位元、低8位元
TR0=1; // 启动T0(7-7页)
TH1=TH_M2; TL1=TL_M2;// 设置T1自动载入值、计数量
TR1=1; // 启动T1
LED=1; // 关闭LED
while(1); // 无穷回圈,程序停滞
} // 主程序结束
//== T0中断子程序- 计算并显示秒数 ==================
void T0_1s(void) interrupt 1 // T0中断子程序开始
{ TH0=TH_M1; TL0=TL_M1; // 设置T0计数量高8位元、低8位元
if (++count_T0==20) // 若中断20次,即005x20=1秒
{ count_T0=0; // 重新计次
seconds++; // 秒数加1
if (seconds==60) // 若超过60秒
{ seconds=0; // 秒数归0,重新开始
LED=~LED; // 切换LED
} // if叙述结束(超过60秒)
} // if叙述结束(中断20次)
disp[1]=TAB[seconds/10]; // 填入十位数显示区
disp[0]=TAB[seconds%10]; // 填入个位数显示区
} // T0中断子程序结束
//===T1中断子程序 - 扫瞄 =========================
void T1_8ms(void) interrupt 3 // T1中断子程序开始
{ if (++count_T1==32) // 若中断32次,即025mx32=8ms
{ count_T1=0; // 重新计次
if (++scan==3) scan=1;// 若超过十位数,显示个位
SEG=0xff; // 关闭7段显示器
SCANP=~scan; // 输出扫瞄信号
SEG=disp[scan-1]; // 输出显示信号
} // 结束if判断(中断32次)
} // T0中断子程序结束
我来发一个C语言51单片机时钟程序,希望能帮到你
/ 程序功能:带定时闹铃时钟 /
/---------------------------------------------------------------/
#include <AT89X51H> /包含器件配置文件/
#define uchar unsigned char
#define uint unsigned int
char DATA_7SEG[10]={0xC0,0xF9,0xA4,0xB0,0x99,
0x92,0x82,0xF8,0x80,0x90,};/0~9的数码管段码/
uchar hour=0,min=0,sec=0; /时、分、秒单元清零/
uchar deda=0; /5mS计数单元清零/
bit d_05s=0; /05秒标志/
uchar set=0; /模式设定标志/
uchar m=0;
uchar flag=0; /RAM掉电标志/
void delay(uint k); /延时函数/
void conv(); /走时单元转换/
void disp(); /走时时间显示函数/
/------------------------走时函数部分 ----------------------/
/定时器T0 5mS初始化/
void init_timer()
{
TMOD=0x01;
TH0=-(4800/256);
TL0=-(4800%256);
IE=0x82;
TR0=1;
}
/---------------------------------/
/5mS定时中断服务函数/
void T0_srv(void) interrupt 1
{
TH0=-(4800/256);
TL0=-(4800%256);
deda++;
}
/----------------------------------/
/时、分、秒单元及走时单元转换/
void conv()
{
if(deda<=100)d_05s=0;
else d_05s=1;
if(deda>=200){sec++;deda=0;}
if(sec==60){min++;sec=0;}
if(min==60){hour++;min=0;}
if(hour==24){hour=0;}
}
/------------------------ 显示函数部分 ----------------------/
/走时时间显示函数/
void disp()
{
P0=DATA_7SEG[hour/10];P2=0xf7;delay(1);
P0=DATA_7SEG[hour%10];P2=0xfb;delay(1);
if(d_05s==1){if(P2_2==0)P0_7=0;else P0_7=1;}
delay(1);
P0=DATA_7SEG[min/10];P2=0xfd;delay(1);
P0=DATA_7SEG[min%10];P2=0xfe;delay(1);
}
/---------------------- 调整时间函数部分 -------------------/
/调整走时时间/
void set_time()
{uchar m;
if(P2_5==0)delay(1);
if(P2_5==0)hour++;
if(hour==24)hour=0;
for(m=0;m<30;m++)
{
disp();
if(P2_2==0)P0_7=0;
else P0_7=1;
delay(1);
}
if(P2_6==0)delay(1);
if(P2_6==0)min++;
if(min==60)min=0;
for(m=0;m<30;m++)
{
disp();
if(P2_2==0)P0_7=0;
else P0_7=1;
delay(1);
}
}
/------------------ 按键扫描、延时等函数部分-------------------/
/走时时间程序函数/
void time()
{
conv(); / 走时单元转换函数 /
disp(); / 走时时间显示函数 /
}
/------------------------------------/
/扫描按键函数/
void scan_key()
{
delay(1);
if(P2_4==0)set++;
if(set>=2)set=0;
if(set==1)flag=0x55;
F0:if(P2_4==0)goto F0; /按键未释放,在此等候/
}
/------------------------------/
/延时函数/
void delay(uint k)
{
uint i,j;
for(i=0;i<k;i++){
for(j=0;j<121;j++)
{;}}
}
/----------------------- 主函数 ------------------------- /
/主函数/
void main()
{
init_timer(); /定时器T0初始化/
while(1) /无限循环/
{
if(P2_4==0)scan_key(); /有按键,调用按键扫描函数/
switch(set) /根据set键值散转/
{
case 0:time(); break; /走时时间程序/
case 1:set_time();break; /走时时间调整/
default:break; /其它退出/
}
if(flag!=0x55) /判断掉电标志/
{
P0=0xc0; P2=0xc0; delay(100);
P2=0xff; delay(400);
}
}
}
以上就是关于单片机时钟程序:通过键设计当前时间,设定闹钟,时间一到,报警全部的内容,包括:单片机时钟程序:通过键设计当前时间,设定闹钟,时间一到,报警、单片机时钟程序、急求单片机电子时钟程序,用汇编写的等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)