QQ网名大全

急!!!ds1302与1602液晶一起做一个万年历,要带闹钟!!万年历我会做,但是不会弄闹钟!!

我有个本科时学习51时自己写的,功能是可以实现的,不过方法不大好,你可以参考一下
要是完全用这个我不大建议,最还自己看看,写简便点的
#include <at89x52.h>
#include<intrins.h>
#define nop _nop_()
**it p07=p0^7;
**it lcd_rs=p2^0;
**it lcd_rw=p2^1;
**it lcd_e=p2^2;
**it rst=p2^3;
**it sclk=p2^4;
**it io=p2^5;
**it acc0=acc^0;
**it acc7=acc^7;
**it int=p3^2;
**it wei=p1^0;
**it up=p1^1;
**it down=p1^2;
unsigned char busy,temp1;
unsigned char times;
char ge,shi;
/************************************
长延时函数
*************************************/
void l_delay(unsigned char ms)
{
unsigned char i;
for(i=0;i<ms;i++)
{
unsigned char j;
for(j=0;j<247;j++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/************************************
短延时函数
*************************************/
void s_delay(unsigned char m)
{
unsigned char n;
for(n=0;n<m;n++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
/**************************************
检测lcd是否忙
**************************************/
void lcd_busy()
{
busy=0;
p0=0xff;
lcd_rs=0; //指令有效
lcd_rw=1; //读指令
lcd_e=1; //使能
s_delay(5);

lcd_e=0; //关闭

if(p07==0)
busy=0; //busy 忙碌,禁止
else
busy=1; // 不忙碌,允许写入数据
}
/**************************************
写指令数据到lcd
rw=0是写入
rs=0写入的是指令
**************************************/
void lcd_wc(int cmd)
{
while(busy==1)
; //检测忙碌
s_delay(5);

lcd_rs=0;
lcd_rw=0; //写指令
lcd_e=0;
s_delay(5);
lcd_e=1;
s_delay(5);
p0=cmd; //指令码
s_delay(5);
lcd_e=0;
}
/**************************************
写显示数据到lcd
rw=0是写入
rs=1写入的是数据
**************************************/
void lcd_wd(unsigned char dat)
{
while(busy==1) //检测忙碌
;
s_delay(5);
lcd_rs=1;
lcd_rw=0; //写数据
lcd_e=0;
s_delay(5);
lcd_e=1;
s_delay(5);
p0=dat; //数据码
s_delay(5);
lcd_e=0;
}
/****************************************
设定显示位置
****************************************/
void lcd_pos(unsigned char hh,unsigned char vv)
{
unsigned char pp;
if(hh==1)
pp=vv+0x80; //第一行数据码
if(hh==2)
pp=vv+0xc0; //第二行数据码
lcd_wc(pp); //写入数据码
}
/****************************************
lcd清屏
****************************************/
void lcd_clr()
{
s_delay(5);
lcd_wc(0x01);
l_delay(5);
}
/****************************************
lcd初始化
****************************************/
void lcd_init()
{
l_delay(5);
lcd_clr(); //清屏

lcd_wc(0x38); //设置16*2显示,5*7点阵,8位数据
l_delay(5);

lcd_wc(0x0c); //0ch-显示开,关光标 ;0eh-显示开,有光标 ; 0fh-显示开,有光标,光标闪烁
l_delay(5);

lcd_wc(0x06); //当读写一个字符后,地址指针加一,且光标加一
l_delay(5);

lcd_wc(0x01); //清屏
l_delay(5);

}

/******************************************
函数名:void write1302()
功能:写入芯片数据
入口参数:地址add 数据dat
返回值:读取的字节
******************************************/
void write1302(unsigned char add,unsigned char dat)
{
unsigned char z;
sclk=0;
rst=1;
acc=add;
nop;nop;nop;

for(z=8;z>0;z--)
{

io=acc0;
nop;nop;nop;
sclk=1;
nop;nop;nop;
sclk=0;
acc=_cror_(acc,1);
}

acc=dat;
for(z=8;z>0;z--)
{

io=acc0;
nop;nop;nop;
sclk=1;
nop;nop;nop;
sclk=0;
acc=_cror_(acc,1);
}
rst=0;
s_delay(5);

}
/******************************************
函数名:void read1302()
功能:读出芯片数据
入口参数:地址add
返回值:读取的一字节数据
******************************************/
void read1302(unsigned char ad)
{
unsigned char t;
sclk=0;
rst=1;
acc=ad;
for(t=8;t>0;t--)
{

io=acc0;
nop;nop;nop;
sclk=1;
nop;nop;nop;
sclk=0;
acc=_cror_(acc,1);
}

for(t=7;t>0;t--)
{
acc7=io;
nop;nop;nop;nop;nop;nop;
sclk=1;
nop;nop;nop;nop;nop;nop;
sclk=0;
acc=_cror_(acc,1);
}
rst=0;
temp1=acc;

}
/******************************************
时钟芯片初始化
******************************************/
void ds1302_init()
{
write1302(0x8e,0x00);
}
/******************************************
函数名:void fenli()
功能:将读取的一字节数分成高四位十位和低四位个位
入口参数:读取的数据
返回值:十位数shi,个位数ge
******************************************/
void fenli(unsigned char d)
{
unsigned char d0,d1,d2;
d1=d&0x0f;
ge=d1;
d0=_cror_(d,4);
d2=d0&0x0f;
shi=d2;
}
/******************************************
显示函数
******************************************/
void play()
{
read1302(0x85); //读小时
fenli(temp1);
lcd_pos(1,0);
lcd_wd(shi+0x30);
lcd_wd(ge+0x30);

lcd_wd(0x3a);

read1302(0x83); //读分
fenli(temp1);
lcd_pos(1,3);
lcd_wd(shi+0x30);
lcd_wd(ge+0x30);

lcd_wd(0x3a);

read1302(0x81); //读秒
fenli(temp1);
lcd_pos(1,6);
lcd_wd(shi+0x30);
lcd_wd(ge+0x30);

lcd_pos(1,10);
lcd_wd(0x57);
lcd_wd(0x65);
lcd_wd(0x65);
lcd_wd(0x6b);

read1302(0x8b); //读星期
fenli(temp1);
lcd_wd(ge+0x30);

read1302(0x8d); //读年
fenli(temp1);
lcd_pos(2,1);
lcd_wd(shi+0x30);
lcd_wd(ge+0x30);

lcd_wd(0x2d);

read1302(0x89); //读月
fenli(temp1);
lcd_pos(2,4);
lcd_wd(shi+0x30);
lcd_wd(ge+0x30);

lcd_wd(0x2d);

read1302(0x87); //读日
fenli(temp1);
lcd_pos(2,7);
lcd_wd(shi+0x30);
lcd_wd(ge+0x30);
}
/*********************************
函数名;weixuan()
功能;记录wei按键按下的次数
入口参数;无
返回值;按下次数times
*********************************/
void weixuan()
{

if(wei==0)
{
l_delay(5);
if(wei==0)
{
times+=1;
}

if(times==7)
times=0;
l_delay(500);
}

}

/**************************************
调节小时
**************************************/
void xiaoshi()
{
read1302(0x85);
fenli(temp1);
while(up==0)
{
l_delay(5);
if(up==0)
ge++;
if(ge==10)
{shi++;ge=0;}
if(ge==4&&shi==2)
{ge=0;shi=0;}
l_delay(500);
}
while(down==0)
{
l_delay(5);
if(down==0)
ge--;

if(ge==(-1)&&shi==0)
{ge=3;shi=2;}

if(ge==(-1))
{shi--;ge=9;}
l_delay(500);
}
temp1=shi*16+ge;
write1302(0x84,temp1);
read1302(0x85);
fenli(temp1);
lcd_pos(1,0);
lcd_wd(shi+0x30);
lcd_wd(ge+0x30);
}
/**************************************
调节分
**************************************/
void fen()
{
read1302(0x83);
fenli(temp1);
while(up==0)
{
l_delay(5);
if(up==0)
ge++;
if(ge==10)
{shi++;ge=0;}
if(shi==6)
{ge=0;shi=0;}
l_delay(500);
}
while(down==0)
{
l_delay(5);
if(down==0)
ge--;

if(ge==(-1)&&shi==0)
{ge=9;shi=5;}

if(ge==(-1))
{shi--;ge=9;}
l_delay(500);
}
temp1=shi*16+ge;
write1302(0x82,temp1);
read1302(0x83);
fenli(temp1);
lcd_pos(1,3);
lcd_wd(shi+0x30);
lcd_wd(ge+0x30);
}
/**************************************
调节秒
**************************************/
void miao()
{
read1302(0x81);
fenli(temp1);
while(up==0)
{
l_delay(5);
if(up==0)
ge++;
if(ge==10)
{shi++;ge=0;}
if(shi==6)
{ge=0;shi=0;}
l_delay(500);
}
while(down==0)
{
l_delay(5);
if(down==0)
ge--;

if(ge==(-1)&&shi==0)
{ge=9;shi=5;}

if(ge==(-1))
{shi--;ge=9;}
l_delay(500);
}
temp1=shi*16+ge;
write1302(0x80,temp1);
read1302(0x81);
fenli(temp1);
lcd_pos(1,6);
lcd_wd(shi+0x30);
lcd_wd(ge+0x30);
}
/**************************************
调节周
**************************************/
void zhou()
{
read1302(0x8b);
fenli(temp1);
while(up==0)
{
l_delay(5);
if(up==0)
ge++;
if(ge==8)
{ge=1;}
l_delay(500);
}
while(down==0)
{
l_delay(5);
if(down==0)
ge--;

if(ge==0)
{ge=7;}
l_delay(500);
}
temp1=shi*16+ge;
write1302(0x8a,temp1);
read1302(0x8b);
fenli(temp1);
lcd_pos(1,14);
lcd_wd(ge+0x30);
}
/**************************************
调节年
**************************************/
void nian()
{
read1302(0x8d);
fenli(temp1);
while(up==0)
{
l_delay(5);
if(up==0)
ge++;
if(ge==10)
{shi++;ge=0;}
if(shi==10)
{ge=0;shi=0;}
l_delay(500);
}
while(down==0)
{
l_delay(5);
if(down==0)
ge--;

if(ge==(-1)&&shi==0)
{ge=9;shi=9;}

if(ge==(-1))
{shi--;ge=9;}
l_delay(500);
}
temp1=shi*16+ge;
write1302(0x8c,temp1);
read1302(0x8d);
fenli(temp1);
lcd_pos(2,1);
lcd_wd(shi+0x30);
lcd_wd(ge+0x30);
}
/**************************************
调节月
**************************************/
void yue()
{
read1302(0x89);
fenli(temp1);
while(up==0)
{
l_delay(5);
if(up==0)
ge++;
if(ge==10)
{shi++;ge=0;}
if(shi==1&&ge==3)
{ge=1;shi=0;}
l_delay(500);
}
while(down==0)
{
l_delay(5);
if(down==0)
ge--;

if(ge==(0)&&shi==0)
{ge=2;shi=1;}

if(ge==(-1))
{shi--;ge=9;}
l_delay(500);
}
temp1=shi*16+ge;
write1302(0x88,temp1);
read1302(0x89);
fenli(temp1);
lcd_pos(2,4);
lcd_wd(shi+0x30);
lcd_wd(ge+0x30);
}
/**************************************
调节日
**************************************/
void ri()
{
read1302(0x87);
fenli(temp1);
while(up==0)
{
l_delay(5);
if(up==0)
ge++;
if(ge==10)
{shi++;ge=0;}
if(shi==3&&ge==2)
{ge=1;shi=0;}
l_delay(500);
}
while(down==0)
{
l_delay(5);
if(down==0)
ge--;

if(ge==(0)&&shi==0)
{ge=1;shi=3;}

if(ge==(-1))
{shi--;ge=9;}
l_delay(500);
}
temp1=shi*16+ge;
write1302(0x86,temp1);
read1302(0x87);
fenli(temp1);
lcd_pos(2,7);
lcd_wd(shi+0x30);
lcd_wd(ge+0x30);
}
/**************************************
函数名;ctrl
功能;选择调解位
**************************************/
void ctrl()
{
weixuan();
lcd_wc(0x38);
switch(times)
{
case 1: //位选按下1次就是调节小时显示

xiaoshi();
break;
case 2: //位选按下2次就是调节分显示
fen();
break;
case 3: //位选按下3次就是调节秒显示
miao();
break;
case 4: //位选按下4次就是调节星期显示
zhou();
break;
case 5: //位选按下5次就是调节年显示
nian();
break;
case 6: //位选按下6次就是调节月显示
yue();
break;
case 7: //位选按下7次就是调节日显示
ri();
break;
}
}

/********************************
外部中断0
********************************/
void exter() interrupt 0
{
ex0=0; //关闭外部中断0
int=1; //禁止外部中断0
if(int==0)
{
l_delay(5);
if(int==0)
{
ctrl();
play();
}
ex0=1; //开放中断0
}
else
times=0;

}

/******************************************
主函数
******************************************/
void main()
{
acc=0xff;
ds1302_init();
lcd_init();

while(1)
{

ea=1; //开总中断
ex0=1; //开外部中断0
it0=0; //设置低电平触发
play();
lcd_pos(2,9);
lcd_wd(0xa0);
lcd_wd(0xa0);
lcd_wd(0xa0);
lcd_wd(0xa0);
lcd_wd(0xa0);
}
}
佚名
2024-06-07 17:20:54
最佳回答
类似问题(10)