花了两天时间才算写出来吧,借鉴了其他人的(闪烁一开始真没想到什么好办法),不多说上代码,代码有一点小问题,就是设置时钟时,加1功能有bug,想了好长时间想不出来,如有知道的麻烦给我讲讲,一起进步哈哈!
main.C
#include "reg52.h"
#include "onewire.h"
#include "ds1302.h"
#include "intrins.h"
#define uchar unsigned char
sfr AUXR=0x8e;
sbit s4=P3^3;
sbit s5=P3^2;
sbit s6=P3^1;
sbit s7=P3^0;
sbit L1=P0^0;
uchar code read_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
uchar code write_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
uchar time[7]={0x55,0x59,0x23,0x00,0x00,0x00,0x00};//秒,分,时,日,月,星期,年
uchar code smgduanma[19]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,
0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f,0xff};//0~f;-;.;全灭
uchar temp=0; //温度
uchar h=0; //闹钟的时分秒
uchar m=0;
uchar s=0;
uchar clock=0; //时钟设置的时分秒标志位
uchar alarm=0; //闹钟设置的时分秒标志位
uchar ms0=0,ms1=0; //定时器0,50毫秒计数,定时器1,50毫秒计数
bit flash=0; //时钟设置,闹钟设置闪烁标志位; =1闪烁
bit led=1;
uchar smg_state=0; //数码管显示状态; =0显示时间; =1显示闹钟
void select573(uchar n)
{
switch(n)
{
case 0:
P2=(P2 & 0x1f) | 0x00;
break;
case 4:
P2=(P2 & 0x1f) | 0x80;
break;
case 5:
P2=(P2 & 0x1f) | 0xa0;
break;
case 6:
P2=(P2 & 0x1f) | 0xc0;
break;
case 7:
P2=(P2 & 0x1f) | 0xe0;
break;
}
}
void delaysmg(uchar t)
{
while(t--);
}
void display_onesmg(uchar value,uchar pos)
{
select573(7);
P0=0xff;
select573(6);
P0=0x01 << pos;
select573(7);
P0=value;
}
void close_allsmg(uchar value)
{
select573(6);
P0=0xff;
select573(7);
P0=value;
}
void display_time()
{
if((clock == 1) && (flash == 1))
{
display_onesmg(smgduanma[18],0);
display_onesmg(smgduanma[18],1);
}
else
{
display_onesmg(smgduanma[time[2]/16],0);
delaysmg(100);
display_onesmg(smgduanma[time[2]%16],1);
delaysmg(100);
}
display_onesmg(smgduanma[16],2);
delaysmg(100);
if((clock == 2) && (flash == 1))
{
display_onesmg(smgduanma[18],3);
display_onesmg(smgduanma[18],4);
}
else
{
display_onesmg(smgduanma[time[1]/16],3);
delaysmg(100);
display_onesmg(smgduanma[time[1]%16],4);
delaysmg(100);
}
display_onesmg(smgduanma[16],5);
delaysmg(100);
if((clock == 3) && (flash == 1))
{
display_onesmg(smgduanma[18],6);
display_onesmg(smgduanma[18],7);
}
else
{
display_onesmg(smgduanma[time[0]/16],6);
delaysmg(100);
display_onesmg(smgduanma[time[0]%16],7);
delaysmg(100);
}
close_allsmg(0xff);
}
void display_alarm()
{
if((alarm == 1) && (flash == 1))
{
display_onesmg(smgduanma[18],0);
display_onesmg(smgduanma[18],1);
}
else
{
display_onesmg(smgduanma[h/10],0);
delaysmg(100);
display_onesmg(smgduanma[h%10],1);
delaysmg(100);
}
display_onesmg(smgduanma[16],2);
delaysmg(100);
if((alarm == 2) && (flash == 1))
{
display_onesmg(smgduanma[18],3);
display_onesmg(smgduanma[18],4);
}
else
{
display_onesmg(smgduanma[m/10],3);
delaysmg(100);
display_onesmg(smgduanma[m%10],4);
delaysmg(100);
}
display_onesmg(smgduanma[16],5);
delaysmg(100);
if((alarm == 3) && (flash == 1))
{
display_onesmg(smgduanma[18],6);
display_onesmg(smgduanma[18],7);
}
else
{
display_onesmg(smgduanma[s/10],6);
delaysmg(100);
display_onesmg(smgduanma[s%10],7);
delaysmg(100);
}
close_allsmg(0xff);
}
void display_temp()
{
display_onesmg(smgduanma[temp/10],5);
delaysmg(100);
display_onesmg(smgduanma[temp%10],6);
delaysmg(100);
display_onesmg(smgduanma[12],7);
delaysmg(100);
close_allsmg(0xff);
}
void initsystem() //初始化系统
{
select573(4);
P0=0xff;
select573(5);
P0=0x00;
select573(0);
}
void set_time() //设置时间
{
uchar i=0;
Write_Ds1302_Byte(0x8e,0x00);
for(i=0;i<7;i++)
{
Write_Ds1302_Byte(write_address[i],time[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
void read_time() //读取DS1302上的时间
{
uchar i=0;
for(i=0;i<7;i++)
{
time[i]=Read_Ds1302_Byte(read_address[i]);
}
}
void initt0() //定时器0,方式一,50毫秒
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD = 0x11; //设置定时器模式
TL0 = (65535 - 50000) % 256; //设置定时初值
TH0 = (65535 - 50000) / 256; //设置定时初值
TF0 = 0; //清除TF0标志
EA=1;
ET0=1;
TR0=0;
}
void servicet0() interrupt 1
{
TL0 = (65535 - 50000) % 256;
TH0 = (65535 - 50000) / 256;
ms0++;
if(ms0 % 4 == 0) //定时0.2秒
{
led = ~led;
}
if(ms0 == 100) //定时5秒
{
ms0=0;
led=1;
TR0=0;
select573(4);
P0=0xff;
select573(0);
}
}
void led_flash() //闹钟时间led闪烁
{
if((time[2] == h) && (time[1] == m) && (time[0] == s))
{
TR0=1;
}
select573(4);
L1 = led;
}
void initt1() //定时器1,方式一,50毫秒
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD = 0x11; //设置定时器模式
TL1 = (65535 - 50000) % 256; //设置定时初值
TH1 = (65535 - 50000) / 256; //设置定时初值
TF1 = 0; //清除TF1标志
EA=1;
ET1=1;
TR1 = 0; //定时器1开始计时
}
void servicet1() interrupt 3
{
TL1 = (65535 - 50000) % 256;
TH1 = (65535 - 50000) / 256;
ms1++;
if(ms1 == 10)
{
flash = ~flash;
ms1=0;
}
}
void scanner_s7()
{
if(s7 == 0)
{
delaysmg(100);
if(s7 == 0)
{
TR0 = 0;
led = 1;
if(alarm == 0)
{
switch(clock)
{
case 0:
clock=1;TR1=1;break; //设置时,打开计时器1中断,
case 1:
clock=2;break;
case 2:
clock=3;break;
case 3:
clock=0;TR1=0;break; //显示时间,关闭计时器1中断;
}
}
while(s7 == 0)
{
display_time();
}
}
}
}
void scanner_s6()
{
if(s6 == 0)
{
delaysmg(100);
if(s6 == 0)
{
TR0=0;
led=1;
if(clock == 0)
{
switch(alarm)
{
case 0:
smg_state=1;;alarm=1;TR1=1;break;
case 1:
alarm=2;break;
case 2:
alarm=3;break;
case 3:
smg_state=0;alarm=0;TR1=0;break;
}
while(s6 == 0)
{
display_alarm();
}
}
}
}
}
void scanner_s5()
{
if(s5 == 0)
{
delaysmg(100);
if(s5 == 0)
{
TR0=0;
led=1;
if((clock != 0) && (smg_state == 0))
{
if(clock == 1)
{
time[2]++;
if((time[2] / 16) * 10 + (time[2] % 16) == 24) {time[2]=0;}
}
else if(clock == 2)
{
time[1]++;
if((time[1] / 16) * 10 + (time[1] % 16) == 60) {time[1]=0;}
}
else if(clock == 3)
{
time[0]++;
if((time[0] / 16) * 10 + (time[0] % 16) == 60) {time[1]=0;}
}
while(s5 == 0)
{
display_time();
}
set_time();
}
if((alarm != 0) && (smg_state == 1))
{
if(alarm == 1)
{
h++;
if(h == 24) {h=0;}
}
else if(alarm == 2)
{
m++;
if(m == 60) {m=0;}
}
else if(alarm == 3)
{
s++;
if(s == 60) {s=0;}
}
while(s5 == 0)
{
display_alarm();
}
}
}
}
}
void scanner_s4()
{
if(s4 == 0)
{
delaysmg(100);
if(s4 == 0)
{
TR0=0;
led=1;
if((smg_state == 0) && (clock == 0))
{
temp=read_temp();
while(s4 == 0)
{
display_temp();
}
}
else if((smg_state == 0) && (clock != 0))
{
if(clock == 1)
{
if(time[2] > 0)
{
time[2]--;
}
}
else if(clock == 2)
{
if(time[1] > 0)
{
time[1]--;
}
}
else if(clock == 3)
{
if(time[0] > 0)
{
time[0]--;
}
}
while(s4 == 0)
{
display_time();
}
set_time();
}
else if((smg_state == 1) && (alarm != 0))
{
if(alarm == 1)
{
if(h > 0)
{
h--;
}
}
else if(alarm == 2)
{
if(m > 0)
{
m--;
}
}
else if(alarm == 3)
{
if(s > 0)
{
s--;
}
}
while(s4 == 0)
{
display_alarm();
}
}
}
}
}
void main()
{
initsystem();
initt0();
initt1();
set_time();
while(1)
{
if((smg_state == 0)&&(clock == 0)) //只在时钟显示时,读取当前时间
{
read_time();
}
switch(smg_state)
{
case 0:
display_time(); //显示时钟
break;
case 1:
display_alarm(); //显示闹钟
break;
}
scanner_s7();
scanner_s6();
scanner_s5();
scanner_s4();
led_flash();
}
}
ds1302.h
#ifndef __DS1302_H
#define __DS1302_H
void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
#endif
ds1302.c
#include <reg52.h>
#include <intrins.h>
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST = P1^3; // DS1302复位
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK=0;
SDA=temp&0x01;
temp>>=1;
SCK=1;
}
}
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
RST=0;
}
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}
owewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
unsigned char rd_temperature(void); //; ;
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
unsigned char read_temp();
#endif
onewire.c
#include "reg52.h"
sbit DQ = P1^4; //单总线接口
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
while(t--);
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
unsigned char read_temp()
{
unsigned char low=0,higt=0;
unsigned char T=0;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay_OneWire(1000);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
low=Read_DS18B20();
higt=Read_DS18B20();
T=(higt << 8) | low;
if((T & 0xf800) == 0x0000)
{
T=T >> 4;
}
return T;
}