发表于 2019-9-19 15:37:31

可以选择地址的。第一次先写入硬件地址和读取地址。第二次直接读取数据长度即可。MEM这个函数我没有仔细的研究,我使用的函数操作过程有I2C开始、停止操作。

hujjj 发表于 2019-9-19 17:25:57

安 发表于 2019-9-19 15:37
可以选择地址的。第一次先写入硬件地址和读取地址。第二次直接读取数据长度即可。MEM这个函数我没有仔细的 ...

我再测试看看。

hujjj 发表于 2019-9-20 10:08:09

    经过测试,使用HAL_I2C_Mem_Write()和HAL_I2C_Mem_Read()函数对DS1307进行读写操作没有问题,而使用HAL_I2C_Transmit()和HAL_I2C_Master_Receive()函数对DS1307进行读写操作却不成功,似乎操作的数据地址不正确。我在测试时按照每分钟读取一次,分别使用不同的函数对同一DS1307器件读取日历数据,用HAL_I2C_Mem_Read()函数能读出正确的日期和时间,而用HAL_I2C_Master_Receive()函数读出的内容却是错误的,应该是读入了其他地址的数据。
    这是用HAL_I2C_Mem_Read()函数读取的日历数据(年份和时间):



    这是月日和时间:



    这是用HAL_I2C_Master_Receive()函数读出年份和时间:



    这是月日和时间:



    我按照版主的提示在读写操作前先写入要读写的地址,然后再进行读写操作,结果仍是不行,看来对用HAL_I2C_Master_Receive()和用HAL_I2C_Master_Transmit()这两个函数还尚未理解和掌握。下面是我测试时的代码:
/******************************************************************************************
* 函数名称: DS1307_I2C_Transmit(uint8_t size)
* 功能说明: 写数据到DS1307
* 输    入: size 数据个数(要写入数据在全局数组DS_Buff中)
* 输    出: 0 = 成功写入1 = 写数据过程中出现错误
******************************************************************************************/
uint8_t DS1307_I2C_Transmit(uint8_t size)
{
   
        DS1307_DataToBuff();      //将时间及日期数据转换到Buff数组中
        HAL_I2C_Master_Transmit(&hi2c1,0xD0,0,1,10000);//发送起始地址
       
        if(HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)DS_Buff ,size,10000) != HAL_OK)
    {
      return 1;
    }
        return 0;
}

/******************************************************************************************
* 函数名称: DS1307_I2C_Receive(uint8_t size)
* 功能说明: 从DS1307读出数据
* 输    入: size 数据个数(读出的数据在全局数组DS_Buff中)
* 输    出: 0 = 成功读出1 = 读数据过程中出现错误
******************************************************************************************/
uint8_t DS1307_I2C_Receive(uint8_t size)
{
        HAL_I2C_Master_Transmit(&hi2c1,0xD0,0,1,10000);//发送起始地址
       
    if(HAL_I2C_Master_Receive(&hi2c1,0xD0,DS_Buff,7,10000) != HAL_OK)
    {
      return 1;
    }
    if(size == 1){               //检查DS1307是否需要初始化
                if(DS_Buff>127){
            year = 2019;
                  month = 9;
                  day = 18;
                  week = 3;
                  hour = 9;
                  minute = 1;
               
            DS1307_DataToBuff();
                        DS1307_I2C_Transmit(8);
                }
        }
        else{
          DS1307_BuffToData();
    }
        return 0;       
}


发表于 2019-9-20 10:20:58

我用到的时I2C1,楼主用的和我一样吗?楼主看一下你用的RTC的硬件地址是多少,是否和我的一致。1307读取出来的是BCD码,需要进行数据转换的。I2C操作入口时指针类型,需要注意一下。

hujjj 发表于 2019-9-20 11:09:22

我的DS1307器件地址是0xD0,数据格式是BCD码,数组是定义为uint8_t,目前用HAL_I2C_Mem..函数能够正常读写,而且对AT24C32也能正常读写。但用HAL_I2C_Master..函数则读写出错,很可能是没有操控好读写的地址。

发表于 2019-9-20 11:23:02

我怀疑时你写入的第一个数内容不对,你入口写0。你按照我给你的代码试试。入口用一个变量或者数组。

hujjj 发表于 2019-9-20 12:25:12

安 发表于 2019-9-20 11:23
我怀疑时你写入的第一个数内容不对,你入口写0。你按照我给你的代码试试。入口用一个变量或者数组。 ...

    确实是这个问题,我改成变量之后就顺利地读出了正确数据,看来这个参数不能用常量。下面是修改后能正确运行的代码:
/******************************************************************************************
* 函数名称: DS1307_I2C_Transmit(uint8_t size)
* 功能说明: 写数据到DS1307
* 输    入: size 数据个数(要写入数据在全局数组DS_Buff中)
* 输    出: 0 = 成功写入1 = 写数据过程中出现错误
******************************************************************************************/
uint8_t DS1307_I2C_Transmit(uint8_t size)
{
    uint8_t addr = 0;
        DS1307_DataToBuff();      //将时间及日期数据转换到Buff数组中
        HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
       
        if(HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)DS_Buff ,size,10000) != HAL_OK)
    {
      return 1;
    }
        return 0;
}

/******************************************************************************************
* 函数名称: DS1307_I2C_Receive(uint8_t size)
* 功能说明: 从DS1307读出数据
* 输    入: size 数据个数(读出的数据在全局数组DS_Buff中)
* 输    出: 0 = 成功读出1 = 读数据过程中出现错误
******************************************************************************************/
uint8_t DS1307_I2C_Receive(uint8_t size)
{
        uint8_t addr = 0;
        HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
       
    if(HAL_I2C_Master_Receive(&hi2c1,0xD0,DS_Buff,7,10000) != HAL_OK)
    {
      return 1;
    }
    if(size == 1){               //检查DS1307是否需要初始化
                if(DS_Buff>127){
            year = 2019;
                  month = 9;
                  day = 18;
                  week = 3;
                  hour = 9;
                  minute = 1;
               
            DS1307_DataToBuff();
                        DS1307_I2C_Transmit(8);
                }
        }
        else{
          DS1307_BuffToData();
    }
        return 0;       
}

    终于实现了两种方法读取数据,再次表示感谢!
页: 1 [2]
查看完整版本: 使用HAL库硬件I2C时如何设置器件地址?