我正在使用PIC18F45K22和XC8。
我已经为I2C插入了MCC库

我需要从ds1307读取秒数的示例,并在下一级中更改当前时间。

根据下面的代码,我在里面
while(状态== I2C2_MESSAGE_PENDING);

    I2C2_MasterWrite(&pdata_write, 1, 0b11010000, &status);
 // at this point, your status will probably be I2C2_MESSAGE_PENDING
    while (status == I2C2_MESSAGE_PENDING); // wait for status to to change
    if (status == I2C2_MESSAGE_COMPLETE) {
    I2C2_MasterRead(&pdata_read, 1, 0b11010001, &status);
    while (status == I2C2_MESSAGE_PENDING); // again, wait for status to to change
    if (status == I2C2_MESSAGE_COMPLETE) {
        // pdata_read should now be the number of seconds (in binary-coded decimal)
    }


这是我从MCC自动创建的密码管理器

#define SCL2_TRIS               TRISDbits.TRISD0
#define SCL2_LAT                LATDbits.LATD0
#define SCL2_PORT               PORTDbits.RD0
#define SCL2_ANS                ANSELDbits.ANSD0
#define SCL2_SetHigh()            do { LATDbits.LATD0 = 1; } while(0)
#define SCL2_SetLow()             do { LATDbits.LATD0 = 0; } while(0)
#define SCL2_Toggle()             do { LATDbits.LATD0 = ~LATDbits.LATD0; } while(0)
#define SCL2_GetValue()           PORTDbits.RD0
#define SCL2_SetDigitalInput()    do { TRISDbits.TRISD0 = 1; } while(0)
#define SCL2_SetDigitalOutput()   do { TRISDbits.TRISD0 = 0; } while(0)
#define SCL2_SetAnalogMode()  do { ANSELDbits.ANSD0 = 1; } while(0)
#define SCL2_SetDigitalMode() do { ANSELDbits.ANSD0 = 0; } while(0)

// get/set SDA2 aliases
#define SDA2_TRIS               TRISDbits.TRISD1
#define SDA2_LAT                LATDbits.LATD1
#define SDA2_PORT               PORTDbits.RD1
#define SDA2_ANS                ANSELDbits.ANSD1
#define SDA2_SetHigh()            do { LATDbits.LATD1 = 1; } while(0)
#define SDA2_SetLow()             do { LATDbits.LATD1 = 0; } while(0)
#define SDA2_Toggle()             do { LATDbits.LATD1 = ~LATDbits.LATD1; } while(0)
#define SDA2_GetValue()           PORTDbits.RD1
#define SDA2_SetDigitalInput()    do { TRISDbits.TRISD1 = 1; } while(0)
#define SDA2_SetDigitalOutput()   do { TRISDbits.TRISD1 = 0; } while(0)
#define SDA2_SetAnalogMode()  do { ANSELDbits.ANSD1 = 1; } while(0)
#define SDA2_SetDigitalMode() do { ANSELDbits.ANSD1 = 0; } while(0)


Image

Image2

见下面的图片

也试图在我的液晶显示器中显示时间

sprintf(txt,"%d",pdata_read);
     LCDPutStr(txt,1);

最佳答案

我没有硬件或软件,但查看了https://www.studentcompanion.co.za/interfacing-the-ds1307-real-time-clock-with-pic-microcontroller-xc8/(一个很长的教程,可以使您快速入门)和https://datasheets.maximintegrated.com/en/ds/DS1307.pdf(数据表),以及一些提到 / I2C_MasterWrite以某种方式。

非常低级的步骤是:


START(为您处理)
写入0b1101000(这是地址加方向位)
收到确认
如您正确指出的那样,“秒”寄存器的写地址为I2C_MasterRead(这是数据)
收到确认
开始
写入0b11010001(这是地址加方向位)
收到确认

发送确认或不确认


看起来很底层的部分(START / ACKNOWLEDGE和发送地址)正在为您处理,因此您可能只需要执行与以下代码类似的操作(您可能希望重组0x00逻辑以处理错误)更好):

I2C_MESSAGE_STATUS status;
uint8_t pdata_write = 0; // 0 to 'seconds' register
uint8_t pdata_read; // will hold 'seconds'

I2C2_MasterWrite(&pdata_write, 1, 0b1101000, &status);
// at this point, your status will probably be I2C2_MESSAGE_PENDING
while (status == I2C_MESSAGE_PENDING); // wait for status to to change
if (status == I2C_MESSAGE_COMPLETE) {
    I2C2_MasterRead(&pdata_read, 1, 0b1101000, &status);
    while (status == I2C_MESSAGE_PENDING); // again, wait for status to to change
    if (status == I2C_MESSAGE_COMPLETE) {
        // pdata_read should now be the number of seconds (in binary-coded decimal)
    }
}



if是指向您要读取/写入的内容的指针,它实际上是指向上述步骤4中包含*pdata的变量的指针。
0x0是您要读取/写入的数据的长度,我认为在上面列出的所有步骤中,该长度恰好为1
length是DS1307的地址,address
0b1101000是I2C消息的状态。


根据https://github.com/apaivaj/WWVB/blob/master/MainProject/WWVB/mcc_generated_files/i2c1.hpstatus可以是以下任意一项:

typedef enum
{
    I2C1_MESSAGE_FAIL,
    I2C1_MESSAGE_PENDING,
    I2C1_MESSAGE_COMPLETE,
    I2C1_STUCK_START,
    I2C1_MESSAGE_ADDRESS_NO_ACK,
    I2C1_DATA_NO_ACK,
    I2C1_LOST_STATE
} I2C1_MESSAGE_STATUS;


您可能应该至少检查pstatus



更新:要写入秒寄存器,请参见数据表第12页的图4:您需要写入两段数据:首先是寄存器编号,然后是您想要写入该寄存器的编号。因此,代码如下所示:

I2C_MESSAGE_STATUS status;
uint8_t pdata_write[2] = { 0, 0x10 }; // 0x10 into 'seconds' register
I2C2_MasterWrite(pdata_write, 1, 0b1101000, &status);
while (status == I2C_MESSAGE_PENDING); // wait for status to to change
if (status == I2C_MESSAGE_COMPLETE) {
    // done!
} else {
    // error
}

关于c - 使用I2C的读取时间(Ds1307),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49492415/

10-14 03:36