温度时钟you电路图

更新时间:2024-05-27 18:34:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

时钟电路图设计:

PCB板设计:

单片机程序:

/*==================================================================== 调试要求:

1.MCU:AT89S52芯片或AT89C52 2.晶振:12MHz

功能:多功能时钟+温度计

====================================================================*/

#include #include

#define uchar unsigned char #define uint unsigned int

sbit dis_bit1=P2^7;//定义数码管控制口 sbit dis_bit2=P2^6;//定义数码管控制口 sbit dis_bit3=P2^4;//定义数码管控制口 sbit dis_bit4=P2^3;//定义数码管控制口 sbit dis_bit5=P2^1;//定义数码管控制口 sbit dis_bit6=P2^0;//定义数码管控制口 sbit led1_bit=P2^2;//定时LED的控制口

sbit led2_bit=P2^5;//定时LED的控制口 sbit s1_bit=P1^0; //定义S1控制口 sbit s2_bit=P1^1; //定义S2控制口 sbit s3_bit=P1^2; //定义S3控制口

sbit dq_ds18b20=P3^3;//定义控制DS18B20 sbit speak=P3^7; //定义蜂鸣器控制口

sbit clk_ds1302=P3^6;//定义控制DS1302的时钟线 sbit io_ds1302=P3^5;//定义控制DS1302的串行数据 sbit rest_ds1302=P3^4;

#define smg_data P0//定义数码管数据口

void delay_3us();//3US的延时程序

void delay_8us(uint t);//8US延时基准程序

void delay_50us(uint t);//延时50*T微妙函数的声明 void display1(uchar dis_data);//数码管1显示子程序 void display2(uchar dis_data);//数码管2显示子程序 void display3(uchar dis_data);//数码管3显示子程序 void display4(uchar dis_data);//数码管4显示子程序 void display5(uchar dis_data);//数码管5显示子程序 void display6(uchar dis_data);//数码管6显示子程序 void init_t0();//定时器0初始化函数 void dis_led();//LED处理函数 void judge_s1();//S1按键处理函数 void judge_s2();//S2按键处理函数 void judge_s3();//S3按键处理函数

void dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1);//显示子程序

void dis_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1,uchar san);//闪烁显示子程序

void judge_dis();//显示处理函数 void judge_clock();//显示处理函数 void set_ds1302();//设置时间

void get_ds1302();//读取当前时间

void w_1byte_ds1302(uchar t);//向DS1302写一个字节的数据 uchar r_1byte_ds1302();//从DS1302读一个字节的数据

//***********************************************************************

//DS18B20测温函数定义

void w_1byte_ds18b20(uchar value);//向DS18B20写一个字节 uchar r_1byte_ds18b20(void);//从DS18B20读取一个字节的数据 void rest_ds18b20(void);//DS18B20复位程序 void readtemp_ds18b20(void);//读取温度 void dis_temp();//温度显示函数

//共阳数码管断码表

const uchar tabl1[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92, // 0 1 2 3 4 5

0x82,0xf8,0x80,0x90,0x86,0x87,0xFF, //6 7 8 9 E T B 0xc6,0xbf,0xff}; // C - const uchar tabl3[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; uchar t0_crycle;

uchar hour_count,minute_count,second_count,msecond_count; uchar clock_hour,clock_minute; uchar countdown_second;

uchar countdown_hour,countdown_minute;

uchar clock_en;//闹钟关闭和开启的标志,1开启,0关闭 uchar flag1,second_flag,zancun1,zancun2,zancun3; uchar zancun4,zancun5,zancun6,zancun7; uchar clock_flag,countdown_flag;

uchar msecond_minute,msecond_second,msecond_msecond,msecond_flag;//秒表相关参数

uint speak_count;

uchar templ,temph,temp_flag;

uchar t_b,t_s,t_g,t_x,temp_flag2;//从左到右分别存储温度百位,十位,个位,小数位

uchar tab23[3];//={0x40,0x59,0x23,0x28,0x11,0x06,0x09};//上电时默认的时间 //主程序 void main() {

P3=0x00; flag1=0; zancun3=0;

msecond_minute=0;//置秒表相关参数为0 msecond_second=0; msecond_msecond=0; speak=1;//关闭蜂鸣器 speak_count=0; clock_hour=0; clock_minute=0; clock_flag=0;

countdown_flag=0;//倒计时标志位为0

clock_en=0;//开机时默认关闭闹钟 init_t0(); TR0=1;//

// set_ds1302();//设置DS1302的初始时间 //接下来开始编写让数码管显示的程序 while(1) {

get_ds1302();

judge_dis();//显示处理 judge_s1(); judge_s2(); judge_s3();

judge_clock();//闹钟处理程序 } }

void timer0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%6; t0_crycle++; if(t0_crycle==2)// 0.1秒 { t0_crycle=0;

msecond_flag=1; msecond_count++;

if(msecond_count==10)//1秒 {

msecond_count=0; second_flag=1; } } }

