dsa编程

2023-11-18 12:06:16 数码极客 bianji01

 

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秒时,计时器清零,同时标志位置位,即可~

希望对你有帮助。

声明:易趣百科所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流。若您的权利被侵害,请联系315127732@qq.com
广告位招租
横幅广告