以at89c51为核心,制作一个LED显示的智能电子钟。用C语言或Keil编程,Proteus画原理图,望高手回答!~

设计要求:1、计时:秒、分、时、天、周、月、年
2、2路定时输出,可任意关断
3、时间、月、日交替显示
4、键盘采用动态扫描的方式,所有的查询、设置功能均由功能键K1、K2完成
很急需!~如遇高手请发我邮箱[email protected]

我这里有但是和你的功能有差别,你可以看看,在改改!我用的at89c52单片机
程序:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit T_RST=P1^0; //ds1302复位引脚
sbit T_CLK=P1^1; //ds1302时钟引脚
sbit T_IO=P1^2; //ds1302数据引脚
sbit lcdrs=P2^0; //液晶数据/命令选择端(H/L)
sbit lcden=P2^1; //液晶使能信号端
sbit DQ=P2^7; //ds18B20温度传感信号端
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
uchar tempbuffer[6]; //温度显示数据
uint temp_value; //读取温度值
uchar flag=0;
uchar table1[22]="T:";
uchar code table2[]="D:";
//uchar *table3[7]={"Mon","Tue","Wen","Thu","Fri","Sat","Sun"};
uchar code s1[]={0x00,0x57,0x17,0x16,0x06,0x03,0x10};
uchar data s2[7]={0,0,0,0,0,0,0};
void delay_18b20(uint xus) /*温度延时函数*/
{ while(xus--);}
void delay(uchar xms) /*延时函数*/
{
uchar i,j;
for(i=xms;i>0;i--)
for(j=127;j>0;j--);
}
void wr_com(uchar com) /*液晶写命令函数*/
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void wr_data(uchar date) /*液晶写数据函数*/
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init() /*液晶初始化函数*/
{
uchar i,j;
lcden=0;
wr_com(0x01); //清屏
wr_com(0x38); //设置16*2显示,5*7点阵,8位数据接口
wr_com(0x0c); //开显示,不显示光标,字符不闪烁
wr_com(0x06); //光标从左向右移动,内容不移动
wr_com(0x80);
for(i=0;i<2;i++)
{
wr_data(table1[i]);
delay(5);
}
wr_com(0x80+0x40);
for(j=0;j<2;j++)
{
wr_data(table2[j]);
delay(5);
}
}
/******************ds1302时钟芯片******************/
/*************往ds1302写入1byte数据函数************/
void writeB(uchar ucda)
{
uchar i;
ACC=ucda;
for(i=8;i>0;i--)
{
T_IO=ACC0;
T_CLK=1;
T_CLK=0;
ACC=ACC>>1;
}
}
/*************从ds1302读取1byte数据函数************/
uchar readB()
{
uchar i;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
ACC7=T_IO;
T_CLK=1;
T_CLK=0;
}
return(ACC);
}
/*向ds1302某地址写入命令/数据函数,先写地址,后写命令/数据*/
void v_w1302(uchar ucaddr,uchar ucda)
{
T_RST=0;
T_CLK=0;
T_RST=1;
writeB(ucaddr); //写地址,命令
writeB(ucda); //写1byte数据
T_CLK=1;
T_RST=0;
}
/*读取ds1302某地址的数据函数,先写地址,后读命令/数据*/
//ucaddr:ds1302地址
uchar v_r1302(uchar ucaddr)
{
uchar ucda;
T_RST=0;
T_CLK=0;
T_RST=1;
writeB(ucaddr); //写地址
ucda=readB(); //读1byte命令/数据
T_CLK=1;
T_RST=0;
return(ucda);
}
/**********设置时钟初始时间函数***********/
//psecda(初始时间地址),格式为秒、分、时、日、月、星期、年
void v_set1302(uchar psecda[])
{
uchar i,j=0;
uchar ucaddr=0x80;
v_w1302(0x8e,0x00);
for(i=7;i>0;i--)
{
v_w1302(ucaddr,psecda[j]);
j++;
ucaddr+=2;
}
v_w1302(0x8e,0x80); //控制命令,wp=1,写保护
}
/**********读取ds1302当前时间函数***********/
//uccurtime(保存当前时间地址),格式为秒、分、时、日、月、星期、年
void v_get1302(uchar uccurtime[])
{
uchar i;
uchar ucaddr=0x81;
for(i=0;i<7;i++)
{
uccurtime[i]=v_r1302(ucaddr);
ucaddr=ucaddr+2;
}
}
void change_time(uchar s[]) /*转换时间函数(BCD码转换成)*/
{
uchar i,j,a;
a=s[5];
table1[2]=(s[5]&0x0f)+'0'; //星期转换
table1[3]=' '; //输入空格
for(i=0,j=4;i<=2;i++) //转换秒、分、时
{
a=s[i];
table1[j]=(s[i]&0x0f)+'0';
j++;
a=a>>4;
table1[j]=(a&0x0f)+'0';
j++;
table1[j]=':';
j++;
}
a=s[6]; //转换年
table1[13]=(s[6]&0x0f)+'0';
a=a>>4;
table1[14]=(a&0x0f)+'0';
table1[15]='-';
for(i=3,j=16;i<=4;i++) //转换日、月
{
a=s[i];
table1[j]=(s[i]&0x0f)+'0';
j++;
a=a>>4;
table1[j]=(a&0x0f)+'0';
j++;
table1[j]='-';
j++;
}
}
/******************ds18B20温度传感****************************/
void ow_reset() /*复位函数*/
{
DQ=1;
delay_18b20(8);
DQ=0;
delay_18b20(80);
DQ=1;
delay_18b20(38);
}
uchar read_byte() /*从单线上读取一个字节*/
{
uchar i;
uchar value=0;
for(i=8;i>0;i--)
{
DQ=0;
value=value>>1;
DQ=1;
if(DQ)
value=value|0x80;
delay_18b20(8);
}
return(value);
}
void write_byte(uchar val) /*向单线上写一个字节*/
{
uchar i;
for(i=8;i>0;i--) //一次写一个字节
{
DQ=0;
DQ=val&0x01;
delay_18b20(8);
DQ=1;
val=val>>1;
}
}
void read_temperature() /*读取温度*/
{
uchar a=0,b=0;
ow_reset();
write_byte(0xcc); //忽略64位ROM地址
write_byte(0x44); //启动ds18B20进行温度转换
delay_18b20(80);
ow_reset();
write_byte(0xcc);
write_byte(0xbe); //读内部RAM中9字节的内容
delay_18b20(80);

a=read_byte();
b=read_byte();
temp_value=b<<8;
temp_value=temp_value|a; //+(a&0xf0)>>4;
if((temp_value&0x8000)!=0)
{
flag=1;
temp_value=~temp_value+1;
}
else
flag=0;
temp_value=temp_value*0.0625;
}
void temp_to_str() /*温度数据转换成字符函数*/
{
//tempbuffer[0]=temp_value/100+'0';//百位
tempbuffer[1]=temp_value/10+'0'; //十位
tempbuffer[2]=temp_value%10+'0'; //个位
tempbuffer[3]=0xdf; //温度符号
tempbuffer[4]='C';
tempbuffer[5]='\0';
}
void main()
{
uchar i;
init();
v_set1302(s1);
ow_reset();
while(1)
{
v_get1302(s2);
change_time(s2);
wr_com(0x82); //显示时、分、秒、星期
for(i=11;i>=2;i--)
{
wr_data(table1[i]);
delay(5);
}
wr_com(0x82+0x40); //显示月、日、年
for(i=20;i>=13;i--)
{
wr_data(table1[i]);
delay(5);
}
wr_data(' ');
delay(5);
read_temperature(); //读温度调用
temp_to_str(); //温度转换调用
if(flag==1)
{
wr_data('-');
delay(5);
}
for(i=1;i<6;i++)
{
wr_data(tempbuffer[i]); //显示温度
delay(20);
}
}
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-06-06
有偿制作,提供源码,原理图及代码,如需文档也可制作,联系邮箱:[email protected]