//************************************************** //显示处理函数 void judge_dis() {

if(flag1==0) {

if(second_flag==1) {

zancun7++; second_flag=0; }

if(zancun7<1)

{

if(temp_flag2==1) {

readtemp_ds18b20();//读取温度 temp_flag2=0; }

dis_temp();//温度显示函数 }

if(zancun7>=1) {

temp_flag2=1;

zancun4=hour_count&0xf0; zancun4>>=4;

zancun5=minute_count&0xf0; zancun5>>=4;

zancun6=second_count&0xf0; zancun6>>=4;

dis(zancun4,hour_count&0x0f,zancun5,minute_count&0x0f,zancun6,second_count&0x0f);

dis_led();

if(zancun7==5)zancun7=0; } }

if(flag1!=0) {

switch(flag1) {

case 1:

dis(5,10,11,1,12,12);//显示SET1 led1_bit=1; led2_bit=1; break; case 2:

dis(5,10,11,2,12,12);//显示SET2 break; case 3:

dis(5,10,11,3,12,12);//显示SET3 break; case 4:

dis(5,10,11,4,12,12);//显示SET4 break; case 5:

dis(5,10,11,5,12,12);//显示SET5 break; case 6:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,12,1); break; case 7:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,12,2); break; case 8:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,12,3); break;

case 9://进入修改时间,时间分位个位闪烁

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,12,4); break;

case 10://进入修改闹钟,闹钟小时十位闪烁

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,zancun3,1); break;

case 11://进入修改闹钟,闹钟小时个位闪烁

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,zancun3,2); break;

case 12://进入修改闹钟,闹钟小时十位闪烁

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,zancun3,3); break;

case 13://进入修改闹钟,闹钟小时个位闪烁

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,zancun3,4); break;

case 14://进入修改闹钟的开关

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,zancun3,6); break; case 15:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,zancun3/10,zancun3,1);

break; case 16:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,zancun3/10,zancun3,2);

break; case 17:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,zancun3/10,zancun3,3);

break; case 18:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,zancun3/10,zancun3,4);

break; case 19:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,zancun3/10,zancun3,5);

break; case 20:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,zancun3/10,zancun3,6);

break; case 21:

if(second_flag==1) {

second_flag=0;

countdown_second--;

if(countdown_second==255) {

countdown_second=59; countdown_minute--;

if(countdown_minute==255) {

countdown_minute=59; countdown_hour--;

if(countdown_hour==255) {

flag1=22;

countdown_minute=0; countdown_hour=0; countdown_second=0; countdown_flag=1;

} } } }

dis(countdown_hour/10,countdown_hour,countdown_minute/10,countdown_minute,countdown_second/10,countdown_second);// break; case 22:

if(countdown_flag>0 && countdown_flag<7) {

speak=0;

if(second_flag==1) {

second_flag=0; countdown_flag++; } } else {

speak=1; }

dis(countdown_hour/10,countdown_hour,countdown_minute/10,countdown_minute,countdown_second/10,countdown_second);// break; case 23:

dis(msecond_minute/10,msecond_minute,msecond_second/10,msecond_second,msecond_msecond,12); break; case 24:

if(msecond_flag==1) {

msecond_flag=0;

msecond_msecond++;

if(msecond_msecond==10) {

msecond_msecond=0; msecond_second++;

if(msecond_second==60) {

msecond_second=0;

msecond_minute++;

if(msecond_minute==100) {

msecond_minute=99; flag1=23; } } } }

dis(msecond_minute/10,msecond_minute,msecond_second/10,msecond_second,msecond_msecond,12); break; case 25:

dis(zancun3/10,zancun3,zancun2/10,zancun2,zancun1/10,zancun1); break; default: break; } } }

//************************************************** //S1按键处理函数 void judge_s1() {

s1_bit=1;//置IO为1,准备读入收据 if(s1_bit==0)//判断是否有按键按下 {

delay_50us(1);// 延时,去除机械抖动 if(s1_bit==0) {

switch(flag1) {

case 0: case 1: case 2: case 3: case 4: case 6: case 7: case 8: case 10: case 11:

case 12: case 13: case 15: case 16: case 17: case 18: case 19:

flag1++; break; case 9:

flag1=6; break; case 14:

flag1=10; break; case 20:

flag1=15; break; case 5: case 21: case 22:

case 23://系统从秒表状态复位 case 24://系统从秒表状态复位 case 25://系统从计数器复位 flag1=0; break; default: break; } while(s1_bit==0) {

judge_dis(); }//等待按键释放 } } }

//************************************************** //S2按键处理函数 void judge_s2() {

s2_bit=1;//置IO为1,准备读入收据 if(s2_bit==0)//判断是否有按键按下 {

