This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSPM0G1106:DS1307读取错误

Guru**** 1788580 points
Other Parts Discussed in Thread: SYSCONFIG
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1402476/mspm0g1106-ds1307-read-error

器件型号:MSPM0G1106
主题中讨论的其他器件:SysConfig

工具与软件:

大家好、我在使用 DS1307。 我不断从 I2C 线路收到无意义的时间。 我将保留下面编写的代码。 您能帮我解决可能出错的问题吗?

#include "ti_msp_dl_config.h"
#include "LCD_Func.h"
int val=0;


#define DS1307_ADDRESS 0x68

#define 秒0x00
#define minutes 0x01
#define Hours 0x02
#define Day 0x03
#define Date 0x04
#define Month 0x05
#define 年份0x06
/* I2C 目标地址*/


/*从 DS1307接收到的数据*/
易失性 uint8_t gRxPacket[7];

uint8_t 秒;// Saniyeler
uint8_t minutes ;// Dakikalar
uint8_t 小时;// Saatler
uint8_t dayOfWeek ;/ Haftanın günü
uint8_t dayOfMonth ;/ Ayın günü
uint8_t 月;//天
uint8_t 年;


int bcdToDec (int val){
返回((val / 16)* 10 + val % 16);
}


uint8_t rxData;
uint8_t readDS1307Register (uint8_t regAddr)



DL_I2C_fillControllerTXFIFO (I2C_INST、&regAddr、1);


while (! (DL_I2C_getControllerStatus (I2C_INST)和 DL_I2C_CONTROLLER_STATUS_IDLE);


DL_I2C_startControllerTransfer (I2C_INST、DS1307_ADDRESS、
DL_I2C_CONTROLLER_DIRECTION_RX、1);


while (DL_I2C_isControllerRXFIFOEMpty (I2C_INST))

rxData = DL_I2C_receiveControllerData (I2C_INST);


if (DL_I2C_getControllerStatus (I2C_INST)和 DL_I2C_CONTROLLER_STATUS_ERROR){
__BKPT (0);// hata durumunda duraklat
}


返回 bcdToDec (rxData);
}

int main (void)

SYSCFG_DL_init ();

uint8_t start_address = 0x00;



while (1){

// DS13710den saniyeleri Oku ve yazdır
// DS13710den saniyeleri Oku ve yazdır
uint8_t seconds = readDS1307Register (秒);
printf ("秒:%02d\n"、秒);

// DS13730den dakikaları Oku ve yazdır
uint8_t minutes = readDS1307Register (minutes);
printf ("minut:%02d\n"、分钟);

// DS13710den saatleri Oku ve yazdır
uint8_t hours = readDS1307Register (hours);
printf ("小时数:%02d\n"、小时数);

// DS13730den günü Oku ve yazdır
uint8_t day = readDS1307Register (day);
printf ("天:%02d\n"、天);

// DS13710den tarihi Oku ve yazdır
uint8_t date = readDS1307Register (Date);
printf ("日期:%02d\n"、日期);

// DS13730den ayı Oku ve yazdır
uint8_t month = readDS1307Register (month);
printf ("monty:%02d\n"、月);

// DS13730den yılı Oku ve yazdır
uint8_t year = readDS1307Register (Year);
printf ("年:%02d\n"、年);


printf ("//////////////////////////////////////////////////////////////////////////////////////////// \n");
delay_cycles (160000000);


// toggle_gpio_pin ();
}
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Burak:

    在查看输出时、您似乎是从 DS1307器件中获得一些数据、这并不是您所期望的数据。 目前、该 I2C 总线上有其他器件吗? 此数据是否确实来自 DS1307?

    我提出这个问题是因为、假设总线上没有其他器件、并且数据肯定来自 DS1307、在我看来、MSPM0侧的 I2C 通信工作正常。 但 DS1307的响应并非如此。 我建议您查看 DS1307数据表、从而验证所用的通信方案、查看是否存在缺失的信号。

    通常、如果 MSPM0用作 I2C 控制器、并且以不正确的格式读取器件、则会出现总线错误情况。 您可以监控许多中断来检查这一点、请参阅 MSPM0 G 系列 TRM 的"I2C"部分。 如果您在工程中使用 SysConfig、则启用所有错误检查中断非常方便、然后在读取 DS1307时只需检查是否发生了其中任何中断。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我使用的电路是我以前使用过的电路。 我没有连接任何其他仅连接至 ds1307线路的从器件。 我将发送数据表和电路作为附件。

    e2e.ti.com/.../29185_5F00_6597768-_2800_3_2900_.pdf

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    首先、您不处理秒寄存器中的"CH"位。

    第二、我看不出您将要读取的寄存器发送到何处。 我想你会喜欢的。

    DL_I2C_startControllerTransfer (I2C_INST、I2C_TARGET_ADDRESS、
           DL_I2C_CONTROLLER_DIRECTION_TX、I2C_TX_PACKET_SIZE);

    来告诉 DS1307需要的寄存器。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我通过查看数据表将 ds1307地址指定为0x68。 regAddr 帮助您找到读取的位置。

    void readAllDS1307Registers (uint8_t *buffer){
    uint8_t regAddr = 0x01;// Başlangıç adresi (秒寄存器)

    /* Başlangıç adresini belirle */
    DL_I2C_fillControllerTXFIFO (I2C_INST、&regAddr、1);

    /* I2C hattının boşalmasını bekle */
    while (! (DL_I2C_getControllerStatus (I2C_INST)和 DL_I2C_CONTROLLER_STATUS_IDLE);

    /* 7 byte' işlemini başlat veri Okuma lık */
    DL_I2C_startControllerTransfer (I2C_INST、DS1307_ADDRESS、
    DL_I2C_CONTROLLER_DIRECTION_RX、7);

    /* Verilerin alındığından Emin ol */
    对于(int i = 0;i < 7;i++){
    while (DL_I2C_isControllerRXFIFOEMpty (I2C_INST))

    Buffer[i]= DL_I2C_receiveControllerData (I2C_INST);
    }

    /* Hata kontrolü*/
    if (DL_I2C_getControllerStatus (I2C_INST)和 DL_I2C_CONTROLLER_STATUS_ERROR){
    __BKPT (0);// hata durumunda duraklat
    }

    /* Tüm verileri bcd'den decimal'e çevir */
    对于(int i = 0;i < 7;i++){
    Buffer[i]= bcdToDec (buffer[i]);
    }
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Burak:

    快速浏览 DS1307数据表后、必须先写入寄存器指针、然后再执行读取操作。 如果您在不对寄存器指针进行写入的情况下执行读取操作、DS1307将使用存储到寄存器指针的最新值、这在您的程序中是未指定的、因此我们不知道其值。

    您需要按照设置的方式设置外围设备地址、然后手动发送要读取的寄存器地址、然后再次发送外围设备地址。 然后使用重复启动条件、您可以通过读取来重新启动、以读取刚刚指示的数据寄存器。 因此、例如、若要读取年寄存器、您需要发送[ 0x68、0x06、0x68 ]、然后使用重复的 START 并将 DIRECTION 位设置为 READ、然后继续读取寄存器。

    要执行重复启动、请使用 DL_I2C_startControllerTransferAdvanced ()函数、您可以在我们的 driverlib API 指南中了解该函数