下面这个函数其实要控制的是几个全局变量
int32_t I2C0_Read_Write_SLAVE(uint8_t slvaddr)
{
uint32_t i;
g_u8DeviceAddr = slvaddr;
for(i = 0; i < 0x100; i++)
{
g_au8MstTxData[0] = (uint8_t)((i & 0xFF00) >> 8);
g_au8MstTxData[1] = (uint8_t)(i & 0x00FF);
g_au8MstTxData[2] = (uint8_t)(g_au8MstTxData[1] + 3);
g_u8MstDataLen = 0;
g_u8MstEndFlag = 0;
/* I2C function to write data to slave */
s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterTx;
/* I2C as master sends START signal */
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA);
/* Wait I2C Tx Finish */
while(g_u8MstEndFlag == 0);
g_u8MstEndFlag = 0;
/* I2C function to read data from slave */
s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterRx;
g_u8MstDataLen = 0;
g_u8DeviceAddr = slvaddr;
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA);
/* Wait I2C Rx Finish */
while(g_u8MstEndFlag == 0);
/* Compare data */
if(g_u8MstRxData != g_au8MstTxData[2])
{
printf("I2C Byte Write/Read Failed, Data 0x%x\n", g_u8MstRxData);
return -1;
}
}
printf("Master Access Slave (0x%X) Test OK\n", slvaddr);
return 0;
}
实际应用中,肯定不是这么写,但是可以根据它的内容知道这些函数如何用
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA);
不管是发送完成还是接收完成都是通过中断标志g_u8MstEndFlag置位来实现。
发送和接收都在中断回调函数里执行。并根据状态字执行不同的动作
/*---------------------------------------------------------------------------------------------------------*/
/* I2C Rx Callback Function */
/*---------------------------------------------------------------------------------------------------------*/
void I2C_MasterRx(uint32_t u32Status)
{
if(u32Status == 0x08) /* START has been transmitted and prepare SLA+W */
{
I2C_SET_DATA(I2C0, (g_u8DeviceAddr << 1)); /* Write SLA+W to Register I2CDAT */
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else if(u32Status == 0x18) /* SLA+W has been transmitted and ACK has been received */
{
I2C_SET_DATA(I2C0, g_au8MstTxData[g_u8MstDataLen++]);
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else if(u32Status == 0x20) /* SLA+W has been transmitted and NACK has been received */
{
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA_STO_SI);
}
else if(u32Status == 0x28) /* DATA has been transmitted and ACK has been received */
{
if(g_u8MstDataLen != 2)
{
I2C_SET_DATA(I2C0, g_au8MstTxData[g_u8MstDataLen++]);
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else
{
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA_SI);
}
}
else if(u32Status == 0x10) /* Repeat START has been transmitted and prepare SLA+R */
{
I2C_SET_DATA(I2C0, ((g_u8DeviceAddr << 1) | 0x01)); /* Write SLA+R to Register I2CDAT */
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else if(u32Status == 0x40) /* SLA+R has been transmitted and ACK has been received */
{
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else if(u32Status == 0x58) /* DATA has been received and NACK has been returned */
{
g_u8MstRxData = (unsigned char) I2C_GET_DATA(I2C0);
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STO_SI);
g_u8MstEndFlag = 1;
}
else
{
/* TO DO */
printf("Status 0x%x is NOT processed\n", u32Status);
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* I2C Tx Callback Function */
/*---------------------------------------------------------------------------------------------------------*/
void I2C_MasterTx(uint32_t u32Status)
{
if(u32Status == 0x08) /* START has been transmitted */
{
I2C_SET_DATA(I2C0, g_u8DeviceAddr << 1); /* Write SLA+W to Register I2CDAT */
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else if(u32Status == 0x18) /* SLA+W has been transmitted and ACK has been received */
{
I2C_SET_DATA(I2C0, g_au8MstTxData[g_u8MstDataLen++]);
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else if(u32Status == 0x20) /* SLA+W has been transmitted and NACK has been received */
{
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA_STO_SI);
}
else if(u32Status == 0x28) /* DATA has been transmitted and ACK has been received */
{
if(g_u8MstDataLen != 3)
{
I2C_SET_DATA(I2C0, g_au8MstTxData[g_u8MstDataLen++]);
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
}
else
{
I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STO_SI);
g_u8MstEndFlag = 1;
}
}
else
{
/* TO DO */
printf("Status 0x%x is NOT processed\n", u32Status);
}
}
|