delay_50us(1);// 延时,去除机械抖动

if(s2_bit==0) {

switch (flag1) {

case 1: //在显示SET1状态下按S2件,进入修改时间 flag1=6;

zancun4=hour_count&0xf0; zancun4>>=4;

zancun6=hour_count&0x0f; zancun1=zancun4*10+zancun6; //zancun1=hour_count;

zancun5=minute_count&0xf0; zancun5>>=4;

zancun6=minute_count&0x0f; zancun2=zancun5*10+zancun6; // zancun2=minute_count; break;

case 2://在显示SET2状态下按S2,进入设置闹钟 zancun1=clock_hour; zancun2=clock_minute; flag1=10; break;

case 6://修改时钟小时十位状态下按S2件 case 7://修改时钟小时个位状态下按S2件 case 8://修改时钟分钟十位状态下按S2件 case 9://修改时钟分钟个位状态下按S2件 //zancun4=zancun1/10;

tab23[2]=zancun1/10*16+zancun1;

//zancun5=zancun2&0xf0; //zancun5>>=4;

tab23[1]=zancun2/10*16+zancun2; hour_count=tab23[2]; minute_count=tab23[1]; second_count=0; tab23[0]=0;

set_ds1302();//设置DS1302的初始时间 flag1=0; break;

case 10://修改闹钟小时十位状态下按S2 case 11://修改闹钟小时个位状态下按S2 case 12://修改闹钟分钟十位状态下按S2 case 13://修改闹钟分钟个位状态下按S2

case 14://修改闹钟使能状态下按S2 clock_hour=zancun1; clock_minute=zancun2; clock_en=zancun3; flag1=0; break; case 3:

flag1=15;

zancun1=countdown_hour; zancun2=countdown_minute; zancun3=countdown_second; break; case 15: case 16: case 17: case 18: case 19: case 20:

countdown_hour=zancun1; countdown_minute=zancun2; countdown_second=zancun3; flag1=21;

countdown_flag=0; break; case 22:

flag1=21; break; case 21:

flag1=22; break; case 4:

flag1=23;//秒表暂停 msecond_minute=0; msecond_second=0; msecond_msecond=0; break; case 23:

flag1=24; break; case 24:

flag1=23; break; case 5:

flag1=25;//进入计数器模式

zancun1=0; zancun2=0; zancun3=0; break; default: break; }

while(s2_bit==0) {

judge_dis(); }//等待按键释放 } } }

//************************************************** //S3按键处理函数 void judge_s3() {

s3_bit=1;//置IO为1,准备读入收据 if(s3_bit==0)//判断是否有按键按下 {

delay_50us(1);// 延时,去除机械抖动 if(s3_bit==0) {

switch (flag1) {

case 6://修改时间小时的十位数 zancun1+=10;

if(zancun1>=24)zancun1=zancun1; break;

case 7://修改时间小时的个位数

zancun1=zancun1/10*10+(zancun1+1); if(zancun1>=24)zancun1=20; break;

case 8://修改时间分钟的十位数 zancun2+=10;

if(zancun2>=60)zancun2-=60; break;

case 9://修改时间分钟的个位数

zancun2=zancun2/10*10+(zancun2+1); break;

case 10://修改闹钟小时的十位数

zancun1+=10;

if(zancun1>=24)zancun1=zancun1; break;

case 11://修改闹钟小时的个位数

zancun1=zancun1/10*10+(zancun1+1); if(zancun1>=24)zancun1=20; break;

case 12://修改闹钟分钟的十位数 zancun2+=10;

if(zancun2>=60)zancun2-=60; break;

case 13://修改闹钟分钟的个位数

zancun2=zancun2/10*10+(zancun2+1); break; case 14:

zancun3^=1; break;

case 15://修改倒计时小时的十位数 zancun1+=10;

if(zancun1>=100)zancun1-=100; break;

case 16: //修改倒计时小时的个位数

zancun1=zancun1/10*10+(zancun1+1); break;

case 17://修改倒计时分钟的十位数 zancun2+=10;

if(zancun2>=60)zancun2-=60; break;

case 18: //修改倒计时分钟的个位数

zancun2=zancun2/10*10+(zancun2+1); break;

case 19://修改倒计时秒的十位数 zancun3+=10;

if(zancun3>=60)zancun3-=60; break;

case 20: //修改倒计时秒的个位数

zancun3=zancun3/10*10+(zancun3+1); break; case 21: case 22://

countdown_hour=zancun1; countdown_minute=zancun2; countdown_second=zancun3; flag1=21;

break; case 23:

case 24://秒表复位 flag1=24;

msecond_minute=0; msecond_second=0; msecond_msecond=0; break; case 25:

zancun1++;

if(zancun1==100) {

zancun1=0; zancun2++;

if(zancun2==100) {

zancun2=0; zancun3++; } }

break; default: break; }

while(s3_bit==0) {

judge_dis(); }//等待按键释放 } } }

//**************************************** //显示处理函数 void judge_clock() {

zancun4=hour_count&0xf0; zancun4>>=4;

zancun6=hour_count&0x0f; zancun4*=10;

zancun4+=zancun6;

zancun5=minute_count&0xf0; zancun5>>=4;

zancun6=minute_count&0x0f;

zancun5*=10;

zancun5+=zancun6;

if(clock_hour==zancun4 && clock_minute==zancun5) {

if(clock_en==1 && clock_flag==0) {

speak_count=0;//开启蜂鸣器 clock_flag=1; speak_count=0; } } else {

clock_flag=0; }

if(clock_flag==1 && speak_count<400) {

if(msecond_count<=5) {

speak=0;

speak_count++; } else {

speak=1;

} } else {

speak=1; } }

//**************************************** ////闪烁显示子程序

void dis_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1,uchar san) {

if(san==1) {

if(msecond_count<5) {

display1(s6);

} } else {

display1(s6); }

if(san==2) {

if(msecond_count<5) {

display2(s5); } } else {

display2(s5); }

if(san==3) {

if(msecond_count<5) {

display3(s4); } } else {

display3(s4); }

if(san==4) {

if(msecond_count<5) {

display4(s3); } } else {

display4(s3); }

if(san==5) {

if(msecond_count<5) {

display5(s2);

} } else {

display5(s2); }

if(san==6) {

if(msecond_count<5) {

display6(s1); } } else {

display6(s1); } }

