89c51单面机c语言时钟控制器编程
方案1:AT89S52,DS12887时钟芯片,实践通过,运行稳定。自己根据程序连接引脚。
LCD显示的。
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineLCDCOMXBYTE[0xcffc]//LCD写命令寄存器地址
#defineLCDDATAXBYTE[0xcffd]//LCD写数据寄存器地址
#defineLCDSTATUSXBYTE[0xcffe]//LCD读状态寄存器地址
#defineDSAXBYTE[0x8f0a]//实时时钟寄存器A
#defineDSBXBYTE[0x8f0b]//实时时钟寄存器B
#defineDSCXBYTE[0x8f0c]//实时时钟寄存器C
#defineDSDXBYTE[0x8f0d]//实时时钟寄存器D
#defineSECONDXBYTE[0x8f05]//实时时钟分报警
sbitbflag=ACC^7;
ucharidatadt[7]={06,7,11,17,05,0,2};//时间初值
ucharat[7]={9,8,7,4,2,0,6};//年,月,日,时,分,秒,星期时标寄存器地址
ucharxdata*addr=0x8f00;//实时时钟片选地址
//函数的声明部分
//voiddelay1(uintx);
voidlcd_busy();
voidlcd_cmd(ucharlcd_cmd);
voidlcd_data(ucharlcd_data);
voidlcd_moveto(ucharposition);
voidinit(void);
//voiddelay(unsignedintnumber);
voidinit_ds(void);//实时时钟初始化
voidWDS(void);//写时标函数
voidRDS(void);//读时标函数
ucharymd[10]={2,0,0,0,0,0,0,0,0,0};//年月日
ucharhms[8]={0,0,0,0,0,0,0,0};//时分秒
ucharweekday[3];
ucharcodedis_buf[12]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2e,0x3a};
voidinit_ds(void)//实时时钟初始化
DSA=0x2f;//选时钟32.768kHz;中断周期500ms
ACC=DSC;//清中断请求标志
ACC=DSD;//VRT=1;数据有效
DSB=0x7e;//中断允许,时标值为二进制码,24小时制,芯片工作,方波输出允许
voidWDS(void)//写时标函数
uchari;
DSB=0x8e;//置SET位为1
DSB=0x8e;
for(i=0;i<7;i++)
*(addr+at[i])=dt[i];//置时标初值
voidRDS(void)
uchari;
ACC=DSA;
while(bflag==1);
for(i=0;i<7;i++)
dt[i]=*(addr+at[i]);
voidlcd_busy()//检测lcd忙程序
ACC=LCDSTATUS;
while(bflag==1);//当他忙的时候就不停的检测,直到空闲为止
voidlcd_cmd(ucharlcd_cmd)//写命令函数
LCDCOM=lcd_cmd;
lcd_busy();
voidlcd_data(ucharlcd_data)//写数据函数
LCDDATA=lcd_data;
lcd_busy();
voidlcd_moveto(ucharposition)//确定显示位置
uchartemp;//为显示位置对应的地址
if(position<16)
temp=(position+0x80-1);//为在第一行
temp=((position-16)+0xc0);//为第二行
lcd_cmd(temp);
voidinit(void)//lcd初始化
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x38);//置功能:2行,5*7字符
lcd_busy();
lcd_cmd(0x06);//置输入模式:地址增量,显示屏不移动
lcd_busy();
lcd_cmd(0x0c);//置显示开,不显示光标,光标不闪烁
lcd_busy();
lcd_cmd(0x01);//清显示
lcd_busy();
voidshizhong(void)//时钟的每一位取出来
ymd[2]=dt[0]/10;
ymd[3]=dt[0]%10;
ymd[4]=10;
ymd[5]=dt[1]/10;
ymd[6]=dt[1]%10;
ymd[7]=10;
ymd[8]=dt[2]/10;
ymd[9]=dt[2]%10;
hms[0]=dt[3]/10;
hms[1]=dt[3]%10;
hms[2]=11;
hms[3]=dt[4]/10;
hms[4]=dt[4]%10;
hms[5]=11;
hms[6]=dt[5]/10;
hms[7]=dt[5]%10;
使用芯片:AT89S52,DS12887时钟芯片,实践通过,运行稳定。自己根据程序连接引脚。
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineLCDCOMXBYTE[0xcffc]//LCD写命令寄存器地址
#defineLCDDATAXBYTE[0xcffd]//LCD写数据寄存器地址
#defineLCDSTATUSXBYTE[0xcffe]//LCD读状态寄存器地址
#defineDSAXBYTE[0x8f0a]//实时时钟寄存器A
#defineDSBXBYTE[0x8f0b]//实时时钟寄存器B
#defineDSCXBYTE[0x8f0c]//实时时钟寄存器C
#defineDSDXBYTE[0x8f0d]//实时时钟寄存器D
#defineSECONDXBYTE[0x8f05]//实时时钟分报警
sbitbflag=ACC^7;
ucharidatadt[7]={06,7,11,17,05,0,2};//时间初值
ucharat[7]={9,8,7,4,2,0,6};//年,月,日,时,分,秒,星期时标寄存器地址
ucharxdata*addr=0x8f00;//实时时钟片选地址
//函数的声明部分
//voiddelay1(uintx);
voidlcd_busy();
voidlcd_cmd(ucharlcd_cmd);
voidlcd_data(ucharlcd_data);
voidlcd_moveto(ucharposition);
voidinit(void);
//voiddelay(unsignedintnumber);
voidinit_ds(void);//实时时钟初始化
voidWDS(void);//写时标函数
voidRDS(void);//读时标函数
ucharymd[10]={2,0,0,0,0,0,0,0,0,0};//年月日
ucharhms[8]={0,0,0,0,0,0,0,0};//时分秒
ucharweekday[3];
ucharcodedis_buf[12]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2e,0x3a};
/*voiddelay1(uintx)//延时1ms程序
ucharj;
while(x--)
for(j=0;j<125;j++)
voiddelay(unsignedintnumber)
unsignedchari;
unsignedintu;
while(u
for(i=0;i<=125;i++);
voidinit_ds(void)//实时时钟初始化
DSA=0x2f;//选时钟32.768kHz;中断周期500ms
ACC=DSC;//清中断请求标志
ACC=DSD;//VRT=1;数据有效
DSB=0x7e;//中断允许,时标值为二进制码,24小时制,芯片工作,方波输出允许
voidWDS(void)//写时标函数
uchari;
DSB=0x8e;//置SET位为1
DSB=0x8e;
for(i=0;i<7;i++)
*(addr+at[i])=dt[i];//置时标初值
voidRDS(void)
uchari;
ACC=DSA;
while(bflag==1);
for(i=0;i<7;i++)
dt[i]=*(addr+at[i]);
voidlcd_busy()//检测lcd忙程序
ACC=LCDSTATUS;
while(bflag==1);//当他忙的时候就不停的检测,直到空闲为止
voidlcd_cmd(ucharlcd_cmd)//写命令函数
LCDCOM=lcd_cmd;
lcd_busy();
voidlcd_data(ucharlcd_data)//写数据函数
LCDDATA=lcd_data;
lcd_busy();
voidlcd_moveto(ucharposition)//确定显示位置
uchartemp;//为显示位置对应的地址
if(position<16)
temp=(position+0x80-1);//为在第一行
temp=((position-16)+0xc0);//为第二行
lcd_cmd(temp);
voidinit(void)//lcd初始化
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x38);//置功能:2行,5*7字符
lcd_busy();
lcd_cmd(0x06);//置输入模式:地址增量,显示屏不移动
lcd_busy();
lcd_cmd(0x0c);//置显示开,不显示光标,光标不闪烁
lcd_busy();
lcd_cmd(0x01);//清显示
lcd_busy();
voidshizhong(void)//时钟的每一位取出来
ymd[2]=dt[0]/10;
ymd[3]=dt[0]%10;
ymd[4]=10;
ymd[5]=dt[1]/10;
ymd[6]=dt[1]%10;
ymd[7]=10;
ymd[8]=dt[2]/10;
ymd[9]=dt[2]%10;
hms[0]=dt[3]/10;
hms[1]=dt[3]%10;
hms[2]=11;
hms[3]=dt[4]/10;
hms[4]=dt[4]%10;
hms[5]=11;
hms[6]=dt[5]/10;
hms[7]=dt[5]%10;
switch(dt[6])
case1:weekday[0]=m;weekday[1]=o;weekday[2]=n;break;
case2:weekday[0]=t;weekday[1]=u;weekday[2]=e;break;
case3:weekday[0]=w;weekday[1]=e;weekday[0]=n;break;
case4:weekday[0]=t;weekday[1]=h;weekday[2]=u;break;
case5:weekday[0]=f;weekday[1]=r;weekday[2]=i;break;
case6:weekday[0]=s;weekday[1]=a;weekday[0]=t;break;
case7:weekday[0]=s;weekday[1]=u;weekday[0]=n;break;
voidmain(void)
uchari;
WDS();
init_ds();
init();
while(1)
RDS();
shizhong();
lcd_moveto(3);
for(i=0;i<10;i++)
lcd_data(dis_buf[ymd[i]]);
lcd_moveto(17);
for(i=0;i<8;i++)
lcd_data(dis_buf[hms[i]]);
lcd_data(0x20);
for(i=0;i<3;i++)
lcd_data(weekday[i]);
方案2:用内部的定时器做数字钟,通过数码管显示出来
使用芯片:AT89S52,DS12887时钟芯片,实践通过,运行稳定。自己根据程序连接引脚。
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineLCDCOMXBYTE[0xcffc]//LCD写命令寄存器地址
#defineLCDDATAXBYTE[0xcffd]//LCD写数据寄存器地址
#defineLCDSTATUSXBYTE[0xcffe]//LCD读状态寄存器地址
#defineDSAXBYTE[0x8f0a]//实时时钟寄存器A
#defineDSBXBYTE[0x8f0b]//实时时钟寄存器B
#defineDSCXBYTE[0x8f0c]//实时时钟寄存器C
#defineDSDXBYTE[0x8f0d]//实时时钟寄存器D
#defineSECONDXBYTE[0x8f05]//实时时钟分报警
sbitbflag=ACC^7;
ucharidatadt[7]={06,7,11,17,05,0,2};//时间初值
ucharat[7]={9,8,7,4,2,0,6};//年,月,日,时,分,秒,星期时标寄存器地址
ucharxdata*addr=0x8f00;//实时时钟片选地址
//函数的声明部分
//voiddelay1(uintx);
voidlcd_busy();
voidlcd_cmd(ucharlcd_cmd);
voidlcd_data(ucharlcd_data);
voidlcd_moveto(ucharposition);
voidinit(void);
//voiddelay(unsignedintnumber);
voidinit_ds(void);//实时时钟初始化
voidWDS(void);//写时标函数
voidRDS(void);//读时标函数
ucharymd[10]={2,0,0,0,0,0,0,0,0,0};//年月日
ucharhms[8]={0,0,0,0,0,0,0,0};//时分秒
ucharweekday[3];
ucharcodedis_buf[12]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2e,0x3a};
/*voiddelay1(uintx)//延时1ms程序
ucharj;
while(x--)
for(j=0;j<125;j++)
voiddelay(unsignedintnumber)
unsignedchari;
unsignedintu;
while(u
for(i=0;i<=125;i++);
voidinit_ds(void)//实时时钟初始化
DSA=0x2f;//选时钟32.768kHz;中断周期500ms
ACC=DSC;//清中断请求标志
ACC=DSD;//VRT=1;数据有效
DSB=0x7e;//中断允许,时标值为二进制码,24小时制,芯片工作,方波输出允许
voidWDS(void)//写时标函数
uchari;
DSB=0x8e;//置SET位为1
DSB=0x8e;
for(i=0;i<7;i++)
*(addr+at[i])=dt[i];//置时标初值
voidRDS(void)
uchari;
ACC=DSA;
while(bflag==1);
for(i=0;i<7;i++)
dt[i]=*(addr+at[i]);
voidlcd_busy()//检测lcd忙程序
ACC=LCDSTATUS;
while(bflag==1);//当他忙的时候就不停的检测,直到空闲为止
voidlcd_cmd(ucharlcd_cmd)//写命令函数
LCDCOM=lcd_cmd;
lcd_busy();
voidlcd_data(ucharlcd_data)//写数据函数
LCDDATA=lcd_data;
lcd_busy();
voidlcd_moveto(ucharposition)//确定显示位置
uchartemp;//为显示位置对应的地址
if(position<16)
temp=(position+0x80-1);//为在第一行
temp=((position-16)+0xc0);//为第二行
lcd_cmd(temp);
voidinit(void)//lcd初始化
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x38);//置功能:2行,5*7字符
lcd_busy();
lcd_cmd(0x06);//置输入模式:地址增量,显示屏不移动
lcd_busy();
lcd_cmd(0x0c);//置显示开,不显示光标,光标不闪烁
lcd_busy();
lcd_cmd(0x01);//清显示
lcd_busy();
voidshizhong(void)//时钟的每一位取出来
ymd[2]=dt[0]/10;
ymd[3]=dt[0]%10;
ymd[4]=10;
ymd[5]=dt[1]/10;
ymd[6]=dt[1]%10;
ymd[7]=10;
ymd[8]=dt[2]/10;
ymd[9]=dt[2]%10;
hms[0]=dt[3]/10;
hms[1]=dt[3]%10;
hms[2]=11;
hms[3]=dt[4]/10;
hms[4]=dt[4]%10;
hms[5]=11;
hms[6]=dt[5]/10;
hms[7]=dt[5]%10;
switch(dt[6])
case1:weekday[0]=m;weekday[1]=o;weekday[2]=n;break;
case2:weekday[0]=t;weekday[1]=u;weekday[2]=e;break;
case3:weekday[0]=w;weekday[1]=e;weekday[0]=n;break;
case4:weekday[0]=t;weekday[1]=h;weekday[2]=u;break;
case5:weekday[0]=f;weekday[1]=r;weekday[2]=i;break;
case6:weekday[0]=s;weekday[1]=a;weekday[0]=t;break;
case7:weekday[0]=s;weekday[1]=u;weekday[0]=n;break;
voidmain(void)
uchari;
WDS();
init_ds();
init();
while(1)
RDS();
shizhong();
lcd_moveto(3);
for(i=0;i<10;i++)
lcd_data(dis_buf[ymd[i]]);
lcd_moveto(17);
for(i=0;i<8;i++)
lcd_data(dis_buf[hms[i]]);
lcd_data(0x20);
for(i=0;i<3;i++)
lcd_data(weekday[i]);
再给一个:用内部的定时器做数字钟,通过数码管显示出来。
#include
#defineucharunsignedchar
#defineuintunsignedint
uchardispcode[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00};//定义0到F的段选码
uchardispbitcode[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};//8位数码管的位选码
uchardispbuf[8]={0,0,16,0,0,16,0,0};//定义一个缓冲区
uchardispbitcnt;
ucharsecond;
ucharMinite;
ucharhour;
uinttcnt;
ucharmstcnt;
uchari,j;
voidmain(void)
TMOD=0x02;//定时器0工作方式2
TH0=0x06;//每250us中断一次
TL0=0x06;
TR0=1;//启动定时器0
ET0=1;//定时器0中断允许
EA=1;//CPU开中断
while(1)
if(P0_0==0)
{for(i=5;i>0;i--)
for(j=248;j>0;j--);//延时检查是否是P0_0被按下
if(P0_0==0)//如果被按下
second++;//秒就加1
if(second==60)
second=0;
dispbuf[0]=second%10;//存放秒的个位
dispbuf[1]=second/10;//存放秒的十位
while(P0_0==0);//等待P0_0变高
if(P0_1==0)
{for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_1==0)
minite++;
if(minite==60)
minite=0;
dispbuf[3]=minite%10;
dispbuf[4]=minite/10;
while(P0_1==0);
if(P0_2==0)
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_2==0)
hour++;
if(hour==24)
hour=0;
dispbuf[6]=hour%10;
dispbuf[7]=hour/10;
while(P0_2==0);
voidt0(void)interrupt1using0//定时器0中断服务程序
P1=dispcode[dispbuf[dispbitcnt]];//为位选码
P3=dispbitcode[dispbitcnt];//为段选码
dispbitcnt++;
if(dispbitcnt==8)
dispbitcnt=0;
tcnt++;
if(tcnt==4000)//此时有一秒钟了(4000*250us)
tcnt=0;
second++;
if(second==60)
second=0;
minite++;
if(minite==60)
minite=0;
hour++;
if(hour==24)
hour=0;
dispbuf[0]=second%10;
dispbuf[1]=second/10;
dispbuf[3]=minite%10;
dispbuf[4]=minite/10;
dispbuf[6]=hour%10;
dispbuf[7]=hour/10;
注:至于你说的蜂鸣器,这个很简单,在程序里设置一个标志位
sbitbusy_louder在硬件连接上采用一个放大器与单片机的一个引脚相接即时到60秒时,计时器清零,同时标志位置位,即可~
希望对你有帮助。
89c51单面机c语言时钟控制器编程
方案1:AT89S52,DS12887时钟芯片,实践通过,运行稳定。自己根据程序连接引脚。
LCD显示的。
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineLCDCOMXBYTE[0xcffc]//LCD写命令寄存器地址
#defineLCDDATAXBYTE[0xcffd]//LCD写数据寄存器地址
#defineLCDSTATUSXBYTE[0xcffe]//LCD读状态寄存器地址
#defineDSAXBYTE[0x8f0a]//实时时钟寄存器A
#defineDSBXBYTE[0x8f0b]//实时时钟寄存器B
#defineDSCXBYTE[0x8f0c]//实时时钟寄存器C
#defineDSDXBYTE[0x8f0d]//实时时钟寄存器D
#defineSECONDXBYTE[0x8f05]//实时时钟分报警
sbitbflag=ACC^7;
ucharidatadt[7]={06,7,11,17,05,0,2};//时间初值
ucharat[7]={9,8,7,4,2,0,6};//年,月,日,时,分,秒,星期时标寄存器地址
ucharxdata*addr=0x8f00;//实时时钟片选地址
//函数的声明部分
//voiddelay1(uintx);
voidlcd_busy();
voidlcd_cmd(ucharlcd_cmd);
voidlcd_data(ucharlcd_data);
voidlcd_moveto(ucharposition);
voidinit(void);
//voiddelay(unsignedintnumber);
voidinit_ds(void);//实时时钟初始化
voidWDS(void);//写时标函数
voidRDS(void);//读时标函数
ucharymd[10]={2,0,0,0,0,0,0,0,0,0};//年月日
ucharhms[8]={0,0,0,0,0,0,0,0};//时分秒
ucharweekday[3];
ucharcodedis_buf[12]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2e,0x3a};
voidinit_ds(void)//实时时钟初始化
DSA=0x2f;//选时钟32.768kHz;中断周期500ms
ACC=DSC;//清中断请求标志
ACC=DSD;//VRT=1;数据有效
DSB=0x7e;//中断允许,时标值为二进制码,24小时制,芯片工作,方波输出允许
voidWDS(void)//写时标函数
uchari;
DSB=0x8e;//置SET位为1
DSB=0x8e;
for(i=0;i<7;i++)
*(addr+at[i])=dt[i];//置时标初值
voidRDS(void)
uchari;
ACC=DSA;
while(bflag==1);
for(i=0;i<7;i++)
dt[i]=*(addr+at[i]);
voidlcd_busy()//检测lcd忙程序
ACC=LCDSTATUS;
while(bflag==1);//当他忙的时候就不停的检测,直到空闲为止
voidlcd_cmd(ucharlcd_cmd)//写命令函数
LCDCOM=lcd_cmd;
lcd_busy();
voidlcd_data(ucharlcd_data)//写数据函数
LCDDATA=lcd_data;
lcd_busy();
voidlcd_moveto(ucharposition)//确定显示位置
uchartemp;//为显示位置对应的地址
if(position<16)
temp=(position+0x80-1);//为在第一行
temp=((position-16)+0xc0);//为第二行
lcd_cmd(temp);
voidinit(void)//lcd初始化
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x38);//置功能:2行,5*7字符
lcd_busy();
lcd_cmd(0x06);//置输入模式:地址增量,显示屏不移动
lcd_busy();
lcd_cmd(0x0c);//置显示开,不显示光标,光标不闪烁
lcd_busy();
lcd_cmd(0x01);//清显示
lcd_busy();
voidshizhong(void)//时钟的每一位取出来
ymd[2]=dt[0]/10;
ymd[3]=dt[0]%10;
ymd[4]=10;
ymd[5]=dt[1]/10;
ymd[6]=dt[1]%10;
ymd[7]=10;
ymd[8]=dt[2]/10;
ymd[9]=dt[2]%10;
hms[0]=dt[3]/10;
hms[1]=dt[3]%10;
hms[2]=11;
hms[3]=dt[4]/10;
hms[4]=dt[4]%10;
hms[5]=11;
hms[6]=dt[5]/10;
hms[7]=dt[5]%10;
使用芯片:AT89S52,DS12887时钟芯片,实践通过,运行稳定。自己根据程序连接引脚。
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineLCDCOMXBYTE[0xcffc]//LCD写命令寄存器地址
#defineLCDDATAXBYTE[0xcffd]//LCD写数据寄存器地址
#defineLCDSTATUSXBYTE[0xcffe]//LCD读状态寄存器地址
#defineDSAXBYTE[0x8f0a]//实时时钟寄存器A
#defineDSBXBYTE[0x8f0b]//实时时钟寄存器B
#defineDSCXBYTE[0x8f0c]//实时时钟寄存器C
#defineDSDXBYTE[0x8f0d]//实时时钟寄存器D
#defineSECONDXBYTE[0x8f05]//实时时钟分报警
sbitbflag=ACC^7;
ucharidatadt[7]={06,7,11,17,05,0,2};//时间初值
ucharat[7]={9,8,7,4,2,0,6};//年,月,日,时,分,秒,星期时标寄存器地址
ucharxdata*addr=0x8f00;//实时时钟片选地址
//函数的声明部分
//voiddelay1(uintx);
voidlcd_busy();
voidlcd_cmd(ucharlcd_cmd);
voidlcd_data(ucharlcd_data);
voidlcd_moveto(ucharposition);
voidinit(void);
//voiddelay(unsignedintnumber);
voidinit_ds(void);//实时时钟初始化
voidWDS(void);//写时标函数
voidRDS(void);//读时标函数
ucharymd[10]={2,0,0,0,0,0,0,0,0,0};//年月日
ucharhms[8]={0,0,0,0,0,0,0,0};//时分秒
ucharweekday[3];
ucharcodedis_buf[12]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2e,0x3a};
/*voiddelay1(uintx)//延时1ms程序
ucharj;
while(x--)
for(j=0;j<125;j++)
voiddelay(unsignedintnumber)
unsignedchari;
unsignedintu;
while(u
for(i=0;i<=125;i++);
voidinit_ds(void)//实时时钟初始化
DSA=0x2f;//选时钟32.768kHz;中断周期500ms
ACC=DSC;//清中断请求标志
ACC=DSD;//VRT=1;数据有效
DSB=0x7e;//中断允许,时标值为二进制码,24小时制,芯片工作,方波输出允许
voidWDS(void)//写时标函数
uchari;
DSB=0x8e;//置SET位为1
DSB=0x8e;
for(i=0;i<7;i++)
*(addr+at[i])=dt[i];//置时标初值
voidRDS(void)
uchari;
ACC=DSA;
while(bflag==1);
for(i=0;i<7;i++)
dt[i]=*(addr+at[i]);
voidlcd_busy()//检测lcd忙程序
ACC=LCDSTATUS;
while(bflag==1);//当他忙的时候就不停的检测,直到空闲为止
voidlcd_cmd(ucharlcd_cmd)//写命令函数
LCDCOM=lcd_cmd;
lcd_busy();
voidlcd_data(ucharlcd_data)//写数据函数
LCDDATA=lcd_data;
lcd_busy();
voidlcd_moveto(ucharposition)//确定显示位置
uchartemp;//为显示位置对应的地址
if(position<16)
temp=(position+0x80-1);//为在第一行
temp=((position-16)+0xc0);//为第二行
lcd_cmd(temp);
voidinit(void)//lcd初始化
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x38);//置功能:2行,5*7字符
lcd_busy();
lcd_cmd(0x06);//置输入模式:地址增量,显示屏不移动
lcd_busy();
lcd_cmd(0x0c);//置显示开,不显示光标,光标不闪烁
lcd_busy();
lcd_cmd(0x01);//清显示
lcd_busy();
voidshizhong(void)//时钟的每一位取出来
ymd[2]=dt[0]/10;
ymd[3]=dt[0]%10;
ymd[4]=10;
ymd[5]=dt[1]/10;
ymd[6]=dt[1]%10;
ymd[7]=10;
ymd[8]=dt[2]/10;
ymd[9]=dt[2]%10;
hms[0]=dt[3]/10;
hms[1]=dt[3]%10;
hms[2]=11;
hms[3]=dt[4]/10;
hms[4]=dt[4]%10;
hms[5]=11;
hms[6]=dt[5]/10;
hms[7]=dt[5]%10;
switch(dt[6])
case1:weekday[0]=m;weekday[1]=o;weekday[2]=n;break;
case2:weekday[0]=t;weekday[1]=u;weekday[2]=e;break;
case3:weekday[0]=w;weekday[1]=e;weekday[0]=n;break;
case4:weekday[0]=t;weekday[1]=h;weekday[2]=u;break;
case5:weekday[0]=f;weekday[1]=r;weekday[2]=i;break;
case6:weekday[0]=s;weekday[1]=a;weekday[0]=t;break;
case7:weekday[0]=s;weekday[1]=u;weekday[0]=n;break;
voidmain(void)
uchari;
WDS();
init_ds();
init();
while(1)
RDS();
shizhong();
lcd_moveto(3);
for(i=0;i<10;i++)
lcd_data(dis_buf[ymd[i]]);
lcd_moveto(17);
for(i=0;i<8;i++)
lcd_data(dis_buf[hms[i]]);
lcd_data(0x20);
for(i=0;i<3;i++)
lcd_data(weekday[i]);
方案2:用内部的定时器做数字钟,通过数码管显示出来
使用芯片:AT89S52,DS12887时钟芯片,实践通过,运行稳定。自己根据程序连接引脚。
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineLCDCOMXBYTE[0xcffc]//LCD写命令寄存器地址
#defineLCDDATAXBYTE[0xcffd]//LCD写数据寄存器地址
#defineLCDSTATUSXBYTE[0xcffe]//LCD读状态寄存器地址
#defineDSAXBYTE[0x8f0a]//实时时钟寄存器A
#defineDSBXBYTE[0x8f0b]//实时时钟寄存器B
#defineDSCXBYTE[0x8f0c]//实时时钟寄存器C
#defineDSDXBYTE[0x8f0d]//实时时钟寄存器D
#defineSECONDXBYTE[0x8f05]//实时时钟分报警
sbitbflag=ACC^7;
ucharidatadt[7]={06,7,11,17,05,0,2};//时间初值
ucharat[7]={9,8,7,4,2,0,6};//年,月,日,时,分,秒,星期时标寄存器地址
ucharxdata*addr=0x8f00;//实时时钟片选地址
//函数的声明部分
//voiddelay1(uintx);
voidlcd_busy();
voidlcd_cmd(ucharlcd_cmd);
voidlcd_data(ucharlcd_data);
voidlcd_moveto(ucharposition);
voidinit(void);
//voiddelay(unsignedintnumber);
voidinit_ds(void);//实时时钟初始化
voidWDS(void);//写时标函数
voidRDS(void);//读时标函数
ucharymd[10]={2,0,0,0,0,0,0,0,0,0};//年月日
ucharhms[8]={0,0,0,0,0,0,0,0};//时分秒
ucharweekday[3];
ucharcodedis_buf[12]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2e,0x3a};
/*voiddelay1(uintx)//延时1ms程序
ucharj;
while(x--)
for(j=0;j<125;j++)
voiddelay(unsignedintnumber)
unsignedchari;
unsignedintu;
while(u
for(i=0;i<=125;i++);
voidinit_ds(void)//实时时钟初始化
DSA=0x2f;//选时钟32.768kHz;中断周期500ms
ACC=DSC;//清中断请求标志
ACC=DSD;//VRT=1;数据有效
DSB=0x7e;//中断允许,时标值为二进制码,24小时制,芯片工作,方波输出允许
voidWDS(void)//写时标函数
uchari;
DSB=0x8e;//置SET位为1
DSB=0x8e;
for(i=0;i<7;i++)
*(addr+at[i])=dt[i];//置时标初值
voidRDS(void)
uchari;
ACC=DSA;
while(bflag==1);
for(i=0;i<7;i++)
dt[i]=*(addr+at[i]);
voidlcd_busy()//检测lcd忙程序
ACC=LCDSTATUS;
while(bflag==1);//当他忙的时候就不停的检测,直到空闲为止
voidlcd_cmd(ucharlcd_cmd)//写命令函数
LCDCOM=lcd_cmd;
lcd_busy();
voidlcd_data(ucharlcd_data)//写数据函数
LCDDATA=lcd_data;
lcd_busy();
voidlcd_moveto(ucharposition)//确定显示位置
uchartemp;//为显示位置对应的地址
if(position<16)
temp=(position+0x80-1);//为在第一行
temp=((position-16)+0xc0);//为第二行
lcd_cmd(temp);
voidinit(void)//lcd初始化
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30);//置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x38);//置功能:2行,5*7字符
lcd_busy();
lcd_cmd(0x06);//置输入模式:地址增量,显示屏不移动
lcd_busy();
lcd_cmd(0x0c);//置显示开,不显示光标,光标不闪烁
lcd_busy();
lcd_cmd(0x01);//清显示
lcd_busy();
voidshizhong(void)//时钟的每一位取出来
ymd[2]=dt[0]/10;
ymd[3]=dt[0]%10;
ymd[4]=10;
ymd[5]=dt[1]/10;
ymd[6]=dt[1]%10;
ymd[7]=10;
ymd[8]=dt[2]/10;
ymd[9]=dt[2]%10;
hms[0]=dt[3]/10;
hms[1]=dt[3]%10;
hms[2]=11;
hms[3]=dt[4]/10;
hms[4]=dt[4]%10;
hms[5]=11;
hms[6]=dt[5]/10;
hms[7]=dt[5]%10;
switch(dt[6])
case1:weekday[0]=m;weekday[1]=o;weekday[2]=n;break;
case2:weekday[0]=t;weekday[1]=u;weekday[2]=e;break;
case3:weekday[0]=w;weekday[1]=e;weekday[0]=n;break;
case4:weekday[0]=t;weekday[1]=h;weekday[2]=u;break;
case5:weekday[0]=f;weekday[1]=r;weekday[2]=i;break;
case6:weekday[0]=s;weekday[1]=a;weekday[0]=t;break;
case7:weekday[0]=s;weekday[1]=u;weekday[0]=n;break;
voidmain(void)
uchari;
WDS();
init_ds();
init();
while(1)
RDS();
shizhong();
lcd_moveto(3);
for(i=0;i<10;i++)
lcd_data(dis_buf[ymd[i]]);
lcd_moveto(17);
for(i=0;i<8;i++)
lcd_data(dis_buf[hms[i]]);
lcd_data(0x20);
for(i=0;i<3;i++)
lcd_data(weekday[i]);
再给一个:用内部的定时器做数字钟,通过数码管显示出来。
#include
#defineucharunsignedchar
#defineuintunsignedint
uchardispcode[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00};//定义0到F的段选码
uchardispbitcode[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};//8位数码管的位选码
uchardispbuf[8]={0,0,16,0,0,16,0,0};//定义一个缓冲区
uchardispbitcnt;
ucharsecond;
ucharminite;
ucharhour;
uinttcnt;
ucharmstcnt;
uchari,j;
voidmain(void)
TMOD=0x02;//定时器0工作方式2
TH0=0x06;//每250us中断一次
TL0=0x06;
TR0=1;//启动定时器0
ET0=1;//定时器0中断允许
EA=1;//CPU开中断
while(1)
if(P0_0==0)
{for(i=5;i>0;i--)
for(j=248;j>0;j--);//延时检查是否是P0_0被按下
if(P0_0==0)//如果被按下
second++;//秒就加1
if(second==60)
second=0;
dispbuf[0]=second%10;//存放秒的个位
dispbuf[1]=second/10;//存放秒的十位
while(P0_0==0);//等待P0_0变高
if(P0_1==0)
{for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_1==0)
minite++;
if(minite==60)
minite=0;
dispbuf[3]=minite%10;
dispbuf[4]=minite/10;
while(P0_1==0);
if(P0_2==0)
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_2==0)
hour++;
if(hour==24)
hour=0;
dispbuf[6]=hour%10;
dispbuf[7]=hour/10;
while(P0_2==0);
voidt0(void)interrupt1using0//定时器0中断服务程序
P1=dispcode[dispbuf[dispbitcnt]];//为位选码
P3=dispbitcode[dispbitcnt];//为段选码
dispbitcnt++;
if(dispbitcnt==8)
dispbitcnt=0;
tcnt++;
if(tcnt==4000)//此时有一秒钟了(4000*250us)
tcnt=0;
second++;
if(second==60)
second=0;
minite++;
if(minite==60)
minite=0;
hour++;
if(hour==24)
hour=0;
dispbuf[0]=second%10;
dispbuf[1]=second/10;
dispbuf[3]=minite%10;
dispbuf[4]=minite/10;
dispbuf[6]=hour%10;
dispbuf[7]=hour/10;
注:至于你说的蜂鸣器,这个很简单,在程序里设置一个标志位
sbitbusy_louder在硬件连接上采用一个放大器与单片机的一个引脚相接即时到60秒时,计时器清零,同时标志位置位,即可~
希望对你有帮助。