微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 给我看一下这个程序,我怎么做DS1302都记不住时间,,

给我看一下这个程序,我怎么做DS1302都记不住时间,,

时间:10-02 整理:3721RD 点击:
/*共阳数码管加了DS1302的,有DS18B20,调好了!可用的程序*/
/*刘老师的---孙玉龙*/
#include <reg52.h>
#include <intrins.h>
sbit key_2=P3^5;
sbit key_1=P3^7;
sbit SCK=P1^5;  //DS1302
sbit SDA=P1^6;  //DS1302
sbit RST = P1^7;   // DS1302复位
sbit CLKA=P1^2;  
sbit CLKB=P1^3;  
sbit DQ20=P1^4;  //DS18B20
bit ReadRTC_Flag;
unsigned char l_tmpdate[3]={0,0,0};//秒分时08-05-15 12:00:00
unsigned char l_tmpdisplay[6];
unsigned char DS18B20_ma[6];
code unsigned char write_rtc_address[3]={0x80,0x82,0x84}; //秒分时 最低位读写位
code unsigned char read_rtc_address[3]={0x81,0x83,0x85};  
code unsigned char table[]={0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,0xba,0x20,0x28};
       //共阳数码管,码自写
code unsigned char table1[]={0xbf,0xdf,0xf7,0x7f,0xfd,0xfe,};
                     //显示位码表