//**************************************** //时钟显示程序

void dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1) {

display1(s6); display2(s5); display3(s4); display4(s3); display5(s2); display6(s1); }

//******************************************************************************************** void init_t0() {

TMOD=0x01;//设定定时器工作方式1,定时器定时50毫秒 TH0=(65536-50000)/256; TL0=(65536-50000)%6; EA=1;//开总中断 ET0=1;//允许定时器0中断 t0_crycle=0;//定时器中断次数计数单元 }

//************************************************** //LED处理函数 void dis_led() {

if(msecond_count<5) {

led1_bit=1; led2_bit=1; } else {

led1_bit=0; led2_bit=0; } }

//*************************************************************** //功能:把数据1显示在数码管1上 void display6(uchar dis_data) {

smg_data=tabl1[dis_data];//送显示断码 dis_bit6=0;//锁存数据 delay_50us(40); dis_bit6=1; }

//*************************************************************** //功能:把数据1显示在数码管1上 void display5(uchar dis_data) {

smg_data=tabl1[dis_data];//送显示断码 dis_bit5=0;//锁存数据 delay_50us(40); dis_bit5=1; }

//*************************************************************** //功能:把数据1显示在数码管1上 void display4(uchar dis_data) {

smg_data=tabl1[dis_data];//送显示断码 dis_bit4=0;//锁存数据 delay_50us(40); dis_bit4=1;

}//*************************************************************** //功能:把数据1显示在数码管1上 void display3(uchar dis_data) {

smg_data=tabl1[dis_data];//送显示断码 dis_bit3=0;//锁存数据 delay_50us(40);

dis_bit3=1; }

//*************************************************************** //功能:把数据1显示在数码管1上 void display1(uchar dis_data) {

smg_data=tabl1[dis_data];//送显示断码 dis_bit1=0;//锁存数据 delay_50us(40); dis_bit1=1; }

//*************************************************************** //功能:把数据1显示在数码管1上 void display2(uchar dis_data) {

smg_data=tabl1[dis_data];//送显示断码 dis_bit2=0;//锁存数据 delay_50us(40); dis_bit2=1; }

//**************************************************************************************************

//函数名称:void delay_50US(unsigned int t) //功能: 延时50*t(us) void delay_50us(uint t) {

unsigned char j; for(;t>0;t--) {

for(j=19;j>0;j--); } }

//*******************************************************************************

//8微秒延时基准程序 void delay_8us(uint t) {

while(--t); }

//******************************************************************************* //3微秒延时程序 void delay_3us() {

; ; }

//*******************************************************************************

//子程序功能:向DS18B20写一字节的数据 void w_1byte_ds18b20(uchar value) {

