搜索
bottom↓
回复: 16

在线等啊:DS1302的写入读出问题

[复制链接]
头像被屏蔽

出0入0汤圆

发表于 2013-1-31 10:40:02 | 显示全部楼层 |阅读模式
提示: 作者被禁止或删除 内容自动屏蔽

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
头像被屏蔽

出0入0汤圆

 楼主| 发表于 2013-1-31 12:26:46 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2013-1-31 10:40:03 | 显示全部楼层
建议用仿真器和示波器跟踪一下。
头像被屏蔽

出0入0汤圆

 楼主| 发表于 2013-1-31 12:32:52 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2013-1-31 12:34:04 | 显示全部楼层
观察下波形看和期望的一样不。

出0入0汤圆

发表于 2013-1-31 12:39:34 | 显示全部楼层
把你的电路图贴出来看看,

出0入0汤圆

发表于 2013-1-31 13:11:08 | 显示全部楼层
          /************ DS1302实时时钟芯片操作 **************/
//底层驱动函数
/*******************************************************************************
函数名:DS1302_w_bit()
功  能:向DS1302写入一个字节数据/指令(没有RST操作)
参  数:byte --- 欲写入的数据/指令内容
返回值:无
/******************************************************************************/
void  DS1302_w_bit(unchar byte)
{
   unchar i;
   for(i=0;i<8;i++)                           //8位数据计数
   {
     PORTB &= (~BIT(0));          //拉低时钟端,准备写入数据
     if(byte&0x01)                      //当前位是否是1
      {
        PORTB|=BIT(1);        //是1,拉高数据端
      }
     else                                                  
      {
        PORTB &= (~BIT(1));   //不是1而是0,拉低数据端
      }  
     delayus(5);                          //延时,调整时钟和脉冲宽度
     PORTB|=BIT(0);                  //时钟上升沿(DS1302采样数据)
     byte>>=1;                                  //数据右移1位,为送出新数据位做准备
   }
}
/*******************************************
函数名:DS1302_r_bit()
功  能:从DS1302读出一个字节数据(没有RST操作)
参  数:无
返回值:byte --- 读出的数据内容
/********************************************/
unchar  DS1302_r_bit(void)
{
   unchar i,byte=0;
   DDRB &= (~BIT(1));              //将数据端口设置为输入                  
   PORTB &= (~BIT(1));              //无上拉电阻
   for(i=0;i<8;i++)                          //8位数据计数
     {
       byte>>=1;                            //保存读入的数据位
       PORTB|=BIT(0);              //时钟上升沿
       delayus(5);                          //延时,调整时钟脉冲宽度
       PORTB &= (~BIT(0));    //时钟下降沿,DS1302输出数据位
       delayus(5);                          //等待数据变化
       if(PINB&BIT(1))        //当前位是否是高电平
        {
          byte|=BIT(7);              //是高电平就将返回数据的当前位置1
        }
       else
        {
          byte &= (~BIT(7));  //是低电平就将返回数据的当前位置0
        }
     }
   DDRB|=BIT(1);                      //最后将数据端口设置为输出
return byte;                                  //返回读出的数据
}
/*******************************************************************************
函数名:DS1302_write()
功  能:向DS1302的某个地址写入一个字节数据
参  数:addr -- 欲写入的地址
           data -- 欲写入的数据
返回值:无
/********************************************/
void  DS1302_write(unchar addr,unchar data)
{
   PORTB &= (~BIT(2));              //拉低片选端
   PORTB &= (~BIT(0));              //拉低时钟端
   delayus(5);
   PORTB|=BIT(2);                  //拉高片选端
   delayus(5);                               //调整片选脉冲
   DS1302_w_bit(addr);              //写入操作命令(地址)
   delayus(5);
   PORTB &= (~BIT(0));              //拉低时钟端
   delayus(5);
   DS1302_w_bit(data);              //写入数据
   PORTB &= (~BIT(0));              //拉低时钟端
   delayus(5);                              //调整片选脉冲
   PORTB &= (~BIT(2));              //拉低片选端
}
/*******************************************
函数名:DS1302_read()
功  能:从DS1302的某个地址读出一个字节数据
参  数:addr -- 地址值(寄存器或RAM)
返回值:data -- 读出的数据
/********************************************/
unchar DS1302_read(unchar addr)
{
   unchar data;
   PORTB &= (~BIT(2));              //拉低片选端
   PORTB &= (~BIT(0));              //拉低时钟端
   delayus(5);
   PORTB|=BIT(2);                  //拉高片选端
   delayus(5);                               //调整片选脉冲
   DS1302_w_bit(addr);              //写入操作命令(地址)
   delayus(5);
   data=DS1302_r_bit();              //读出数据
   delayus(5);
   PORTB &= (~BIT(0));        //拉低时钟端
   PORTB &= (~BIT(2));               //拉低片选端
   return data;                              //返回读出的数据
}
/*******************************************************************************
函数名:DS1302_Init()
功  能:初始化DS1302芯片
参  数:无
返回值:无
/******************************************************************************/
void  DS1302_Init()
{
   DS1302_write(0x8E,0x00);   //控制命令,WP位为0,允许写操作
   delayms(5);               
   DS1302_write(0x8C,0x09);   //写入年份09年
   delayms(1);
   DS1302_write(0x8A,0x06);   //写入星期5
   delayms(1);
   DS1302_write(0x88,0x10);   //写入月份10月
   delayms(1);
   DS1302_write(0x86,0x31);   //写入日期31日
   delayms(1);
   DS1302_write(0x84,0x15);   //写入小时15点
   delayms(1);
   DS1302_write(0x82,0x06);   //写入分钟06分
   delayms(1);
   DS1302_write(0x90,0xA5);   //涓流充电
   delayms(1);
   DS1302_write(0x80,0x00);   //写入秒00,开始走时
   DS1302_write(0x8E,0x80);   //控制命令,WP位为1,允许写操作
}  
/*******************************************************************************
函数名:time_get()
功  能:从DS1302芯片里读取时间数据
参  数:无
返回值:无
/******************************************************************************/
void  time_get()
{
   int a,b;                   //定义一下,用于数据处理
   year = DS1302_read(0x8D);  //读取年份数据
   xq = DS1302_read(0x8B);    //读取星期数据
   month = DS1302_read(0x89); //读取月份数据
   day = DS1302_read(0x87);   //读取日期数据
   hour = DS1302_read(0x85);  //读取小时数据
   min = DS1302_read(0x83);   //读取分钟数据
   sec = DS1302_read(0x81);   //读取秒钟数据
//BCD码转换成十进制数
//年
   a = (year&0xF0)>>4;        //转换十位
   b = year&0x0F;             //转换个位
   year = a*10+b;
//月
   a = (month&0xF0)>>4;       //转换十位
   b = month&0x0F;            //转换个位
   month = a*10+b;
//日
   a = (day&0xF0)>>4;         //转换十位
   b = day&0x0F;              //转换个位
   day = a*10+b;
//时
   a = (hour&0xF0)>>4;        //转换十位
   b = hour&0x0F;             //转换个位
   hour = a*10+b;             //汇总
//分
   a = (min&0xF0)>>4;         //转换十位
   b = min&0x0F;              //转换个位
   min = a*10+b;              //汇总
//秒
   a = (sec&0xF0)>>4;         //转换十位
   b = sec&0x0F;              //转换个位
   sec = a*10+b;              //汇总
}

