单片机时钟程序:通过键设计当前时间,设定闹钟,时间一到,报警

单片机时钟程序:通过键设计当前时间,设定闹钟,时间一到,报警,第1张

这是我以前写的一段程序,希望对你能有帮助

我的程序,首先有一点,肯定是调试通过的,不像我以前找的一些网络程序,貌似可以,就是不能执行结果。

/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);

}

}

}

以上就是关于单片机时钟程序:通过键设计当前时间,设定闹钟,时间一到,报警全部的内容,包括:单片机时钟程序:通过键设计当前时间,设定闹钟,时间一到,报警、单片机时钟程序、急求单片机电子时钟程序,用汇编写的等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存