uchar i=0; for(i=0;i<8;i++) {

dq_ds18b20=1; delay_3us(); dq_ds18b20=0; delay_8us(2);

if (value & 0x01) dq_ds18b20=1; //DQ = 1 delay_50us(1); //延时50us 以上 delay_8us(2); value>>=1; }

dq_ds18b20=1; //DQ = 1 }

//读一个字节

uchar r_1byte_ds18b20(void) {

uchar i=0;

uchar value = 0; for (i=0;i<8;i++) {

value>>=1;

dq_ds18b20=0;// DQ_L; delay_3us();

dq_ds18b20=1; //DQ_H; delay_8us(2);

if(dq_ds18b20==1) value|=0x80; delay_8us(6); //延时40us }

dq_ds18b20=1; return value; }

//;************************************************** //ds18b20复位子程序 void rest_ds18b20(void) {

rest:delay_3us(); //稍做延时 delay_3us(); dq_ds18b20=1; delay_3us();

dq_ds18b20=0;// DQ_L;

delay_50us(11);//480us

if(dq_ds18b20==1) {

return; }

delay_50us(2); //延时90us if(dq_ds18b20==1) {

return; } else {

goto rest; } }

//**************************************************** //读取温度

void readtemp_ds18b20(void) {

uchar temp32; rest_ds18b20();

w_1byte_ds18b20(0xcc); //跳过读序列号的操作 w_1byte_ds18b20(0x44); //启动温度转换 delay_8us(2); rest_ds18b20();

w_1byte_ds18b20(0xcc); //跳过读序列号的操作

w_1byte_ds18b20(0xbe); //读取温度寄存器等(共可读9个寄存器)是温度

templ=r_1byte_ds18b20(); temph=r_1byte_ds18b20();

if((temph&0xf0))//判断温度的正负性 {

temp_flag=0;//温度为负数标志 temph=-temph; templ=-templ;

t_x=tabl3[templ & 0x0f];//计算温度的小数 temp32=temph & 0x0f;

前两个就 temp32<<=4; templ>>=4;

temp32=temp32 | templ;

t_b=temp32/100;//计算温度的百位数据 t_s=temp32/10;//计算温度的十位数据 t_g=temp32;//计算温度的个位数据 }

else//为正数 {

t_x=tabl3[templ & 0x0f];//计算温度的小数 temp32=temph & 0x0f; temp32<<=4; templ>>=4;

temp32=temp32 | templ;

t_b=temp32/100;//计算温度的百位数据 t_s=temp32/10;//计算温度的十位数据 t_g=temp32;//计算温度的个位数据 temp_flag=1; } }

void dis_temp()//温度显示函数 {

if(temp_flag=1) {

if(t_b==0) {

dis(12,12,t_s,t_g,13,12); } else {

dis(12,t_b,t_s,t_g,13,12); } } else {

dis(14,t_b,t_s,t_g,13,12); } }

//;##############################################################################

//;子程序名:w_1byte_ds1302

//;功能: 向DS1302写一个字节的数据 void w_1byte_ds1302(uchar t) {

uchar i;

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

if(t & 0x01)

{io_ds1302=1;} else

{io_ds1302=0;} clk_ds1302=1; delay_3us(); delay_3us(); clk_ds1302=0; delay_3us(); delay_3us(); t>>=1; } }

//;########################################################################

//;子程序名:r_1byte_ds1302()

//;功能: 从DS1302读一个字节的数据 uchar r_1byte_ds1302() {

uchar i,temp11=0;

io_ds1302=1;//置IO为1,准备读入数据 for(i=0;i<8;i++) {

temp11>>=1;

if(io_ds1302) temp11 |= 0x80; clk_ds1302=1; delay_3us(); delay_3us(); clk_ds1302=0; delay_3us(); }

return(temp11); }

//;#################################################################################

//;子程序名:setbds1302

//;功能: 设置DS1302初始时间,并启动计时 void set_ds1302() {

uchar i,j;

rest_ds1302=0;

delay_3us(); clk_ds1302=0; delay_3us(); rest_ds1302=1; delay_3us();

w_1byte_ds1302(0x8e);//写控制命令字 delay_3us();

w_1byte_ds1302(0x00);//写保护关闭 clk_ds1302=1; delay_3us(); rest_ds1302=0;

for(i=0,j=0x80;i<7;i++,j+=2) {

rest_ds1302=0; delay_3us(); clk_ds1302=0; delay_3us(); rest_ds1302=1; delay_3us();

w_1byte_ds1302(j); delay_3us();

w_1byte_ds1302(tab23[i]); delay_3us(); delay_3us(); clk_ds1302=1; delay_3us(); rest_ds1302=0; delay_3us(); delay_3us(); }

rest_ds1302=0; delay_3us(); clk_ds1302=0; delay_3us(); rest_ds1302=1; delay_3us();

w_1byte_ds1302(0x8e); delay_3us();

w_1byte_ds1302(0x80); clk_ds1302=1; delay_3us(); rest_ds1302=0; delay_3us(); }

//;#################################################################-------

//;子程序名:get1302 void get_ds1302() {

uchar temp11[7],i,j; for(i=0;i<7;i++) {temp11[i]=0;}

