给你个参考:
#include<reg52.h>sbitclock_clk=P2^7
sbitclock_dat=P2^6
sbitclock_rst=P2^5sbitwei1=P2^0
sbitwei2=P2^1
sbitwei3=P2^2
sbitwei4=P2^3
sbitwei5=P2^4
sbitwei6=P3^3sbita0=ACC^0//为了编程方便定义的位变量
sbita1=ACC^1
sbita2=ACC^2
sbita3=ACC^3
sbita4=ACC^4
sbita5=ACC^5
sbita6=ACC^6
sbita7=ACC^7unsignedcharTab_Num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}//0-9数字voiddelay(intnum)//延时函数
{
while(num--)
}
voidclock_write(unsignedchardd)//写入一个字节,DS1302时序
{
ACC=dd
clock_clk=0clock_dat=a0clock_clk=1
clock_clk=0clock_dat=a1clock_clk=1
clock_clk=0clock_dat=a2clock_clk=1
clock_clk=0clock_dat=a3clock_clk=1
clock_clk=0clock_dat=a4clock_clk=1
clock_clk=0clock_dat=a5clock_clk=1
clock_clk=0clock_dat=a6clock_clk=1
clock_clk=0clock_dat=a7clock_clk=1
}unsignedcharclock_read(void)//读出一个字节,时序
{clock_clk=1clock_clk=0a0=clock_dat<br/><br/>clock_clk=1clock_clk=0a1=clock_dat<br/><br/>clock_clk=1clock_clk=0a2=clock_dat<br/><br/>clock_clk=1clock_clk=0a3=clock_dat<br/><br/>clock_clk=1clock_clk=0a4=clock_dat<br/><br/>clock_clk=1clock_clk=0a5=clock_dat<br/><br/>clock_clk=1clock_clk=0a6=clock_dat<br/><br/>clock_clk=1clock_clk=0a7=clock_dat<br/><br/>return(ACC)<br/><br/>}unsignedcharread_clock(unsignedcharreg1)//从reg1寄存器读数据
{
unsignedchardd=0
clock_clk=0
clock_rst=0
clock_rst=1
clock_write(reg1)
dd=clock_read()
clock_rst=0
return(dd)
}voidwrite_clock(unsignedcharreg2,unsignedchardate)//向reg2写入date数据
{
clock_clk=0
clock_rst=0
clock_rst=1
clock_write(reg2)
clock_write(date)
clock_rst=0
}voidshow(void)//显示和闪烁函数
{
unsignedchard,e
unsignedinti
for(i=0i<1000i++)
{
d=read_clock(0x81)//读秒
e=d
d=d>>4
e=e&0x0fP0=Tab_Num[d]//秒十位
wei2=1
delay(250)
wei2=0
P0=Tab_Num[e]//秒各位
wei1=1
delay(250)
wei1=0d=read_clock(0x83)//读分钟
e=d
d=d>>4
e=e&0x0fP0=Tab_Num[d]//分十位
wei4=1
delay(250)
wei4=0
P0=Tab_Num[e]//分各位
wei3=1
delay(250)
wei3=0d=read_clock(0x85)//读小时
e=d
d=d>>4
e=e&0x0fP0=Tab_Num[d]//小时十位
wei6=1
delay(250)
wei6=0
P0=Tab_Num[e]//小时各位
wei5=1
delay(250)
wei5=0
}for(i=0i<400i++)//间隔显示
{
d=read_clock(0x87)//读日
e=d
d=d>>4
e=e&0x0f
P0=Tab_Num[d]//日十位
wei2=1
delay(250)
wei2=0
P0=Tab_Num[e]//日各位
wei1=1
delay(250)
wei1=0d=read_clock(0x89)//读月
e=d
d=d>>4
e=e&0x0f
P0=Tab_Num[d]//月十位
wei4=1
delay(250)
wei4=0
P0=Tab_Num[e]//月各位
wei3=1
delay(250)
wei3=0d=read_clock(0x8d)//读年
e=d
d=d>>4
e=e&0xf
P0=Tab_Num[d]//年十位
wei6=1
delay(250)
wei6=0
P0=Tab_Num[e]//年各位
wei5=1
delay(250)
wei5=0
}
for(i=0i<200i++)//间隔显示
{
d=read_clock(0x8b)//读年
e=d
d=d>>4
e=e&0xf
P0=Tab_Num[d]//年十位
wei2=1
delay(250)
wei2=0
P0=Tab_Num[e]//年各位
wei1=1
delay(250)
wei1=0
}
}/*--------------------时钟的初始化---------------------------*/
voidInit_1302(void)//如果不满意现在的表,可以初始化调整,写入程序之后,再把初始化屏蔽掉
{
write_clock(0x8e,0x00)//close_protect
delay(250)
write_clock(0x8c,0x08)//year08年
delay(250)
write_clock(0x88,0x6)//month06
delay(250)
write_clock(0x86,0x25)//date25
delay(250)
write_clock(0x84,0x8)//hour8
delay(250)
write_clock(0x82,0x28)//minute28
delay(250)
write_clock(0x80,0x29)//second40
delay(250)
write_clock(0x8a,0x03)//week_day3
delay(250)
write_clock(0x90,0xa0)//supply_power
delay(250)write_clock(0x8e,0x80)//protect
delay(250)
}
voidmain(void)
{
inti
for(i=0i<2i++)
delay(2000)
Init_1302()//DS1302寄存器初始化P2=0x00while(1)
{
show()
}
}
彻底断电后重新上电时时钟可能正常走时也可能不走并显示乱码何以解决?这是楼主的问题。解决之道,在你的程序里加一个可选的时钟设置功能需要时启用这个功能设定好时间后启动走时,并进行写保护做时钟,时间设置功能是基本要求就算你不拔电池,一旦走时出现误差也要重新设置时间进行修正啊!#include <reg52.h>#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit SCK=P3^6
sbit SDA=P3^4
sbit RST=P3^5// DS1302复位
sbit set=P3^0//定义按键端口
sbit s1=P3^1
sbit s2=P3^2
sbit s3=P3^3
/************液晶口定义*******/
sbit RS=P2^4//RS为数据/指令选择1/0
sbit RW=P2^5//读写
sbit E=P2^6//E为使能信号
bit flag//是否读取时间的标志位
uchar setn=0//复位键、增加键、减少键按下次数
uchar code time0[]="DATE: - - "
uchar code time1[]="TIME: : : "
uchar l_tmpdate[7]={0,55,16,22,8,6,9}//秒分时日月周年// 可随时更改
uchar code write_add[7]={0x80,0x82,0x84,0x86,
0x88,0x8a,0x8c}//秒分时日月周年 写的寄存器地址
uchar code read_add[7]={0x81,0x83,0x85,0x87,
0x89,0x8b,0x8d}//秒分时日月周年 读的寄存器地址
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d
,0x7d,0x07,0x7f,0x6f,0x40}//共阴数码管 0-9加'-'熄灭表
void delay(uint z)
{
while(--z)
}
void write_com(uchar com)//液晶写命令函数
{
RS=0//写命令使能
RW=0//写
delay(5000)
/****在高脉冲下命令输入*****/
E=0
P0=com
delay(500)
E=1
delay(500)
E=0
}
void write_data(uchar dat)//液晶写数据函数
{
RS=1//写数据使能
RW=0
delay(5000)
/****在高脉冲下数据输入*****/
E=0
P0=dat
delay(500)
E=1
delay(500)
E=0
}
void init()//液晶初始化
{
uchar num
E=0
write_com(0x38)//显示模式设置
delay(500)
write_com(0x38)
delay(500)
write_com(0x38)
write_com(0x08)//显示关闭
delay(500)
write_com(0x01)//显示清屏
write_com(0x06)//光标移动设置整屏不移动
write_com(0x0c)//屏幕开、光标不闪(0)不显示(0)
delay(500)
write_com(0x80)
for(num=0num<16num++)
{
write_data(time0[num])
delay(5)
}
write_com(0x80+0x40)
for(num=0num<13num++)
{
write_data(time1[num])
delay(5)
}
}
void Write_Ds1302_Byte(uchar temp) //写一个字节
{
uchar i
for (i=0i<8i++)//循环8次写入数据
{
SCK=0
SDA=temp&0x01 //每次传输低字节
temp>>=1 //右移一位
SCK=1
}
}
/****************************************************************************/
void Write_Ds1302(uchar add,uchar dat )//向寄存器写数据
{
RST=0
_nop_()
SCK=0
_nop_()
RST=1//启动
_nop_()
Write_Ds1302_Byte(add)//发送地址
Write_Ds1302_Byte(dat)//发送数据
RST=0 //恢复
}
uchar Read_Ds1302_Byte()//读一个字节
{
uchar i,temp=0x00
for (i=0i<8i++) //循环8次 读取数据
{
if(SDA)
temp|=0x80 //每次传输低字节
SCK=0
temp>>=1 //右移一位
SCK=1
}
return(temp)
}
uchar Read_Ds1302(uchar address )//从寄存器读数据
{
uchar date
RST=0
_nop_()
SCK=0
_nop_()
RST=1
_nop_()
Write_Ds1302_Byte(address)
date=Read_Ds1302_Byte()
RST=0
_nop_() //以下为DS1302复位的稳定时间
RST=0
SCK=0
_nop_()
SCK=1
_nop_()
SDA=0
_nop_()
SDA=1
_nop_()
return (date)
}
/*********************************************************/
void Read_RTC(void) //读取日历
{
uchar i,*p
p=read_add //读的地址传递
for(i=0i<7i++) //分7次读取 秒分时日月周年
{
l_tmpdate[i]=Read_Ds1302(*p)
p++
}
}
/******************************************************/
void Set_RTC(void) //设定日历
{
uchar i,*p,tmp
for(i=0i<7i++)
{ //BCD处理,将十六进制转换成十进制
tmp=l_tmpdate[i]/10
l_tmpdate[i]=l_tmpdate[i]%10
l_tmpdate[i]=l_tmpdate[i]+tmp*16
}
Write_Ds1302(0x8E,0X00)//关闭写保护
p=write_add//传要写的寄存器地址
for(i=0i<7i++) //7次写入秒分时日月周年
{
Write_Ds1302(*p,l_tmpdate[i])
p++
}
Write_Ds1302(0x8E,0x80)//打开写保护
}
void write_lcd()
{
static uchar i,temp[2]
switch(i)
{
case 0: write_com(0x80+0x40+0x0b)break//秒
case 1: write_com(0x80+0x40+8)break//分
case 2: write_com(0x80+0x40+5)break//时
case 3: write_com(0x80+0x0b)break//日
case 4: write_com(0x80+8)break//月
case 5: write_com(0x80+0x0e)break//星期
case 6: write_com(0x80+5)break//年
}
temp[0]=l_tmpdate[i]/16//数据的转换
temp[1]=l_tmpdate[i]&0x0f
write_data(0x30+temp[0])
write_data(0x30+temp[1])
i++
if(i==7)
i=0
}
uchar change(uchar x)//十进制转换成十六进制
{
uchar tep,y
y=x
tep=y/16
y=y%16
y=y+tep*10
return y
}
void keyscan()
{
uchar tem[2],tp,Flag//存储要更改的时间数据
if(set==0)
{
flag=1//时间停止
delay(500)//去键盘按下抖动
if(set==0)
{
delay(500)
while(!set)
delay(500)//去键盘抬起时抖动
while(!set)
delay(500)
setn++
if(setn==1)
{
write_com(0x80+0x40+12)//将光标移动到秒个位
write_com(0x0f)//显示光标并且闪烁
}
if(setn==2)
{
write_com(0x80+0x40+9)//将光标移动到分个位
write_com(0x0f)//显示光标并且闪烁
}
if(setn==3)
{
write_com(0x80+0x40+6)//将光标移动到时个位
write_com(0x0f)//显示光标并且闪烁
}
if(setn==4)
{
write_com(0x80+15)
write_com(0x0f)
}
if(setn==5)
{
write_com(0x80+12)
write_com(0x0f)
}
if(setn==6)
{
write_com(0x80+9)
write_com(0x0f)
}
if(setn==7)
{
write_com(0x80+6)
write_com(0x0f)
}
if(setn==8)
{
setn=0
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[0],l_tmpdate[0])
Write_Ds1302(0x8E,0x80)//打开写保护
flag=0//时钟正常运行
write_com(0x0c)//光标停止闪烁
}
}
}
if(setn!=0)//更改时间
{
if(s1==0)//增加时间
{
delay(5000)
if(s1==0)
{
while(!s1)
delay(5000)//去键盘抬起时抖动
while(!s1)
if(setn==1)
{
l_tmpdate[0]=change(l_tmpdate[0])
l_tmpdate[0]++
if(l_tmpdate[0]>=60)
l_tmpdate[0]=0
{
tp=l_tmpdate[0]/10
l_tmpdate[0]=l_tmpdate[0]%10
l_tmpdate[0]=l_tmpdate[0]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[0],l_tmpdate[0])
Write_Ds1302(0x8E,0x80)//打开写保护
}
write_com(0x80+0x40+11)
tem[0]=l_tmpdate[0]/16//数据的转换
tem[1]=l_tmpdate[0]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+0x40+12)
Flag=1
}
if(setn==2)
{ l_tmpdate[1]=change(l_tmpdate[1])
l_tmpdate[1]++
if(l_tmpdate[1]==60)
l_tmpdate[1]=0
{
tp=l_tmpdate[1]/10
l_tmpdate[1]=l_tmpdate[1]%10
l_tmpdate[1]=l_tmpdate[1]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[1],l_tmpdate[1])
Write_Ds1302(0x8E,0x80)//打开写保护
}
write_com(0x80+0x40+8)
tem[0]=l_tmpdate[1]/16//数据的转换
tem[1]=l_tmpdate[1]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+0x40+9)
}
if(setn==3)
{ l_tmpdate[2]=change(l_tmpdate[2])
l_tmpdate[2]++
if(l_tmpdate[2]>=24)
l_tmpdate[2]=0
{
tp=l_tmpdate[2]/10
l_tmpdate[2]=l_tmpdate[2]%10
l_tmpdate[2]=l_tmpdate[2]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[2],l_tmpdate[2])
Write_Ds1302(0x8E,0x80)//打开写保护
}
write_com(0x80+0x40+5)
tem[0]=l_tmpdate[2]/16//数据的转换
tem[1]=l_tmpdate[2]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+0x40+6)
}
if(setn==4)
{
l_tmpdate[5]=change(l_tmpdate[5])
l_tmpdate[5]++
if(l_tmpdate[5]==8)
l_tmpdate[5]=1
{
tp=l_tmpdate[5]/10
l_tmpdate[5]=l_tmpdate[5]%10
l_tmpdate[5]=l_tmpdate[5]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[5],l_tmpdate[5])
Write_Ds1302(0x8E,0x80)//打开写保护
}
write_com(0x80+14)
tem[0]=l_tmpdate[5]/16//数据的转换
tem[1]=l_tmpdate[5]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+15)
}
if(setn==5)
{
l_tmpdate[3]=change(l_tmpdate[3])
l_tmpdate[3]++
if(l_tmpdate[3]==32)
l_tmpdate[3]=0
{
tp=l_tmpdate[3]/10
l_tmpdate[3]=l_tmpdate[3]%10
l_tmpdate[3]=l_tmpdate[3]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[3],l_tmpdate[3])
Write_Ds1302(0x8E,0x80)//打开写保护
}
write_com(0x80+11)
tem[0]=l_tmpdate[3]/16//数据的转换
tem[1]=l_tmpdate[3]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+12)
}
if(setn==6)
{
l_tmpdate[4]=change(l_tmpdate[4])
l_tmpdate[4]++
if(l_tmpdate[4]==13)
l_tmpdate[4]=0
write_com(0x80+8)
{
tp=l_tmpdate[4]/10
l_tmpdate[4]=l_tmpdate[4]%10
l_tmpdate[4]=l_tmpdate[4]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[4],l_tmpdate[4])
Write_Ds1302(0x8E,0x80)//打开写保护
}
tem[0]=l_tmpdate[4]/16//数据的转换
tem[1]=l_tmpdate[4]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+9)
}
if(setn==7)
{
l_tmpdate[6]=change(l_tmpdate[6])
l_tmpdate[6]++
if(l_tmpdate[6]==100)
l_tmpdate[6]=0
write_com(0x80+5)
{
tp=l_tmpdate[6]/10
l_tmpdate[6]=l_tmpdate[6]%10
l_tmpdate[6]=l_tmpdate[6]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[6],l_tmpdate[6])
Write_Ds1302(0x8E,0x80)//打开写保护
}
tem[0]=l_tmpdate[6]/16//数据的转换
tem[1]=l_tmpdate[6]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+6)
}
}
}
if(s2==0)//减少时间
{
delay(5000)
if(s2==0)
{
while(!s2)
delay(5000)//去键盘抬起时抖动
while(!s2)
if(setn==1)
{
l_tmpdate[0]=change(l_tmpdate[0])
if(l_tmpdate[0]!=0)
l_tmpdate[0]--
if(l_tmpdate[0]==0)
l_tmpdate[0]=59
{
tp=l_tmpdate[0]/10
l_tmpdate[0]=l_tmpdate[0]%10
l_tmpdate[0]=l_tmpdate[0]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[0],l_tmpdate[0])
Write_Ds1302(0x8E,0x80)//打开写保护
}
write_com(0x80+0x40+11)
tem[0]=l_tmpdate[0]/16//数据的转换
tem[1]=l_tmpdate[0]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+0x40+12)
}
if(setn==2)
{
l_tmpdate[1]=change(l_tmpdate[1])
if(l_tmpdate[1]!=0)
l_tmpdate[1]--
if(l_tmpdate[1]==0)
l_tmpdate[1]=59
{
tp=l_tmpdate[1]/10
l_tmpdate[1]=l_tmpdate[1]%10
l_tmpdate[1]=l_tmpdate[1]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[1],l_tmpdate[1])
Write_Ds1302(0x8E,0x80)//打开写保护
}
write_com(0x80+0x40+8)
tem[0]=l_tmpdate[1]/16//数据的转换
tem[1]=l_tmpdate[1]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+0x40+9)
}
if(setn==3)
{ l_tmpdate[2]=change(l_tmpdate[2])
if(l_tmpdate[2]!=0)
l_tmpdate[2]--
if(l_tmpdate[2]==0)
l_tmpdate[2]=23
{
tp=l_tmpdate[2]/10
l_tmpdate[2]=l_tmpdate[2]%10
l_tmpdate[2]=l_tmpdate[2]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[2],l_tmpdate[2])
Write_Ds1302(0x8E,0x80)//打开写保护
}
write_com(0x80+0x40+5)
tem[0]=l_tmpdate[2]/16//数据的转换
tem[1]=l_tmpdate[2]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+0x40+6)
}
if(setn==4)
{
l_tmpdate[5]=change(l_tmpdate[5])
if(l_tmpdate[5]!=0)
l_tmpdate[5]--
if(l_tmpdate[5]==0)
l_tmpdate[5]=7
{
tp=l_tmpdate[5]/10
l_tmpdate[5]=l_tmpdate[5]%10
l_tmpdate[5]=l_tmpdate[5]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[5],l_tmpdate[5])
Write_Ds1302(0x8E,0x80)//打开写保护
}
write_com(0x80+14)
tem[0]=l_tmpdate[5]/16//数据的转换
tem[1]=l_tmpdate[5]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+15)
}
if(setn==5)
{
l_tmpdate[3]=change(l_tmpdate[3])
if(l_tmpdate[3]!=0)
l_tmpdate[3]--
if(l_tmpdate[3]==0)
l_tmpdate[3]=31
{
tp=l_tmpdate[3]/10
l_tmpdate[3]=l_tmpdate[3]%10
l_tmpdate[3]=l_tmpdate[3]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[3],l_tmpdate[3])
Write_Ds1302(0x8E,0x80)//打开写保护
}
write_com(0x80+11)
tem[0]=l_tmpdate[3]/16//数据的转换
tem[1]=l_tmpdate[3]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+12)
}
if(setn==6)
{
l_tmpdate[4]=change(l_tmpdate[4])
if(l_tmpdate[4]!=0)
l_tmpdate[4]--
if(l_tmpdate[4]==0)
l_tmpdate[4]=12
write_com(0x80+8)
{
tp=l_tmpdate[4]/10
l_tmpdate[4]=l_tmpdate[4]%10
l_tmpdate[4]=l_tmpdate[4]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[4],l_tmpdate[4])
Write_Ds1302(0x8E,0x80)//打开写保护
}
tem[0]=l_tmpdate[4]/16//数据的转换
tem[1]=l_tmpdate[4]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+9)
}
if(setn==7)
{
l_tmpdate[6]=change(l_tmpdate[6])
if(l_tmpdate[6]!=0)
l_tmpdate[6]--
if(l_tmpdate[6]==0)
l_tmpdate[6]=99
write_com(0x80+5)
{
tp=l_tmpdate[6]/10
l_tmpdate[6]=l_tmpdate[6]%10
l_tmpdate[6]=l_tmpdate[6]+tp*16
Write_Ds1302(0x8E,0X00)//关闭写保护
Write_Ds1302(write_add[6],l_tmpdate[6])
Write_Ds1302(0x8E,0x80)//打开写保护
}
tem[0]=l_tmpdate[6]/16//数据的转换
tem[1]=l_tmpdate[6]&0x0f
write_data(0x30+tem[0])
write_data(0x30+tem[1])
write_com(0x80+6)
}
}
}
}
}
/*******************************************************/
void main(void)
{
//Set_RTC()//在第一次使用时给ds1302赋初值
init()
while(1)
{
if(flag==0)
{
Read_RTC()
write_lcd()
}
keyscan()
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)