51单片机ds1302怎么读到的数据跟自己写入的不一样。

[复制链接]
3449|7
juexin123456 发表于 2025-9-9 17:30 | 显示全部楼层 |阅读模式
大佬们好,我正在学习51单片机,使用的是89c52,使用的是普中科技的开发版,学到DS1302这里,我想在lcd读取我的写数据,写入的数据是0X03,但是运行后lcd显示的是128,应该显示003,大佬们帮忙看看我写的代码哪里出问题了,我先写了DS1302读写代码,模块化后,再主程序里面的调用。我就想实现,我写入数据0X03,然后读出来显示到LCD上。


#include <REGX52.H>

sbit DS1302_SCLK=P3^6;
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;

/*
*@brief(介绍)  把DS1302初始化,让CE和SCLK置0
*@param(参数)   无
*@retval(返回值)无
*/
void DS1302_Init(void) //这个函数没有参数,那括号里面可以不写,也可以写void
{
        DS1302_CE=0;
        DS1302_SCLK=0;
       
}

/*
*@brief(介绍)  使用DS1202单字节写数据
*@param(参数)  第一个参数,Command就是命令字,第二个参数,Data就是要写入的数据
*@retval(返回值) 无
*/
void DS1302_WriteByte(unsigned char Command,Data)
{  
        unsigned char i;
        DS1302_CE=1;
        for(i=0;i<8;i++)
        {
                DS1302_IO=Command&(0x01<<i);
                DS1302_SCLK=1;
                DS1302_SCLK=0;
        }
        for(i=0;i<8;i++)
        {
                DS1302_IO=Data&(0x01<<i);
                DS1302_SCLK=1;
                DS1302_SCLK=0;
}
        DS1302_CE=0;

}



/*
*@brief(介绍)  单字节读,读取Data的值
*@param(参数)   Command 命令字,Data是我们要读取的数据
*@retval(返回值)  Data
*/
unsigned char DS1302_ReadByte(unsigned char Command)
{
        unsigned char i,Data=0x00;
//    Command|=0x81;//将指令转换为读指令
        DS1302_CE=1;
        for(i=0;i<8;i++)
        {
                DS1302_IO=Command&(0x01<<i);
                DS1302_SCLK=0;
                DS1302_SCLK=1;
        }
    for(i=0;i<8;i++)
    {
                DS1302_SCLK=1;//DS1302_SCLK=0;
                DS1302_SCLK=0;//DS1302_SCLK=1;
            if(DS1302_IO){Data|=(0x01<<i);}
               
        }
//    DS1302_SCLK=0;
        DS1302_CE=0;
        DS1302_IO=0;
        return Data;//因为我们定义的子函数是有返回值的,所以要写return 返回代码
}

主函数

#include <REGX52.H>
#include "LCD1602.h"
#include "DS1302.h"

unsigned char Second;
void main()
{
        LCD_Init();
        DS1302_Init();
        LCD_ShowString(1,1,"RTC");
        DS1302_WriteByte(0X80,0X03);//写一个秒的数,那么写的命令字就是0x80,写入的数据是0x03
        Second=DS1302_ReadByte(0X81);//把上面写的数据读出来,因为是秒,所以读的命令字就是0X81
        LCD_ShowNum(2,1,Second,3);//上面写完,读出来后,这一步是在LCD上面显示出来,再第2行第1列显示,显示3个长度
       
        while(1)
        {
               
        }
}

STCMCUNT015 发表于 2025-9-10 16:56 | 显示全部楼层
STC89系列图形化编程:
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=19632#lastpost

可以去STC技术交流社区www.STCAIMCU.com交流,会有专业的技术解答


dffzh 发表于 2025-9-10 17:11 | 显示全部楼层
1、DS1302的驱动代码是自己写的还是标准驱动?
2、如果不写数据,直接循环读取,读取到的数据是多少?
xch 发表于 2025-9-11 17:02 | 显示全部楼层
DS1302 是啥东西?

有没有数据手册?
使用手册?
xch 发表于 2025-9-11 17:13 | 显示全部楼层
DS1302_IO = Data&(0x01<<i); //这两种不同类型能够这样赋值?
还有,写的时候数据在clk低电平时变化,而读的时候也在clk 低电平时读。不符合常规。
还有时钟频率符合DS1302要求吗?都没插入延时
得看看数据手册
xch 发表于 2025-9-11 17:31 | 显示全部楼层
这张图说明应当在clk 高电平时读数。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
xch 发表于 2025-9-11 17:33 | 显示全部楼层
unsigned char DS1302_ReadByte(unsigned char Command)
{
        unsigned char i,Data=0x00;
//    Command|=0x81;//将指令转换为读指令
        DS1302_CE=1;
        for(i=0;i<8;i++)
        {
                DS1302_IO=Command&(0x01<<i);
                DS1302_SCLK=0;
                DS1302_SCLK=1;
        }
    for(i=0;i<8;i++)
    {
                DS1302_SCLK=1;
                if(DS1302_IO){Data|=(0x01<<i);}  //应当CLK高电平时读
                DS1302_SCLK=0;
        }
        DS1302_CE=0;
        DS1302_IO=0;
        return Data;//因为我们定义的子函数是有返回值的,所以要写return 返回代码
}
xch 发表于 2025-9-11 17:46 | 显示全部楼层
芯片clk 频率可能仅0.5MHZ. MCU 主频多少? CLK 设定之间可能需要插入几个NOP指令,使得CLK脉冲高低电平宽度都达到1微秒
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

1

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部