for(i=0,j=0x81;i<7;i++,j+=2) {

rest_ds1302=0; delay_3us(); clk_ds1302=0; delay_3us(); rest_ds1302=1; delay_3us();

w_1byte_ds1302(j);

temp11[i]=r_1byte_ds1302(); delay_3us(); clk_ds1302=1; delay_3us(); rest_ds1302=0; delay_3us(); }

if(temp11[0]!=0xff)

{second_count=temp11[0];} if(temp11[1]!=0xff)// 数据验证 {minute_count=temp11[1];} if(temp11[2]!=0xff)//数据验证 {hour_count=temp11[2];} // date=temp[3]; //month=temp[4]; // week=temp[5]; //year=temp[6]; }

/*==================================================================== 调试要求:

1.MCU:AT89S52芯片或AT89C52 2.晶振:12MHz

功能:多功能时钟+温度计

====================================================================*/

#include #include

#define uchar unsigned char #define uint unsigned int

sbit dis_bit1=P2^7;//定义数码管控制口 sbit dis_bit2=P2^6;//定义数码管控制口 sbit dis_bit3=P2^4;//定义数码管控制口 sbit dis_bit4=P2^3;//定义数码管控制口 sbit dis_bit5=P2^1;//定义数码管控制口 sbit dis_bit6=P2^0;//定义数码管控制口 sbit led1_bit=P2^2;//定时LED的控制口 sbit led2_bit=P2^5;//定时LED的控制口 sbit s1_bit=P1^0; //定义S1控制口 sbit s2_bit=P1^1; //定义S2控制口 sbit s3_bit=P1^2; //定义S3控制口

sbit dq_ds18b20=P3^3;//定义控制DS18B20 sbit speak=P3^7; //定义蜂鸣器控制口

sbit clk_ds1302=P3^6;//定义控制DS1302的时钟线 sbit io_ds1302=P3^5;//定义控制DS1302的串行数据 sbit rest_ds1302=P3^4;

#define smg_data P0//定义数码管数据口

void delay_3us();//3US的延时程序

void delay_8us(uint t);//8US延时基准程序

void delay_50us(uint t);//延时50*T微妙函数的声明 void display1(uchar dis_data);//数码管1显示子程序 void display2(uchar dis_data);//数码管2显示子程序 void display3(uchar dis_data);//数码管3显示子程序 void display4(uchar dis_data);//数码管4显示子程序 void display5(uchar dis_data);//数码管5显示子程序 void display6(uchar dis_data);//数码管6显示子程序 void init_t0();//定时器0初始化函数 void dis_led();//LED处理函数 void judge_s1();//S1按键处理函数 void judge_s2();//S2按键处理函数 void judge_s3();//S3按键处理函数

void dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1);//显示子程序

void dis_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1,uchar san);//闪烁显示子程序

void judge_dis();//显示处理函数 void judge_clock();//显示处理函数 void set_ds1302();//设置时间

void get_ds1302();//读取当前时间

void w_1byte_ds1302(uchar t);//向DS1302写一个字节的数据 uchar r_1byte_ds1302();//从DS1302读一个字节的数据

//***********************************************************************

//DS18B20测温函数定义

void w_1byte_ds18b20(uchar value);//向DS18B20写一个字节 uchar r_1byte_ds18b20(void);//从DS18B20读取一个字节的数据 void rest_ds18b20(void);//DS18B20复位程序 void readtemp_ds18b20(void);//读取温度 void dis_temp();//温度显示函数

//共阳数码管断码表

const uchar tabl1[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92, // 0 1 2 3 4 5

0x82,0xf8,0x80,0x90,0x86,0x87,0xFF, //6 7 8 9 E T B 0xc6,0xbf,0xff}; // C - const uchar tabl3[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; uchar t0_crycle;

uchar hour_count,minute_count,second_count,msecond_count; uchar clock_hour,clock_minute; uchar countdown_second;

uchar countdown_hour,countdown_minute;

uchar clock_en;//闹钟关闭和开启的标志,1开启,0关闭 uchar flag1,second_flag,zancun1,zancun2,zancun3; uchar zancun4,zancun5,zancun6,zancun7; uchar clock_flag,countdown_flag;

uchar msecond_minute,msecond_second,msecond_msecond,msecond_flag;//秒表相关参数

uint speak_count;

uchar templ,temph,temp_flag;

uchar t_b,t_s,t_g,t_x,temp_flag2;//从左到右分别存储温度百位,十位,个位,小数位

uchar tab23[3];//={0x40,0x59,0x23,0x28,0x11,0x06,0x09};//上电时默认的时间 //主程序 void main()

{

P3=0x00; flag1=0; zancun3=0;

msecond_minute=0;//置秒表相关参数为0 msecond_second=0; msecond_msecond=0; speak=1;//关闭蜂鸣器 speak_count=0; clock_hour=0; clock_minute=0; clock_flag=0;

countdown_flag=0;//倒计时标志位为0 clock_en=0;//开机时默认关闭闹钟 init_t0(); TR0=1;//

// set_ds1302();//设置DS1302的初始时间 //接下来开始编写让数码管显示的程序 while(1) {

get_ds1302();

judge_dis();//显示处理 judge_s1(); judge_s2(); judge_s3();

judge_clock();//闹钟处理程序 } }

void timer0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%6; t0_crycle++; if(t0_crycle==2)// 0.1秒 { t0_crycle=0;

msecond_flag=1; msecond_count++;

if(msecond_count==10)//1秒 {

msecond_count=0; second_flag=1; } }

}

