急求~~单片机AT89c51的时钟C程序

急求~~单片机AT89c51的时钟C程序,第1张

使用芯片:AT89S52,DS12887时钟芯片,实践通过,运行稳定。自己根据程序连接引脚。

#include<reg52.h>

#include<absacc.h>

#define uchar unsigned char

#define uint unsigned int

#define LCDCOM XBYTE[0xcffc] //LCD写命令寄存器地址

#define LCDDATA XBYTE[0xcffd] //LCD写数据寄存器地址

#define LCDSTATUS XBYTE[0xcffe] //LCD读状态寄存器地址

#define DSA XBYTE[0x8f0a] //实时时钟寄存器A

#define DSB XBYTE[0x8f0b] //实时时钟寄存器B

#define DSC XBYTE[0x8f0c] //实时时钟寄存器C

#define DSD XBYTE[0x8f0d] //实时时钟寄存器D

#define SECOND XBYTE[0x8f05] //实时时钟分报警

sbit bflag=ACC^7

uchar idata dt[7]={06,7,11,17,05,0,2}//时间初值

uchar at[7]={9,8,7,4,2,0,6}//年,月,日,时,分,秒,星期时标寄存器地址

uchar xdata *addr=0x8f00//实时时钟片选地址

//函数的声明部分

//void delay1(uint x)

void lcd_busy()

void lcd_cmd(uchar lcd_cmd)

void lcd_data(uchar lcd_data)

void lcd_moveto(uchar position)

void init(void)

//void delay( unsigned int number )

void init_ds(void)//实时时钟初始化

void WDS(void)//写时标函数

void RDS(void)//读时标函数

uchar ymd[10]={2,0,0,0,0,0,0,0,0,0}//年月日

uchar hms[8]={0,0,0,0,0,0,0,0}//时分秒

uchar weekday[3]

uchar code dis_buf[12]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2e,0x3a}

/*void delay1(uint x) //延时1ms程序

{

uchar j

while(x--)

{

for(j=0j<125j++)

{}

}

}

void delay( unsigned int number )

{

unsigned char i

unsigned int u

while(u<number)

{

for(i=0i<=125i++)

u++

}

} */

void init_ds(void) //实时时钟初始化

{

DSA=0x2f//选时钟32.768kHz中断周期500ms

ACC=DSC//清中断请求标志

ACC=DSD//VRT=1;数据有效

DSB=0x7e//中断允许,时标值为二进制码,24小时制,芯片工作,方波输出允许

}

void WDS(void) //写时标函数

{

uchar i

DSB=0x8e//置SET位为1

DSB=0x8e

for(i=0i<7i++)

{

*(addr+at[i])=dt[i]//置时标初值

}

}

void RDS(void)

{

uchar i

do

{

ACC=DSA

}

while(bflag==1)

for(i=0i<7i++)

{

dt[i]=*(addr+at[i])

}

}

void lcd_busy() //检测lcd忙程序

{

do

{

ACC=LCDSTATUS

}

while(bflag==1)//当他忙的时候就不停的检测,直到空闲为止

}

void lcd_cmd(uchar lcd_cmd) //写命令函数

{

LCDCOM=lcd_cmd

lcd_busy()

}

void lcd_data(uchar lcd_data) //写数据函数

{

LCDDATA=lcd_data

lcd_busy()

}

void lcd_moveto(uchar position) //确定显示位置

{

uchar temp//为显示位置对应的地址

if (position<16)

temp=(position+0x80-1)//为在第一行

else

temp=((position-16)+0xc0)//为第二行

lcd_cmd(temp)

}

void init(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()

}

void shizhong(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])

{

case 1:weekday[0]='m'weekday[1]='o'weekday[2]='n'break

case 2:weekday[0]='t'weekday[1]='u'weekday[2]='e'break

case 3:weekday[0]='w'weekday[1]='e'weekday[0]='n'break

case 4:weekday[0]='t'weekday[1]='h'weekday[2]='u'break

case 5:weekday[0]='f'weekday[1]='r'weekday[2]='i'break

case 6:weekday[0]='s'weekday[1]='a'weekday[0]='t'break

case 7:weekday[0]='s'weekday[1]='u'weekday[0]='n'break

}

}

void main(void)

{

uchar i

WDS()

init_ds()

init()

while(1)

{

RDS()

shizhong()

lcd_moveto(3)

for(i=0i<10i++)

{

lcd_data(dis_buf[ymd[i]])

}

lcd_moveto(17)

for(i=0i<8i++)

{

lcd_data(dis_buf[hms[i]])

}

lcd_data(0x20)

for(i=0i<3i++)

{

lcd_data(weekday[i])

}

}

}

再给一个:用内部的定时器做数字钟,通过数码管显示出来。

#include <regx52.h>

#define uchar unsigned char

#define uint unsigned int

uchar dispcode[]={ 0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71,0x00} //定义0到F的段选码

uchar dispbitcode[]={0xfe,0xfd,0xfb,0xf7,

0xef,0xdf,0xbf,0x7f} //8位数码管的位选码

uchar dispbuf[8]={ 0,0,16,0,0,16,0,0} //定义一个缓冲区

uchar dispbitcnt

uchar second

uchar minite

uchar hour

uint tcnt

uchar mstcnt

uchar i,j

void main(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=5i>0i--)

for(j=248j>0j--) //延时检查是否是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=5i>0i--)

for(j=248j>0j--)

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=5i>0i--)

for(j=248j>0j--)

if(P0_2==0)

{

hour++

if(hour==24)

{

hour=0

}

dispbuf[6] =hour%10

dispbuf[7] =hour/10

while (P0_2==0)

} } }}

void t0 (void) interrupt 1 using 0//定时器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

}

}

void choise(int *a,int n)

{

int i,j,k,temp

for(i=0i<n-1i++)

{

k=i/*给记号赋值*/

for(j=i+1j<nj++)

if(a[k]>a[j]) k=j/*是k总是指向最小元素*/

if(i!=k)

{

/*当k!=i是才交换,否则a[i]即为最小*/

temp=a[i]

a[i]=a[k]

a[k]=temp

}

}

}

LIBRARY IEEE

USE IEEE.STD_LOGIC_1164.ALL

ENDITY MUX6_1 IS

PORT(SEL:IN STD_LOGIC_VECTOR(2 DOWNTO 0)

D:IN STD_LOGIC_VECOTOR(5 DOWNTO 0)

OUTPUT:OUT STD_LOGIC)

END

ARCHITECTURE ART OF MUX6_1 IS

BEGIN

OUTPUT<=D(1) WHEN SEL="001" ELSE

D(2) WHEN SEL="010" ELSE

D(3) WHEN SEL="011" ELSE

D(4) WHEN SEL="100" ELSE

D(5) WHEN SEL="101" ELSE

D(0)

END


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

原文地址: https://outofmemory.cn/yw/12115824.html

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

发表评论

登录后才能评论

评论列表(0条)

保存