我正在使用PIC18F45K22和XC8。 我插入了用于I2C的MCC库
我需要示例从ds1307读取秒数,然后在下一级别读取更改当前时间。
根据下面的代码,我在里面堆叠 while(status == 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)
见下面的图片
还试图在我的lcd中显示时间
sprintf(txt,"%d",pdata_read);
LCDPutStr(txt,1);
答案 0 :(得分:0)
我没有硬件或软件,但看了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
/ I2C_MasterRead
的随机页面。
非常低级的步骤是:
0x00
(这是数据)看起来正在为您处理非常低级的部分(START / ACKNOWLEDGE和发送地址),因此您可能只需要执行类似于以下代码的操作(您可能需要重构{{1} }更好地处理错误的逻辑):
if
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)
}
}
是指向您想要读取/写入的内容的指针,它实际上是指向上面步骤4中包含*pdata
的变量的指针。0x0
是您想要读/写的数据的长度,我认为在上面列出的所有步骤中,该数据恰好为1 length
是DS1307的地址address
0b1101000
是I2C消息的状态。根据https://github.com/apaivaj/WWVB/blob/master/MainProject/WWVB/mcc_generated_files/i2c1.h,pstatus
可以是以下任何一种:
pstatus
您应该检查至少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;
。
更新:要写入秒寄存器,请参见数据表第12页的图4:您需要写两个数据:首先是寄存器号,然后是您想要的数字写入该登记册。因此,代码看起来像这样:
I2C_MESSAGE_FAIL