//************************************************** //显示处理函数 void judge_dis() {

if(flag1==0) {

if(second_flag==1) {

zancun7++; second_flag=0; }

if(zancun7<1) {

if(temp_flag2==1) {

readtemp_ds18b20();//读取温度 temp_flag2=0; }

dis_temp();//温度显示函数 }

if(zancun7>=1) {

temp_flag2=1;

zancun4=hour_count&0xf0; zancun4>>=4;

zancun5=minute_count&0xf0; zancun5>>=4;

zancun6=second_count&0xf0; zancun6>>=4;

dis(zancun4,hour_count&0x0f,zancun5,minute_count&0x0f,zancun6,second_count&0x0f);

dis_led();

if(zancun7==5)zancun7=0; } }

if(flag1!=0) {

switch(flag1) {

case 1:

dis(5,10,11,1,12,12);//显示SET1

led1_bit=1; led2_bit=1; break; case 2:

dis(5,10,11,2,12,12);//显示SET2 break; case 3:

dis(5,10,11,3,12,12);//显示SET3 break; case 4:

dis(5,10,11,4,12,12);//显示SET4 break; case 5:

dis(5,10,11,5,12,12);//显示SET5 break; case 6:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,12,1); break; case 7:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,12,2); break; case 8:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,12,3); break;

case 9://进入修改时间,时间分位个位闪烁

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,12,4); break;

case 10://进入修改闹钟,闹钟小时十位闪烁

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,zancun3,1); break;

case 11://进入修改闹钟,闹钟小时个位闪烁

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,zancun3,2); break;

case 12://进入修改闹钟,闹钟小时十位闪烁

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,zancun3,3); break;

case 13://进入修改闹钟,闹钟小时个位闪烁

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,zancun3,4); break;

case 14://进入修改闹钟的开关

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,12,zancun3,6); break; case 15:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,zancun3/10,zancun3,1);

break; case 16:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,zancun3/10,zancun3,2);

break; case 17:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,zancun3/10,zancun3,3);

break; case 18:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,zancun3/10,zancun3,4);

break; case 19:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,zancun3/10,zancun3,5);

break; case 20:

dis_san(zancun1/10,zancun1,zancun2/10,zancun2,zancun3/10,zancun3,6);

break; case 21:

if(second_flag==1) {

second_flag=0;

countdown_second--;

if(countdown_second==255) {

countdown_second=59; countdown_minute--;

if(countdown_minute==255) {

countdown_minute=59; countdown_hour--;

if(countdown_hour==255) {

flag1=22;

countdown_minute=0; countdown_hour=0; countdown_second=0; countdown_flag=1; } } } }

dis(countdown_hour/10,countdown_hour,countdown_minute/10,countdown_minute,countdown_second/10,countdown_second);// break; case 22:

if(countdown_flag>0 && countdown_flag<7) {

speak=0;

if(second_flag==1) {

second_flag=0; countdown_flag++; } } else {

speak=1; }

dis(countdown_hour/10,countdown_hour,countdown_minute/10,countdown_minute,countdown_second/10,countdown_second);// break; case 23:

dis(msecond_minute/10,msecond_minute,msecond_second/10,msecond_second,msecond_msecond,12);

break; case 24:

if(msecond_flag==1) {

msecond_flag=0;

msecond_msecond++;

if(msecond_msecond==10) {

msecond_msecond=0; msecond_second++;

if(msecond_second==60) {

msecond_second=0; msecond_minute++;

if(msecond_minute==100) {

msecond_minute=99; flag1=23; } } } }

dis(msecond_minute/10,msecond_minute,msecond_second/10,msecond_second,msecond_msecond,12); break; case 25:

dis(zancun3/10,zancun3,zancun2/10,zancun2,zancun1/10,zancun1); break; default: break; } } }

//************************************************** //S1按键处理函数 void judge_s1() {

s1_bit=1;//置IO为1,准备读入收据 if(s1_bit==0)//判断是否有按键按下 {

delay_50us(1);// 延时,去除机械抖动 if(s1_bit==0)

