主题中讨论的其他器件:AM2634
工具/软件:
尊敬的团队:
我将处理 AM2634、并通过 I2C 将其与 DS1307 RTC 连接。 我将使用中的 I2C 驱动器 中断模式和回调函数 。
使用 API:
void DS1307_writeTime(uint8_t hr, uint8_t min, uint8_t sec, uint8_t day, uint8_t date, uint8_t month, uint8_t year)
已成功设置 RTC 时间。
但是、当我尝试使用另一个 API 来读取时间时:
void ReadDateTime (void)
我尝试全部阅读 7字节 从寄存器地址开始0x00
(对应于秒寄存器)。 但在这种情况下:
1.输出数据为 垃圾或无效 。
2. 不触发 I2C 中断 读取操作期间的功耗。
另一方面,我有另一个功能:
void ReadSec (void)
其中我读取数据 一次一个字节 首先写入寄存器地址(例如0x00
、、0x01
、0x02
等)、 然后读取一个字节。 这种方法可靠运行、并从 RTC 返回正确的值。
我的问题:
为什么在单个事务中从0x00开始读取完整的7字节块时失败(即返回垃圾而没有中断)、即使 AM2634 I2C 驱动程序支持也是如此 重复启动条件 ? 在将中断模式用于组合写入-读取传输时、这是否是驱动程序的限制或错误?
请提供任何指导或建议。
另外、请在下面附加我的代码、然后看一下
/* * DS1307.c * * Created on: Apr 20, 2025 * Author: Swati */ #include <drivers/i2c.h> #include <kernel/dpl/ClockP.h> #include <stdint.h> #include <string.h> #include "ti_drivers_config.h" #define DS1307_I2C_ADDR (0x68) #define DS1307_REG_SECONDS (0x00) #define DS1307_REG_MINUTES (0x01) #define DS1307_REG_HOURS (0x02) #define DS1307_REG_DAY (0x03) #define DS1307_REG_DATE (0x04) #define DS1307_REG_MONTH (0x05) #define DS1307_REG_YEAR (0x06) #define I2C_READ_LEN (7U) #define I2C_ADDR_START 0x03 #define I2C_ADDR_END 0x77 #define I2C_SCAN_LEN 1 extern I2C_Handle gI2cHandle[]; static uint8_t hr, min, sec, day, date, month, year; uint8_t bcdToDec(uint8_t val) { return ((val / 16 * 10) + (val % 16)); } uint8_t decToBcd(uint8_t val) { return ((val / 10 * 16) + (val % 10)); } void ERTC_CallBack(I2C_Transaction *msg, int32_t transferStatus) { DebugP_log("transferStatus %d\n", transferStatus); if (transferStatus == SystemP_SUCCESS) { DebugP_log("I2C transfer successful.\n"); } else { DebugP_log("I2C transfer failed.\n"); } } void DS1307_writeTime(uint8_t hr, uint8_t min, uint8_t sec, uint8_t day, uint8_t date, uint8_t month, uint8_t year) { I2C_Transaction i2cTransaction = {0U}; uint8_t txBuffer[8]; I2C_Handle i2cHandle; i2cHandle = gI2cHandle[CONFIG_I2C0]; int32_t transferStatus; I2C_Transaction_init(&i2cTransaction); txBuffer[0] = DS1307_REG_SECONDS; txBuffer[1] = decToBcd(sec); txBuffer[2] = decToBcd(min); txBuffer[3] = decToBcd(hr); txBuffer[4] = decToBcd(day); txBuffer[5] = decToBcd(date); txBuffer[6] = decToBcd(month); txBuffer[7] = decToBcd(year); DebugP_log("Writing to DS1307: %02x %02x %02x %02x %02x %02x %02x\n", txBuffer[1], txBuffer[2], txBuffer[3], txBuffer[4], txBuffer[5], txBuffer[6], txBuffer[7]); i2cTransaction.writeBuf = txBuffer; i2cTransaction.writeCount = 8; i2cTransaction.readBuf = NULL; i2cTransaction.readCount = 0; i2cTransaction.targetAddress = (DS1307_I2C_ADDR); transferStatus = I2C_transfer(i2cHandle, &i2cTransaction); if (transferStatus == SystemP_SUCCESS) { DebugP_log("DS1307 write successful\n"); } else { DebugP_log("DS1307 write failed\n"); DebugP_log("Target Address: 0x%x, Wrote %d bytes\n", i2cTransaction.targetAddress, i2cTransaction.writeCount); } } void i2c_read_error_handler(uint8_t addr, int32_t status) { switch (status) { case I2C_STS_ERR: DebugP_logError("[I2C] Addr 0x%02X: Generic error occurred", addr); break; case I2C_STS_ERR_TIMEOUT: DebugP_logError("[I2C] Addr 0x%02X: Timeout error occurred", addr); break; case I2C_STS_ERR_NO_ACK: DebugP_logError("[I2C] Addr 0x%02X: No ACK received", addr); break; case I2C_STS_ERR_ARBITRATION_LOST: DebugP_logError("[I2C] Addr 0x%02X: Arbitration lost", addr); break; case I2C_STS_ERR_BUS_BUSY: DebugP_logError("[I2C] Addr 0x%02X: Bus busy error", addr); break; default: DebugP_logError("[I2C] Addr 0x%02X: Unknown error %d", addr, status); break; } } void ReadDateTime(void) { uint8_t rxBuffer[7]; uint8_t txBuffer[1] = {0x00}; // Start reading from register 0x00 (Seconds) I2C_Handle i2cHandle = gI2cHandle[CONFIG_I2C0]; I2C_Transaction i2cTransaction; int32_t transferStatus; I2C_Transaction_init(&i2cTransaction); i2cTransaction.writeBuf = txBuffer; i2cTransaction.writeCount = 1; i2cTransaction.readBuf = rxBuffer; i2cTransaction.readCount = 7; // Read all registers in one shot i2cTransaction.targetAddress = 0x68; transferStatus = I2C_transfer(i2cHandle, &i2cTransaction); if (transferStatus == I2C_STS_SUCCESS) { sec = bcdToDec(rxBuffer[0] & 0x7F); min = bcdToDec(rxBuffer[1]); hr = bcdToDec(rxBuffer[2]); day = bcdToDec(rxBuffer[3]); date = bcdToDec(rxBuffer[4]); month = bcdToDec(rxBuffer[5]); year = bcdToDec(rxBuffer[6]); DebugP_log("Time from DS1307: %02d:%02d:%02d\n", hr, min, sec); DebugP_log("Date from DS1307: %02d/%02d/%04d\n", date, month, 2000 + year); } else { i2c_read_error_handler(i2cTransaction.targetAddress, i2cTransaction.status); } } void ReadSec(void) { uint8_t secrxBuffer[1]; uint8_t sectxBuffer[I2C_SCAN_LEN] = {0x00}; I2C_Handle i2cHandle; I2C_Transaction i2cTransaction; int32_t transferStatus; i2cHandle = gI2cHandle[CONFIG_I2C0]; DebugP_log("[I2C] Scanning for I2C devices...\r\n"); I2C_Transaction_init(&i2cTransaction); i2cTransaction.writeBuf = sectxBuffer; i2cTransaction.writeCount = 1; i2cTransaction.readBuf = secrxBuffer; i2cTransaction.readCount = 1; i2cTransaction.targetAddress = 0x68; transferStatus = I2C_transfer(i2cHandle, &i2cTransaction); if (transferStatus == I2C_STS_SUCCESS) { sec = bcdToDec(secrxBuffer[0] & 0x7F); DebugP_log("sec from DS1307: %02d\n", sec); ClockP_usleep(10000); uint8_t minrxBuffer[1]; uint8_t mintxBuffer[I2C_SCAN_LEN] = {0x01}; I2C_Transaction_init(&i2cTransaction); i2cTransaction.writeBuf = mintxBuffer; i2cTransaction.writeCount = 1; i2cTransaction.readBuf = minrxBuffer; i2cTransaction.readCount = 1; i2cTransaction.targetAddress = 0x68; transferStatus = I2C_transfer(i2cHandle, &i2cTransaction); if (transferStatus == I2C_STS_SUCCESS) { min = bcdToDec(minrxBuffer[0]); DebugP_log("min from DS1307: %02d\n", min); uint8_t hrrxBuffer[1]; uint8_t hrtxBuffer[I2C_SCAN_LEN] = {0x02}; I2C_Transaction_init(&i2cTransaction); i2cTransaction.writeBuf = hrtxBuffer; i2cTransaction.writeCount = 1; i2cTransaction.readBuf = hrrxBuffer; i2cTransaction.readCount = 1; i2cTransaction.targetAddress = 0x68; transferStatus = I2C_transfer(i2cHandle, &i2cTransaction); if (transferStatus == I2C_STS_SUCCESS) { hr = bcdToDec(hrrxBuffer[0]); DebugP_log("hr from DS1307: %02d\n", hr); } } DebugP_log("Date from DS1307: %02d:%02d:%04d\n", date, month, (2000 + year)); } else { i2c_read_error_handler(i2cTransaction.targetAddress, i2cTransaction.status); } }
谢谢!