unsigned char count_cent,count_sec,count_hour,count; //
unsigned int i,num,key_1i,key_2i,key_2j; //
unsigned char temperature=0; //
void delay(unsigned int us)
{
while(us--);
}
void Write_Ds1302_Byte(unsigned  char temp)
{
unsigned char i;
ET0=0;
for (i=0;i<8;i++)      //循环8次 写入数据
{
  SCK=0;
  SDA=temp&0x01;      //每次传输低字节
  temp>>=1;    //右移一位
  SCK=1;
}
ET0=1;
}   
/****************************************************************************/
void Write_Ds1302( unsigned char address,unsigned char dat )     
{
  RST=0;
_nop_();
  SCK=0;
_nop_();
  RST=1;
    _nop_();   //启动
  Write_Ds1302_Byte(address); //发送地址
  Write_Ds1302_Byte(dat);  //发送数据
  RST=0;    //恢复
}
/****************************************************************************/
unsigned char Read_Ds1302 ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0;
_nop_();
SCK=0;
_nop_();
RST=1;
_nop_();
Write_Ds1302_Byte(address);
ET0=0;
for (i=0;i<8;i++)   //循环8次 读取数据
{  
  if(SDA)
   temp|=0x80;   //每次传输低字节
  SCK=0;
  temp>>=1;   //右移一位
  SCK=1;
}
ET0=1;
RST=0;
_nop_();  //以下为DS1302复位的稳定时间
RST=0;
SCK=0;
_nop_();
SCK=1;
_nop_();
SDA=0;
_nop_();
SDA=1;
_nop_();
return (temp);   //返回
}
/****************************************************************************/
void Read_RTC(void)  //读取 日历
{
unsigned char i,*p;
p=read_rtc_address;  //地址传递
for(i=0;i<3;i++)  //分3次读取 秒分时日月周年
{
  l_tmpdate[i]=Read_Ds1302(*p);
  p++;
}
}
/***********************************************************************/
void Set_RTC(void)  //设定 日历
{
unsigned char i,*p,tmp;
for(i=0;i<3;i++)
{           //BCD处理
  tmp=l_tmpdate[i]/10;
  l_tmpdate[i]=l_tmpdate[i]%10;
  l_tmpdate[i]=l_tmpdate[i]+tmp*16;
}
Write_Ds1302(0x8E,0X00); //给ds1302写一个数据

p=write_rtc_address; //传地址
for(i=0;i<3;i++)  //3次写入 秒分时
{
  Write_Ds1302(*p,l_tmpdate[i]);
  p++;  
}
Write_Ds1302(0x8E,0x80);
}
//------------------------------------------------------------//
//-----------------ds18b20的初始化----------------------------//
//------------------------------------------------------------//
void init_DS18B20()
{
bit X=0;
DQ20=1;
delay(20);
DQ20=0;
delay(480);
DQ20=1;
delay(4);
X=DQ20;
delay(20);
}
//------------------------------------------------------------//
//---------------用于读ds18b20的温度--------------------------//
//------------------------------------------------------------//
read_DS18B20()
{
unsigned char i,dat=0;
ET0=0;
for (i=0;i<8;i++)
{
  DQ20=0;
  dat>>=1;
  DQ20=1;
  if(DQ20)
   dat|=0x80;
  delay(5);
}
ET0=1;
return(dat);
}
//------------------------------------------------------------//
//---------------用于给ds18b20写读温度指令--------------------//
//------------------------------------------------------------//
void write_DS18B20(unsigned char dat)
{
char i;ET0=0;
for (i=0;i<8;i++)
{
  DQ20=0;
  DQ20=dat&0x01;
  delay(5);
  DQ20=1;
  dat>>=1;
}ET0=1;
delay(4);
}
//------------------------------------------------------------//
//-----------------用于ds18b20读数据与写指令------------------//
//------------------------------------------------------------//
void DS18B20_()
{
unsigned char tempL,tempH;
init_DS18B20();
write_DS18B20(0xcc);
write_DS18B20(0x44);
init_DS18B20();
write_DS18B20(0xcc);
write_DS18B20(0xbe);
tempL=read_DS18B20();
tempH=read_DS18B20();
temperature=(tempL>>4)|(tempH<<4);
}
void tim(void) interrupt 1 using 1//中断,用于数码管扫描
{
unsigned char tmp;
TH0=0xfc;//初始化值
TL0=0x18;
  if(key_2j==1&&i==0)
   P0=table[l_tmpdisplay[i]]&0xdf;  //为显示小数点用
  else if(key_2j==2&&i==2)
   P0=table[l_tmpdisplay[i]]&0xdf;  //为显示小数点用
  else if(key_2j==3&&i==4)
   P0=table[l_tmpdisplay[i]]&0xdf;  //为显示小数点用
  else if(i==1&&!key_2j)
   P0=table[l_tmpdisplay[i]]&0xdf;  //为显示小数点用
  else
   P0=table[l_tmpdisplay[i]];  //查表法得到要显
示数字的数码段
  CLKA=1;
  CLKA=0;
  P2=table1[i];
  CLKB=1;
  CLKB=0;
i++;
if(i==6)
{
  i=0;
  num++;
  if(10==num)       //隔段时间读取1302的数据。时间间隔可以调整
  {
   ReadRTC_Flag=1; //使用标志位判断
   num=0;
  }
}
if(key_1==0)  //这if为调时用
{
  key_1i++;
  if(key_1i==10)
  {
   if(key_2j==0)
   {
    l_tmpdisplay[4]=temperature/10; //ds18b20专用
    l_tmpdisplay[5]=temperature%10; //ds18b20专用
   }
   if(key_2j==1)
   {
    count_hour++;
    if(count_hour==24)count_hour=0;
    count=count_hour;
    tmp=count/10;
    count=count%10;
    count=count+tmp*16;
    Write_Ds1302(0x8E,0X00); //给ds1302写一个数据
    Write_Ds1302(0x84,count);//给ds1302写一个小时数

    Write_Ds1302(0x8E,0x80);
   }
   if(key_2j==2)
   {
    count_sec++;
    if(count_sec==60)count_sec=0;
    count=count_sec;
    tmp=count/10;
    count=count%10;
    count=count+tmp*16;
    Write_Ds1302(0x8E,0X00); //给ds1302写一个数据
    Write_Ds1302(0x82,count);//给ds1302写一个分钟数

    Write_Ds1302(0x8E,0x80);
   }
   if(key_2j==3)
   {
    count_cent++;
    if(count_cent==60)count_cent=0;
    count=count_cent;
    tmp=count/10;
    count=count%10;
    count=count+tmp*16;
    Write_Ds1302(0x8E,0X00); //给ds1302写一个数据
    Write_Ds1302(0x80,count);//给ds1302写一个分钟数

    Write_Ds1302(0x8E,0x80);
   }
  }
  if(key_1i==60000)key_1i=20001;
}
else
  key_1i=0;
if(key_2==0)  //这if为调时位选
{
  key_2i++;
  if(key_2i==10)
  {
   key_2j++;
   if(key_2j==4)key_2j=0;
  }
  if(key_2i==60000)key_2i=20001;
}
else key_2i=0;
}
void main(void)   
{
TMOD=0x01;//定时器设置 16位
TH0=0xfc;//初始化值
TL0=0x18;
EA=1;
ET0=1;
TR0=1;
  //Set_RTC();
while(1)
{
  DS18B20_();
  if(ReadRTC_Flag)  //以下为显示哦!
  {
   ReadRTC_Flag=0;
   Read_RTC();
   l_tmpdisplay[0]=l_tmpdate[2]/16;   
//数据的转换,因我们采用数码管0~9的显示,将数据分开
   l_tmpdisplay[1]=l_tmpdate[2]&0x0f;
   //l_tmpdisplay[2]=10;      
    //加入"-"
   l_tmpdisplay[2]=l_tmpdate[1]/16;
   l_tmpdisplay[3]=l_tmpdate[1]&0x0f;
   //l_tmpdisplay[5]=10;
   if(key_1)
   {
    l_tmpdisplay[4]=l_tmpdate[0]/16;
    l_tmpdisplay[5]=l_tmpdate[0]&0x0f;
   }
   count_hour=l_tmpdisplay[0]*10+l_tmpdisplay[1];  
//用于掉用显示调时小时数
   count_sec =l_tmpdisplay[2]*10+l_tmpdisplay[3];  
//用于掉用显示调时分钟数
   count_cent=l_tmpdisplay[4]*10+l_tmpdisplay[5];
  }
}
}

这个程序在单片机一上电就DS1302的时间就变了,,硬件我是看了的,,没什么问题


一上电应该就是你在软件里面设置的初始值,如果没有电源维持,1302就复位,不工作了

你第一次初始化时间后 是不是以后都不用初始化了?

电路图上没电池,,不过我的板子上有电池,,是接好了的,,,可能是初始化的问题

对啊,,以后都没用了,,

用小编的改了下,不走时

太乱了

上电应该就是你在软件里面设置的初始值,如果没有电源维持,1302就复位,不工作了

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top