{

switch(flag1) {

case 0: case 1: case 2: case 3: case 4: case 6: case 7: case 8: case 10: case 11: case 12: case 13: case 15: case 16: case 17: case 18: case 19:

flag1++; break; case 9:

flag1=6; break; case 14:

flag1=10; break; case 20:

flag1=15; break; case 5: case 21: case 22:

case 23://系统从秒表状态复位 case 24://系统从秒表状态复位 case 25://系统从计数器复位 flag1=0; break; default: break; } while(s1_bit==0) {

judge_dis(); }//等待按键释放 } } }

//************************************************** //S2按键处理函数 void judge_s2() {

s2_bit=1;//置IO为1,准备读入收据 if(s2_bit==0)//判断是否有按键按下 {

delay_50us(1);// 延时,去除机械抖动 if(s2_bit==0) {

switch (flag1) {

case 1: //在显示SET1状态下按S2件,进入修改时间 flag1=6;

zancun4=hour_count&0xf0; zancun4>>=4;

zancun6=hour_count&0x0f; zancun1=zancun4*10+zancun6; //zancun1=hour_count;

zancun5=minute_count&0xf0; zancun5>>=4;

zancun6=minute_count&0x0f; zancun2=zancun5*10+zancun6; // zancun2=minute_count; break;

case 2://在显示SET2状态下按S2,进入设置闹钟 zancun1=clock_hour; zancun2=clock_minute; flag1=10; break;

case 6://修改时钟小时十位状态下按S2件 case 7://修改时钟小时个位状态下按S2件 case 8://修改时钟分钟十位状态下按S2件 case 9://修改时钟分钟个位状态下按S2件 //zancun4=zancun1/10;

tab23[2]=zancun1/10*16+zancun1;

//zancun5=zancun2&0xf0;

//zancun5>>=4;

tab23[1]=zancun2/10*16+zancun2; hour_count=tab23[2]; minute_count=tab23[1]; second_count=0; tab23[0]=0;

set_ds1302();//设置DS1302的初始时间 flag1=0; break;

case 10://修改闹钟小时十位状态下按S2 case 11://修改闹钟小时个位状态下按S2 case 12://修改闹钟分钟十位状态下按S2 case 13://修改闹钟分钟个位状态下按S2 case 14://修改闹钟使能状态下按S2 clock_hour=zancun1; clock_minute=zancun2; clock_en=zancun3; flag1=0; break; case 3:

flag1=15;

zancun1=countdown_hour; zancun2=countdown_minute; zancun3=countdown_second; break; case 15: case 16: case 17: case 18: case 19: case 20:

countdown_hour=zancun1; countdown_minute=zancun2; countdown_second=zancun3; flag1=21;

countdown_flag=0; break; case 22:

flag1=21; break; case 21:

flag1=22; break; case 4:

flag1=23;//秒表暂停 msecond_minute=0; msecond_second=0; msecond_msecond=0; break; case 23:

flag1=24; break; case 24:

flag1=23; break; case 5:

flag1=25;//进入计数器模式 zancun1=0; zancun2=0; zancun3=0; break; default: break; }

while(s2_bit==0) {

judge_dis(); }//等待按键释放 } } }

//************************************************** //S3按键处理函数 void judge_s3() {

s3_bit=1;//置IO为1,准备读入收据 if(s3_bit==0)//判断是否有按键按下 {

delay_50us(1);// 延时,去除机械抖动 if(s3_bit==0) {

switch (flag1) {

case 6://修改时间小时的十位数 zancun1+=10;

if(zancun1>=24)zancun1=zancun1;

break;

case 7://修改时间小时的个位数

zancun1=zancun1/10*10+(zancun1+1); if(zancun1>=24)zancun1=20; break;

case 8://修改时间分钟的十位数 zancun2+=10;

if(zancun2>=60)zancun2-=60; break;

case 9://修改时间分钟的个位数

zancun2=zancun2/10*10+(zancun2+1); break;

case 10://修改闹钟小时的十位数 zancun1+=10;

if(zancun1>=24)zancun1=zancun1; break;

case 11://修改闹钟小时的个位数

zancun1=zancun1/10*10+(zancun1+1); if(zancun1>=24)zancun1=20; break;

case 12://修改闹钟分钟的十位数 zancun2+=10;

if(zancun2>=60)zancun2-=60; break;

case 13://修改闹钟分钟的个位数

zancun2=zancun2/10*10+(zancun2+1); break; case 14:

zancun3^=1; break;

case 15://修改倒计时小时的十位数 zancun1+=10;

if(zancun1>=100)zancun1-=100; break;

case 16: //修改倒计时小时的个位数

zancun1=zancun1/10*10+(zancun1+1); break;

case 17://修改倒计时分钟的十位数 zancun2+=10;

if(zancun2>=60)zancun2-=60; break;

case 18: //修改倒计时分钟的个位数

zancun2=zancun2/10*10+(zancun2+1); break;

本文来源:https://www.bwwdw.com/article/6e77.html

Top