打印

DS1302相关问题,请赐教

[复制链接]
1414|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
keny616|  楼主 | 2008-11-18 18:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
TE, ni, AD, LED, TI
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit CLK_1302 = P3^5;
sbit DIO_1302 = P3^6;
sbit RST_1302  = P3^7;
sbit  K1 = P1^0;
sbit  K2 = P1^1;
sbit  K3 = P1^2;
sbit  K4 = P1^3;
sbit  P2_7=P2^7;
uchar  shift; 
uchar code seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,  
                  0x7d,0x07,0x7f,0x6f,0x40,0x00};
uchar data disbuf[6];
uchar init [] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00};  
uchar init1[] ={0x00,0x00};
/******************************************************************/
void delay_10us(uchar n)
{
 do
 {
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 }
 while(n--);
}

void delay_ms(uint n)
{
do
delay_10us(131);
while(n--);
}
/**********************************************************/

/*底层函数,写1B数据到1302

/**********************************************************/
void write_byte(uchar inbyte)
{
   uchar i;
   for(i=0;i<8;i++)
   {
    CLK_1302=0;             //写的时候低电平改变数据
    if(inbyte&0x01)
    DIO_1302=1;
    else
    DIO_1302=0; 
    CLK_1302=1;            //写的时候高电平,把数据写入ds1302
    _nop_();
    inbyte=inbyte>>1;
   }
}
/**********************************************************/

/*底层函数,从1302读1B数据

/**********************************************************/
uchar read_byte()    //sclk的下跳沿读数据
{
   uchar i,ch=0; 
   DIO_1302=1;                //设置为输入口
   for(i=0;i<7;i++)
   {
    CLK_1302=0;
    if(DIO_1302==1)
    ch=ch|0x80;
    else
    ch=ch&0x7f;
    CLK_1302=1;             //产生下跳沿
    
    ch=ch>>1;
   }
   return (ch);
}

/**********************************************************/
/* 往ds1302的某个地址写入数据 
/**********************************************************/
void write_ds1302(uchar cmd,uchar indata)
{
   CLK_1302=0;
   RST_1302=1;
   write_byte(cmd);        
   write_byte(indata);
   
   CLK_1302=0;
   RST_1302=0;
}

/**********************************************************/
/* 读ds1302某地址的的数据 
/**********************************************************/
uchar read_ds1302(uchar addr)
{
   uchar backdata;
   CLK_1302=0;
   RST_1302=1;

   write_byte(addr);      //先写地址
   backdata=read_byte();  //然后读数据
  
   CLK_1302=0;
   RST_1302=0;
   return (backdata);
}

/**********************************************************/
/* 设定值写入DS1302
/**********************************************************/
void  Set_W1302(uchar addr)
{
   uchar  temp;
   write_ds1302(0x8e,0x00);
   temp=(init1[0]<<4)+init1[1];
   write_ds1302(addr,temp); 
   write_ds1302(0x8e,0x80);
}

/**********************************************************/
/* 读取当前时间 
/**********************************************************/
void read_nowtime(uchar addr,uchar *p,uchar n)
{
  for(;n>0;n--)
  {
    *p=read_ds1302(addr);
    p++;
    addr=addr+2;
  } 
}

/*********************************************************/
/* LED显示函数
/*********************************************************/
void display_led(uchar t)
{
 uchar i,temp;
 P2=0x00;
 SCON=0x00;
 temp=0x7f;                //led显示
 SBUF=temp;
 while(!TI);TI=0;
 for(i=0;i<6;i++)
 {
 P2=seg[disbuf];
 delay_ms(t);
 if(temp==0xfd) break;
 P2=0x00;
 temp=temp<<7|temp>>1;
 SBUF=temp;
 while(!TI);TI=0;
 }
 P2=0x00; 
 temp=0xef;
  SBUF=temp;
 while(!TI);TI=0;
 for(i=0;i<3;i++)     //显示点,用于隔开分时秒,年月日
 {
 P2_7=1;
 delay_ms(t);
 P0=0x00;
 temp=temp<<2|temp>>6;
 SBUF=temp;
 while(!TI);TI=0;
 }     
  }
/*********************************************************/
/* LED时间数据送入缓冲器
/*********************************************************/
void display_led_clk(void)
{
read_nowtime(0x81,init,3);        //读出当前时间,读出7个字节
disbuf[0]=(init[2]&0xf0)>>4;
disbuf[1]=init[2]&0x0f;              //时分秒
disbuf[2]=(init[1]&0xf0)>>4;
disbuf[3]=init[1]&0x0f;
disbuf[4]=(init[0]&0xf0)>>4;
disbuf[5]=init[0]&0x0f;
}
/*********************************************************/
/* LED日期数据送入缓冲器
/*********************************************************/
void display_led_date(void)
{
init[6]=read_ds1302(0x87);
disbuf[4]=(init[6]&0xf0)>>4;
disbuf[5]=init[6]&0x0f;
init[4]=read_ds1302(0x89);
disbuf[2]=(init[4]&0xf0)>>4;    //年月日
disbuf[3]=init[4]&0x0f;
init[3]=read_ds1302(0x8d);
disbuf[0]=(init[3]&0xf0)>>4;
disbuf[1]=init[3]&0x0f;
}
/*********************************************************/
/* LED星期数据送入缓冲器
/*********************************************************/
void display_led_week(void)
{
uchar i;
init[5]=read_ds1302(0x8b);
for(i=0;i<5;i++)
disbuf=10;
disbuf[5]=init[5]&0x0f;              //周
}
/**********************************************************/
/*主函数
/**********************************************************/
void main()
{  
 
   P2=0x00;
   SCON=0x00;
   while(1)
   {
    if(!K1)
    delay_ms(10);
    if(!K1)
    shift++;
    while(!K1);
    if(shift==3)
    shift=0;
    switch(shift)
    {
    case 0:
      display_led_clk();
        display_led(1);
      break;
    case 1:
      display_led_date();
      display_led(1);
      break;
    case 2:
      display_led_week();
      display_led(1);
      break;

    }                   

    }
}
上面程序是实现数字时钟,及年月日,周切换显示
在proteus上,可以仿真。可是硬件不能实现
会不会是DS1302那时序出了问题。
请大侠指点,谢谢啦!~~


相关帖子

沙发
xhtxzxw| | 2008-11-19 02:22 | 只看该作者

嘿嘿

没仔细看,不过read_byte()函数里面 ch = ch>>1;这一行的位置不对吧?
放在现在这个位置, ch的最高位肯定就是0啦! 不应该吧???

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

6

帖子

0

粉丝