出0入0汤圆

发表于 2013-1-31 13:13:19 | 显示全部楼层
            /**************** 初始化端口操作 *************/
/*******************************************************************************
函数名:Port_Init()
功  能:端口初始化设置
参  数:无
返回值:无
/******************************************************************************/
void  Port_Init()
{
   DDRD |= BIT(2)|BIT(3)|BIT(4);//初始化液晶端口
   DDRB |= BIT(0)|BIT(1)|BIT(2);//初始化DS1302端口
   DDRD |= BIT(0);              //初始化DS1820总线端口
   DDRD &= (~BIT(7))&(~BIT(6))&(~BIT(5));
   DDRC &= (~BIT(0));           //设置按键端口为输入
}

出0入0汤圆

发表于 2013-1-31 13:13:44 | 显示全部楼层
1.实时时钟芯片DS1302与MCU接口
            MCU --- DS1302
                    PB0 --- SCLK;
                    PB1 --- I/O;
                    PB2 --- REST;
头像被屏蔽

出0入0汤圆

 楼主| 发表于 2013-1-31 13:47:11 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
头像被屏蔽

出0入0汤圆

 楼主| 发表于 2013-1-31 15:33:05 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
头像被屏蔽

出0入0汤圆

 楼主| 发表于 2013-1-31 15:43:26 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2013-1-31 18:51:35 | 显示全部楼层
gudujiangone 发表于 2013-1-31 15:43
谢谢你。谢谢你的热心帮助。我鼓捣出来了。

多鼓捣鼓捣吧。

出0入0汤圆

发表于 2013-1-31 21:13:43 | 显示全部楼层
gudujiangone 发表于 2013-1-31 13:47
PORTC 5,6,7分别是SCLK,IO,RESET

我不是看不懂你的程序,我是担心你硬件连接有问题,硬件问题还不透露电路图,自己慢慢捣鼓吧……
头像被屏蔽

出0入0汤圆

 楼主| 发表于 2013-2-1 09:08:00 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2013-2-1 09:13:10 | 显示全部楼层
经验都是鼓捣出来的。

出255入0汤圆

发表于 2013-2-1 09:43:15 | 显示全部楼层
用protues就可以了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 07:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表