原理图如下:
后来才发现控制板的排阻位置放错了,该打PP ^__^
LAY好的PCB
下面是做好的板子,这年头什么都涨价,PCB也涨啊~~~晒晒图先~
再来几张焊上元件的图
接下来是工作中的万年历,白天拍的,数码管不是很亮,程序还没有完全编好,有些功能还没实现
下面这张是在设定闹钟时的万年历
现在一天走下来的话会快3、4秒,看了DS1302的DATASHEET,说是在晶振的两端并一6PF的电容会好点。
有何问题和建议可以去论坛http://bbs.555diy.com/dispbbs.asp?boardID=8&ID=326&page=1讨论,谢谢!
按键功能描述:
正常显示下:
按S1:全部数码管闪烁 → 按S3进入时间设定模式
→ 按S4进入闹钟设定模式
按S2:进入睡眠模式,全部数码管熄灭,LED6闪烁 → 按S1恢复显示
按S3:闹钟关闭
按S4:闹钟打开,并显示闹钟时间3秒
时间设定模式及闹钟设定模式:
按S1:不设定时间或闹钟
按S2:待设定数码管左移
按S3:待设定数码管+1
按S4:保存设定
C代码如下:
//*****************************************************//
// www.555diy.com 三五电子网 //
//作者;ksysl //
//日期:2008-03-04 //
//PCB型号:calendar001-A calendar001-B(组合而成) //
//软件版本:DS1302 002-A //
//*****************************************************//
//*****************************************************//
#include <reg52.h>
#include <stdio.h>
#include <intrins.h>
unsigned char year,month,day,week,hour,minute,second;
unsigned char temp_1,temp_2,temp_3;
unsigned char buff1,buff2;
unsigned char disp_data;
unsigned int temp_data;
unsigned char led_flash_flag; //设定时间时数码管闪烁用
unsigned char tcnt;
unsigned char add_data; //设时数据暂放用
unsigned char save_data; //保存设时用
unsigned char led_data1,led_data2,led_data3,led_data4,led_data5,led_data6,led_data7;//设定时间数据保存区
unsigned char led_data8,led_data9,led_data10,led_data11,led_data12,led_data13; //设定时间数据保存区
unsigned char key;
unsigned char key_qu;
unsigned char key_flag;
unsigned char set_flag; //=0 正常显示时间;=1设定时间;=2设定闹钟时间;=3不显示时间;=4选择设定时间还是闹钟;
unsigned char led_select; //数码管选择用
unsigned char set_time_over; //60秒无按键按下自动返回用
unsigned char led_select1,led_select2; //数码管闪烁选择用
unsigned char sleep; //=1关闭数码管显示用
unsigned char clock_set; //闹钟设定标志,=1关闭其余数码管
unsigned char clock_set_flag;
unsigned char clock_hour,clock_minute,clock_second;//闹钟时间
unsigned char hour_data,minute_data,second_data; //正常显示时间暂放区
unsigned char clock_time; //闹钟响铃记时
unsigned char clock_come; //闹钟时间到标志
unsigned char code disp_code[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x00}; //0~9段码 第10位为设定时间时数码管闪烁用
sbit s1=P2^0; //按键定义
sbit s2=P2^1;
sbit s3=P2^2;
sbit s4=P2^3;
sbit hc164data=P2^7; //74HC164数据口
sbit hc164clock=P2^6; //74HC164时钟口
sbit clock="P1"^0; //闹钟打开显示 LOW----亮
sbit wake_up=P1^1; //定时唤醒显示 LOW----亮
sbit led_flash=P1^2; //正常显示时LED闪烁控制 LOW----亮
sbit year_20=P1^3; //年份前两位显示控制 LOW----亮
sbit buzzer="P1"^4; //闹钟时间到响铃用 LOW----响
sbit ds1302_sclk=P1^5; //DS1302时钟口
sbit ds1302_rst=P1^6; //DS1302复位口
sbit ds1302_data=P1^7; //DS1302数据口
sbit DQ="P3"^7; //DS18B20数据口
void display(void);
void key_scan(void);
void send_hc164_data(void);
void delay(unsigned char time);
void int_1(void);
void int_0(void);
void time_1(void);
//延时函数
void delay_us(unsigned int us)
{
for(;us>0;us--);
}
//初始化函数
unsigned char RES_DS18B20(void)
{
unsigned char x;
DQ = 0; //DQ复位
delay_us(29); //精确延时 大于 480us
DQ = 1;
delay_us(3); //稍做延时
x=DQ;
delay_us(25);
return(x); //稍做延时后 如果x=0则初始化成功 x="1则初始化失败"
}
//读一个字节
unsigned char ReadOneChar(void)
{
unsigned char i;
unsigned char dat="0";
for (i=8;i>0;i--)
{
dat>>=1;
DQ = 0; // 给脉冲信号
DQ = 1; // 给脉冲信号
delay_us(1);
if(DQ==1)
{
dat|=0x80;
}
delay_us(6);
}
return(dat);
}
//写一个字节
WriteOneChar(unsigned char da)
{
unsigned char i;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = da&0x01;
delay_us(5);
DQ = 1;
da="da/2";
}
delay_us(5);
}
//读取温度
float ReadTemperature(void)
{
unsigned char a="0";
unsigned char b="0";
unsigned char c="0";
unsigned char d="0";
unsigned int t="0";
float tt="0";
RES_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay_us(10);
RES_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar(); //LSB
b=ReadOneChar(); //MSB
t="b"*256+a; //将char转为int型
tt=t*0.0625; //实际温度
tt= tt*10+0.5; // 将实际温度放大10倍输出并四舍五入
return(tt);
}
//********DS1302读写程序**********************************************//
/**********************************************************************
函 数 名:input_byte1302()
功 能:实时时钟写入一字节
说 明:往DS1302写入1Byte数据 (内部函数)
入口参数:inputdata 写入的数据
返 回 值:无
***********************************************************************/
void input_byte1302(unsigned char inputdata)
{
unsigned char i;
for(i=8; i>0; i--)
{
ds1302_data = (bit)(inputdata&0x01);
ds1302_sclk = 1;
ds1302_sclk = 0;
inputdata = inputdata >>1;
}
}
/********************************************************************
函 数 名:output_byte1302()
功 能:实时时钟读取一字节
说 明:从DS1302读取1Byte数据 (内部函数)
入口参数:无
返 回 值:outputdata
设 计: 日 期:
修 改: 日 期:
***********************************************************************/
unsigned char output_byte1302(void)
{
unsigned char i;
for(i=0; i<8; i++)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = ds1302_data;
ds1302_sclk = 1;
ds1302_sclk = 0;
}
return(ACC);
}
/********************************************************************
函 数 名:write1302()
功 能:往DS1302写入数据
说 明:先写地址,后写命令/数据 (内部函数)
调 用:input_byte1302()
入口参数:addr: DS1302地址, indata: 要写的数据
返 回 值:无
***********************************************************************/
void write1302(unsigned char addr, unsigned char indata)
{
ds1302_rst = 0;
ds1302_sclk = 0;
ds1302_rst = 1;
input_byte1302(addr); // 地址,命令
input_byte1302(indata); // 写1Byte数据
ds1302_sclk = 1;
ds1302_rst = 0;
}
/********************************************************************
函 数 名:read1302()
功 能:读取DS1302某地址的数据
说 明:先写地址,后读命令/数据 (内部函数)
调 用:input_byte1302() , output_byte()
入口参数:addr: DS1302地址
返 回 值:outdata :读取的数据
***********************************************************************/
unsigned char read1302(unsigned char addr)
{
unsigned char outdata;
ds1302_rst = 0;
ds1302_sclk = 0;
ds1302_rst = 1;
input_byte1302(addr); // 地址,命令
outdata = output_byte1302(); // 读1Byte数据
ds1302_sclk = 1;
ds1302_rst = 0;
return(outdata);
}
void delay(unsigned char time) //延时
{
unsigned char m;
unsigned char n;
for(m=time;m>0;m--)
for(n=248;n>0;n--);
}
//********************************************************************//
// 74hc164发送数据
void send_hc164_data(void)
{
unsigned char i;
disp_data=disp_code[buff2];
hc164clock=0;
for(i=0;i<8;i++)
{
hc164data=(bit)(disp_data&0x80);
hc164clock=1;
disp_data<<=1;
hc164clock=0;
}
disp_data=disp_code[buff1];
for(i=0;i<8;i++)
{
hc164data=(bit)(disp_data&0x80);
hc164clock=1;
disp_data<<=1;
hc164clock=0;
}
hc164clock=0;
}
// 74hc164发送数据结素
//**************************************************************************//
//**************************************************************************//
// 数码管显示程序开始
void display()
{
if(sleep==0)
{
if(clock_set==0)
{
year_20=0;
delay(3);
year_20=1;
}
//************************************************************************//
if(((bit)(led_select1&0x01)==1)||(clock_set==1))
{
buff1=10;
}
else
{
buff1=led_data1;
}
if((bit)(led_select2&0x01)==1)
{
buff2=10;
}
else
{
buff2=led_data8;
}
send_hc164_data();
P0=0xfe;
delay(3);
P0=0xff;
//***********************************************************************//
if(((bit)(led_select1&0x02)==1)||(clock_set==1))
{
buff1=10;
}
else
{
buff1=led_data2;
}
if((bit)(led_select2&0x02)==1)
{
buff2=10;
}
else
{
buff2=led_data9;
}
send_hc164_data();
P0=0xfd;
delay(3);
P0=0xff;
//************************************************************************//
if(((bit)(led_select1&0x04)==1)||(clock_set==1))
{
buff1=10;
}
else
{
buff1=led_data3;
}
if((bit)(led_select2&0x04)==1)
{
buff2=10;
}
else
{
buff2=led_data10;
}
send_hc164_data();
P0=0xfb;
delay(3);
P0=0xff;
//***********************************************************************//
if(((bit)(led_select1&0x08)==1)||(clock_set==1))
{
buff1=10;
}
else
{
buff1=led_data4;
}
if((bit)(led_select2&0x08)==1)
{
buff2=10;
}
else
{
buff2=led_data11;
}
send_hc164_data();
P0=0xf7;
delay(3);
P0=0xff;
//***********************************************************************//
if(((bit)(led_select1&0x10)==1)||(clock_set==1))
{
buff1=10;
}
else
{
buff1=led_data5;
}
if((bit)(led_select2&0x10)==1)
{
buff2=10;
}
else
{
buff2=led_data12;
}
send_hc164_data();
P0=0xef;
delay(3);
P0=0xff;
//**********************************************************************//
if(((bit)(led_select1&0x20)==1)||(clock_set==1))
{
buff1=10;
}
else
{
buff1=led_data6;
}
if((bit)(led_select2&0x20)==1)
{
buff2=10;
}
else
{
buff2=led_data13;
}
send_hc164_data();
P0=0xdf;
delay(3);
P0=0xff;
//*************************************************************************//
if(((bit)(led_select1&0x40)==1)||(clock_set==1))
{
buff1=10;
}
else
{
buff1=led_data7;
}
if(clock_set==1)
{
buff2=10;
}
else
{
buff2=temp_1;
}
send_hc164_data();
P0=0xbf;
delay(3);
P0=0xff;
//**************************************************************************//
if(clock_set==0)
{
buff1=temp_3;
buff2=temp_2;
send_hc164_data();
P0=0x7f;
delay(3);
P0=0xff;
}
}
//****************************************************************************//
// 需设定数码管闪烁,设定时间和闹钟共用
if((set_flag==1)||(set_flag==2))
{
switch(led_select)
{
case 1: led_select1=0x00;
led_select2=0x00;
if(led_flash_flag==0)
{
led_select1=0x01;
}
break;
case 2: led_select1=0x00;
led_select2=0x00;
if(led_flash_flag==0)
{
led_select1=0x02;
}
break;
case 3: led_select1=0x00;
led_select2=0x00;
if(led_flash_flag==0)
{
led_select1=0x04;
}
break;
case 4: led_select1=0x00;
led_select2=0x00;
if(led_flash_flag==0)
{
led_select1=0x08;
}
break;
case 5: led_select1=0x00;
led_select2=0x00;
if(led_flash_flag==0)
{
led_select1=0x10;
}
break;
case 6: led_select1=0x00;
led_select2=0x00;
if(led_flash_flag==0)
{
led_select1=0x20;
}
break;
case 7: led_select1=0x00;
led_select2=0x00;
if(led_flash_flag==0)
{
led_select1=0x40;
}
break;
case 8: led_select1=0x00;
led_select2=0x00;
if(led_flash_flag==0)
{
led_select2=0x01;
}
break;
case 9: led_select1=0x00;
led_select2=0x00;
if(led_flash_flag==0)
{
led_select2=0x02;
}
break;
case 10: led_select1=0x00;
led_select2=0x00;
if(led_flash_flag==0)
{
led_select2=0x04;
}
break;
case 11: led_select1=0x00;
led_select2=0x00;
if(led_flash_flag==0)
{
led_select2=0x08;
}
break;
case 12: led_select1=0x00;
led_select2=0x00;
if(led_flash_flag==0)
{
led_select2=0x10;
}
break;
case 13: led_select1=0x00;
led_select2=0x00;
if(led_flash_flag==0)
{
led_select2=0x20;
}
break;
default : break;
}
}
}
//*****************************************************************************************//
// 数码管显示程序结束
//********************************************************************************//
//**********************************************************************************//
// 按键处理程序开始
void key_scan(void)
{
if(clock_come==1) //闹钟响时按S1,关闭闹钟
{
if(s1==0)
{
clock_come=0;
clock="0";
buzzer="1";
set_flag=0;
}
}
if(set_flag==2)
{
if(s1==0) //闹钟时间设定时按S1,退出闹钟设定时间,不保存闹钟设定时间
{
set_time_over=119;
}
if(s4==0) //闹钟时间设定时按S4,保存闹钟设定时间
{
clock="0";
// led_data8=led_data8<<4;
clock_hour=(led_data8*10+led_data9);
// led_data10=led_data10<<4;
clock_minute=(led_data10*10+led_data11);
// led_data12=led_data12<<4;
clock_second=(led_data12*10+led_data13);
set_time_over=119;
}
}
if(set_flag==4)
{
if(s1==0) //时间设定选择时按S1退出选择
{
set_time_over=119;
}
if(s3==0) //时间设定选择时按S3进入时间设定
{
sleep="0";
set_flag=1;
led_flash=1;
led_select=1;
}
if(s4==0) //时间设定选择时按S4进入闹钟设定
{
sleep="0";
clock_set=1;
set_flag=2;
led_select=8;
led_flash=1;
led_data8=clock_hour/10;
led_data9=clock_hour%10;
led_data10=clock_minute/10;
led_data11=clock_minute%10;
led_data12=clock_second/10;
led_data13=clock_second%10;
}
}
if(set_flag==1)
{
if(s1==0) //设定时间的情况下再按S1,退出设定时间,不保存设定时间
{
set_time_over=119;
}
if(s4==0) //设定时间的情况下按S4,保存设定时间
{
write1302(0x8e,0x00);
led_data12=led_data12<<4;
save_data=led_data12+led_data13;
write1302(0x80,save_data);
led_data10=led_data10<<4;
save_data=led_data10+led_data11;
write1302(0x82,save_data);
led_data8=led_data8<<4;
save_data=led_data8+led_data9;
write1302(0x84,save_data);
led_data5=led_data5<<4;
save_data=led_data5+led_data6;
write1302(0x86,save_data);
led_data3=led_data3<<4;
save_data=led_data3+led_data4;
write1302(0x88,save_data);
save_data=led_data7;
write1302(0x8a,save_data);
led_data1=led_data1<<4;
save_data=led_data1+led_data2;
write1302(0x8c,save_data);
write1302(0x8e,0x80);
set_time_over=119;
}
}
if(set_flag==1) //设定时间
{
if(s2==0) //按S2需设定数码管右移
{
set_time_over=0;
led_select++;
if(led_select==14)
{
led_select=1;
}
}
}
if(set_flag==2) //闹钟设定时间
{
if(s2==0) //按S2需设定数码管右移
{
set_time_over=0;
led_select++;
if(led_select==14)
{
led_select=8;
}
}
}
if((set_flag==1)||(set_flag==2)) //按S3需设定数码管加1,设定时间和闹钟共用
{
if(s3==0)
{
set_time_over=0;
switch(led_select)
{
case 1:
led_data1++;
if(led_data1==10)
{
led_data1=0;
}
break;
case 2:
led_data2++;
if(led_data2==10)
{
led_data2=0;
}
break;
case 3:
led_data3++;
if(led_data3==2)
{
led_data3=0;
}
break;
case 4:
led_data4++;
if(led_data4==10)
{
led_data4=0;
}
break;
case 5:
led_data5++;
if(led_data5==4)
{
led_data5=0;
}
break;
case 6:
led_data6++;
if(led_data6==10)
{
led_data6=0;
}
break;
case 7:
led_data7++;
if(led_data7==8)
{
led_data7=1;
}
break;
case 8:
led_data8++;
if(led_data8==3)
{
led_data8=0;
}
break;
case 9:
led_data9++;
if(led_data9==10)
{
led_data9=0;
}
break;
case 10:
led_data10++;
if(led_data10==6)
{
led_data10=0;
}
break;
case 11:
led_data11++;
if(led_data11==10)
{
led_data11=0;
}
break;
case 12:
led_data12++;
if(led_data12==6)
{
led_data12=0;
, ; }
break;
case 13:
led_data13++;
if(led_data13==10)
{
led_data13=0;
}
break;
default : break;
}
}
}
if((set_flag==0)&&(clock_come==0))
{
if(s1==0) //正常显示下(不闹钟),按S1进入设定选择模式
{
set_time_over=0;
tcnt="0";
led_flash=1;
set_flag=4;
}
if(s2==0) //正常显示下(不闹钟),关闭显示
{
sleep="1";
wake_up=0;
set_flag=3;
led_flash=1;
}
if(s3==0) //正常显示下,按S3关闭闹钟LED,关闭闹钟
{
clock="1";
}
if(s4==0) //正常显示下,按S4显示闹钟时间,并打开闹钟LED
{
buzzer="1";
clock="0";
clock_set=1;
set_time_over=110;
led_data8=clock_hour/10;
led_data9=clock_hour%10;
led_data10=clock_minute/10;
led_data11=clock_minute%10;
led_data12=clock_second/10;
led_data13=clock_second%10;
set_flag=5;
}
}
if(set_flag==3) //关闭显示的情况下,再次按S1打开显示
{
if(s1==0)
{
set_flag=0;
sleep="0";
wake_up=1;
}
}
}
// 按键处理结束
//************************************************************************//
//************************************************************************//
// 主程序
void main(void)
{
TMOD="0x10";
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
TR1=1;
ET1=1;
EX1=1; //外部中断1 按键扫描用
IT1=1; //外部中断1 边沿触发 若为0 电平触发
EA="1";
set_flag=0;
led_flash_flag=1;
led_flash=1;
key_flag=0;
clock="0";
sleep="0";
led_select=0;
led_select1=0;
led_select2=0;
clock_set_flag=0;
clock_come=0;
P0=0xff;
s1=1;
s2=1;
s3=1;
s4=1;
clock_hour=12; //闹钟付初值
clock_minute=0;
clock_second=0;
write1302(0x90,0xa0);//关闭充电二级管,不能对后备电池进行充电,防止发胀,原来的程序是打开的请关闭
write1302(0x8e,0x80);//写保护,禁止写操作
//set1302(inittime);
//write1302(0x8e,0x00);
//write1302(0x88,2);
//write1302(0x8e,0x80);
while(1)
{
if((set_flag==0)||(set_flag==3))
{
EA="0";
temp_data=ReadTemperature(); //读取温度
temp_1=temp_data/100; //显示数据处理
temp_2=temp_data%100/10;
temp_3=temp_data%100%10;
EA=1;
second="read1302"(0x81); //读取DS1302数据
led_data13=second&0x0f;
second=second >> 4;
led_data12=second&0x07;
minute="read1302"(0x83);
led_data11=minute&0x0f;
minute=minute >> 4;
led_data10=minute&0x07;
hour="read1302"(0x85);
led_data9=hour&0x0f;
hour=hour >> 4;
led_data8=hour&0x03;
day="read1302"(0x87);
led_data6=day&0x0f;
day=day >> 4;
led_data5=day&0x03;
month="read1302"(0x89);
led_data4=month&0x0f;
month=month >> 4;
led_data3=month&0x01;
week="read1302"(0x8b);
led_data7=week;
year="read1302"(0x8d);
led_data2=year&0x0f;
year=year >> 4;
led_data1=year&0x0f;
}
if(clock==0) //查询闹钟时间是否到
{
if((led_data8==clock_hour/10)&&(led_data9==clock_hour%10)&&(led_data10==clock_minute/10)&&
(led_data11==clock_minute%10)&&(led_data12==clock_second/10)&&(led_data12==clock_second%10))
{
clock_come=1;
}
if(clock_come==1)
{
if(set_flag==3)
{
set_flag=0;
}
if(led_flash==0)
{
buzzer="0";
}
else
{
buzzer="1";
}
}
else
{
buzzer="1";
}
}
else
{
buzzer="1";
}
display();
if(key_qu==1) //按键
{
key_qu=0;
key_flag=1;
if(INT1==0)
{
key_scan();
}
EX1=1;
}
}
}
//**************************************************************//
// 计数器1
void time_1(void) interrupt 3
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
if(key_flag==0)
{
key_qu++;
}
tcnt++;
if(set_flag==5)
{
if(tcnt==50)
{
tcnt="0";
buzzer=1;
set_flag=0;
// clock=1;
clock_set=0;
clock_come=0;
}
}
if(set_flag==4)
{
if(tcnt==5)
{
sleep="1";
}
if(tcnt==10)
{
tcnt="0";
sleep="0";
set_time_over++;
if(set_time_over==120)
{
set_time_over=0;
led_flash_flag=0;
led_select1=0x00;
led_select2=0x00;
clock_set=0;
clock_set_flag=0;
sleep="0";
set_flag=0;
}
}
}
if((set_flag==0)||(set_flag==3))
{
if(tcnt==10)
{
tcnt="0";
if(set_flag==0)
{
led_flash=~led_flash;
sleep=0;
}
if(set_flag==3)
{
wake_up=~wake_up;
}
if(clock_come==1) //闹钟响记时60S
{
clock_time++;
if(clock_time==120)
{
clock="0";
buzzer="1";
clock_come=0;
}
}
}
}
if((set_flag==1)||(set_flag==2))
{
if(tcnt==5)
{
led_flash_flag=0;
}
if(tcnt==10)
{
tcnt="0";
led_flash_flag=1;
set_time_over++;
if(set_time_over==120)
{
set_time_over=0;
led_flash_flag=0;
led_select1=0x00;
led_select2=0x00;
clock_set=0;
clock_set_flag=0;
sleep="0";
clock_come=0;
set_flag=0;
if(set_flag==2) //设定闹钟时间情况下,60S自动退出闹钟设定,不保存设定数据
{
hour="hour"_data;
minute="minute"_data;
second="second"_data;
}
}
}
}
}
// 计数器1程序结束
//**************************************************************//
//*******************************************************************//
// 外部中断1(按键触发)
void int_1(void) interrupt 2
{
EX1=0;
key_flag=0;
}
//****************************************************************************//
用户377235 2011-11-30 21:10
dear sir, pls send me circuit diagram of digital time/date clock and MCU code. thakyou Shahzad Ismail shahzad@brain.net.pk