В AN2824 есть такие функции чтения/записи.
CODE
Status I2C_Master_BufferRead(I2C_TypeDef* I2Cx, uint8_t* pBuffer, uint32_t NumByteToRead, I2C_ProgrammingModel Mode, uint8_t SlaveAddress)
{
__IO uint32_t temp = 0;
__IO uint32_t Timeout = 0;
/* Enable I2C errors interrupts (used in all modes: Polling, DMA and Interrupts */
I2Cx->CR2 |= I2C_IT_ERR;
if (Mode == DMA) /* I2Cx Master Reception using DMA */
{
/* Configure I2Cx DMA channel */
I2C_DMAConfig(I2Cx, pBuffer, NumByteToRead, I2C_DIRECTION_RX);
/* Set Last bit to have a NACK on the last received byte */
I2Cx->CR2 |= CR2_LAST_Set;
/* Enable I2C DMA requests */
I2Cx->CR2 |= CR2_DMAEN_Set;
Timeout = 0xFFFF;
/* Send START condition */
I2Cx->CR1 |= CR1_START_Set;
/* Wait until SB flag is set: EV5 */
while ((I2Cx->SR1&0x0001) != 0x0001)
{
if (Timeout-- == 0)
return Error;
}
Timeout = 0xFFFF;
/* Send slave address */
/* Set the address bit0 for read */
SlaveAddress |= OAR1_ADD0_Set;
Address = SlaveAddress;
/* Send the slave address */
I2Cx->DR = Address;
/* Wait until ADDR is set: EV6 */
while ((I2Cx->SR1&0x0002) != 0x0002)
{
if (Timeout-- == 0)
return Error;
}
/* Clear ADDR flag by reading SR2 register */
temp = I2Cx->SR2;
if (I2Cx == I2C1)
{
/* Wait until DMA end of transfer */
while (!DMA_GetFlagStatus(DMA1_FLAG_TC7));
/* Disable DMA Channel */
DMA_Cmd(I2C1_DMA_CHANNEL_RX, DISABLE);
/* Clear the DMA Transfer Complete flag */
DMA_ClearFlag(DMA1_FLAG_TC7);
}
else /* I2Cx = I2C2*/
{
/* Wait until DMA end of transfer */
while (!DMA_GetFlagStatus(DMA1_FLAG_TC5));
/* Disable DMA Channel */
DMA_Cmd(I2C2_DMA_CHANNEL_RX, DISABLE);
/* Clear the DMA Transfer Complete flag */
DMA_ClearFlag(DMA1_FLAG_TC5);
}
/* Program the STOP */
I2Cx->CR1 |= CR1_STOP_Set;
/* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
while ((I2Cx->CR1&0x200) == 0x200);
}
else if (Mode == Polling) /* I2Cx Master Reception using Polling */
{
if (NumByteToRead == 1)
{
Timeout = 0xFFFF;
/* Send START condition */
I2Cx->CR1 |= CR1_START_Set;
/* Wait until SB flag is set: EV5 */
while ((I2Cx->SR1&0x0001) != 0x0001)
{
if (Timeout-- == 0)
return Error;
}
/* Send slave address */
/* Reset the address bit0 for read */
SlaveAddress |= OAR1_ADD0_Set;
Address = SlaveAddress;
/* Send the slave address */
I2Cx->DR = Address;
/* Wait until ADDR is set: EV6_3, then program ACK = 0, clear ADDR
and program the STOP just after ADDR is cleared. The EV6_3
software sequence must complete before the current byte end of transfer.*/
/* Wait until ADDR is set */
Timeout = 0xFFFF;
while ((I2Cx->SR1&0x0002) != 0x0002)
{
if (Timeout-- == 0)
return Error;
}
/* Clear ACK bit */
I2Cx->CR1 &= CR1_ACK_Reset;
/* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
software sequence must complete before the current byte end of transfer */
__disable_irq();
/* Clear ADDR flag */
temp = I2Cx->SR2;
/* Program the STOP */
I2Cx->CR1 |= CR1_STOP_Set;
/* Re-enable IRQs */
__enable_irq();
/* Wait until a data is received in DR register (RXNE = 1) EV7 */
while ((I2Cx->SR1 & 0x00040) != 0x000040);
/* Read the data */
*pBuffer = I2Cx->DR;
/* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
while ((I2Cx->CR1&0x200) == 0x200);
/* Enable Acknowledgement to be ready for another reception */
I2Cx->CR1 |= CR1_ACK_Set;
}
else if (NumByteToRead == 2)
{
/* Set POS bit */
I2Cx->CR1 |= CR1_POS_Set;
Timeout = 0xFFFF;
/* Send START condition */
I2Cx->CR1 |= CR1_START_Set;
/* Wait until SB flag is set: EV5 */
while ((I2Cx->SR1&0x0001) != 0x0001)
{
if (Timeout-- == 0)
return Error;
}
Timeout = 0xFFFF;
/* Send slave address */
/* Set the address bit0 for read */
SlaveAddress |= OAR1_ADD0_Set;
Address = SlaveAddress;
/* Send the slave address */
I2Cx->DR = Address;
/* Wait until ADDR is set: EV6 */
while ((I2Cx->SR1&0x0002) != 0x0002)
{
if (Timeout-- == 0)
return Error;
}
/* EV6_1: The acknowledge disable should be done just after EV6,
that is after ADDR is cleared, so disable all active IRQs around ADDR clearing and
ACK clearing */
__disable_irq();
/* Clear ADDR by reading SR2 register */
temp = I2Cx->SR2;
/* Clear ACK */
I2Cx->CR1 &= CR1_ACK_Reset;
/*Re-enable IRQs */
__enable_irq();
/* Wait until BTF is set */
while ((I2Cx->SR1 & 0x00004) != 0x000004);
/* Disable IRQs around STOP programming and data reading because of the limitation ?*/
__disable_irq();
/* Program the STOP */
I2C_GenerateSTOP(I2Cx, ENABLE);
/* Read first data */
*pBuffer = I2Cx->DR;
/* Re-enable IRQs */
__enable_irq();
/**/
pBuffer++;
/* Read second data */
*pBuffer = I2Cx->DR;
/* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
while ((I2Cx->CR1&0x200) == 0x200);
/* Enable Acknowledgement to be ready for another reception */
I2Cx->CR1 |= CR1_ACK_Set;
/* Clear POS bit */
I2Cx->CR1 &= CR1_POS_Reset;
}
else
{
Timeout = 0xFFFF;
/* Send START condition */
I2Cx->CR1 |= CR1_START_Set;
/* Wait until SB flag is set: EV5 */
while ((I2Cx->SR1&0x0001) != 0x0001)
{
if (Timeout-- == 0)
return Error;
}
Timeout = 0xFFFF;
/* Send slave address */
/* Reset the address bit0 for write */
SlaveAddress |= OAR1_ADD0_Set;;
Address = SlaveAddress;
/* Send the slave address */
I2Cx->DR = Address;
/* Wait until ADDR is set: EV6 */
while ((I2Cx->SR1&0x0002) != 0x0002)
{
if (Timeout-- == 0)
return Error;
}
/* Clear ADDR by reading SR2 status register */
temp = I2Cx->SR2;
/* While there is data to be read */
while (NumByteToRead)
{
/* Receive bytes from first byte until byte N-3 */
if (NumByteToRead != 3)
{
/* Poll on BTF to receive data because in polling mode we can not guarantee the
EV7 software sequence is managed before the current byte transfer completes */
while ((I2Cx->SR1 & 0x00004) != 0x000004);
/* Read data */
*pBuffer = I2Cx->DR;
/* */
pBuffer++;
/* Decrement the read bytes counter */
NumByteToRead--;
}
/* it remains to read three data: data N-2, data N-1, Data N */
if (NumByteToRead == 3)
{
/* Wait until BTF is set: Data N-2 in DR and data N -1 in shift register */
while ((I2Cx->SR1 & 0x00004) != 0x000004);
/* Clear ACK */
I2Cx->CR1 &= CR1_ACK_Reset;
/* Disable IRQs around data reading and STOP programming because of the
limitation ? */
__disable_irq();
/* Read Data N-2 */
*pBuffer = I2Cx->DR;
/* Increment */
pBuffer++;
/* Program the STOP */
I2Cx->CR1 |= CR1_STOP_Set;
/* Read DataN-1 */
*pBuffer = I2Cx->DR;
/* Re-enable IRQs */
__enable_irq();
/* Increment */
pBuffer++;
/* Wait until RXNE is set (DR contains the last data) */
while ((I2Cx->SR1 & 0x00040) != 0x000040);
/* Read DataN */
*pBuffer = I2Cx->DR;
/* Reset the number of bytes to be read by master */
NumByteToRead = 0;
}
}
/* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
while ((I2Cx->CR1&0x200) == 0x200);
/* Enable Acknowledgement to be ready for another reception */
I2Cx->CR1 |= CR1_ACK_Set;
}
}
else /* I2Cx Master Reception using Interrupts with highest priority in an application */
{
/* Enable EVT IT*/
I2Cx->CR2 |= I2C_IT_EVT;
/* Enable BUF IT */
I2Cx->CR2 |= I2C_IT_BUF;
/* Set the I2C direction to reception */
I2CDirection = I2C_DIRECTION_RX;
SlaveAddress |= OAR1_ADD0_Set;
Address = SlaveAddress;
if (I2Cx == I2C1) NumbOfBytes1 = NumByteToRead;
else NumbOfBytes2 = NumByteToRead;
/* Send START condition */
I2Cx->CR1 |= CR1_START_Set;
/* Wait until the START condition is generated on the bus: START bit is cleared by hardware */
while ((I2Cx->CR1&0x100) == 0x100);
/* Wait until BUSY flag is reset (until a STOP is generated) */
while ((I2Cx->SR2 &0x0002) == 0x0002);
/* Enable Acknowledgement to be ready for another reception */
I2Cx->CR1 |= CR1_ACK_Set;
}
return Success;
}
/**
* @brief Writes buffer of bytes.
* @param pBuffer: Buffer of bytes to be sent to the slave.
* @param NumByteToWrite: Number of bytes to be sent by the Master.
* @param Mode: Polling or DMA or Interrupt having the highest priority in the application.
* @param SlaveAddress: The address of the slave to be addressed by the Master.
* @retval : None.
*/
Status I2C_Master_BufferWrite(I2C_TypeDef* I2Cx, uint8_t* pBuffer, uint32_t NumByteToWrite, I2C_ProgrammingModel Mode, uint8_t SlaveAddress )
{
__IO uint32_t temp = 0;
__IO uint32_t Timeout = 0;
/* Enable Error IT (used in all modes: DMA, Polling and Interrupts */
I2Cx->CR2 |= I2C_IT_ERR;
if (Mode == DMA) /* I2Cx Master Transmission using DMA */
{
Timeout = 0xFFFF;
/* Configure the DMA channel for I2Cx transmission */
I2C_DMAConfig (I2Cx, pBuffer, NumByteToWrite, I2C_DIRECTION_TX);
/* Enable the I2Cx DMA requests */
I2Cx->CR2 |= CR2_DMAEN_Set;
/* Send START condition */
I2Cx->CR1 |= CR1_START_Set;
/* Wait until SB flag is set: EV5 */
while ((I2Cx->SR1&0x0001) != 0x0001)
{
if (Timeout-- == 0)
return Error;
}
Timeout = 0xFFFF;
/* Send slave address */
/* Reset the address bit0 for write */
SlaveAddress &= OAR1_ADD0_Reset;
Address = SlaveAddress;
/* Send the slave address */
I2Cx->DR = Address;
/* Wait until ADDR is set: EV6 */
while ((I2Cx->SR1&0x0002) != 0x0002)
{
if (Timeout-- == 0)
return Error;
}
/* Clear ADDR flag by reading SR2 register */
temp = I2Cx->SR2;
if (I2Cx == I2C1)
{
/* Wait until DMA end of transfer */
while (!DMA_GetFlagStatus(DMA1_FLAG_TC6));
/* Disable the DMA1 Channel 6 */
DMA_Cmd(I2C1_DMA_CHANNEL_TX, DISABLE);
/* Clear the DMA Transfer complete flag */
DMA_ClearFlag(DMA1_FLAG_TC6);
}
else /* I2Cx = I2C2 */
{
/* Wait until DMA end of transfer */
while (!DMA_GetFlagStatus(DMA1_FLAG_TC4));
/* Disable the DMA1 Channel 4 */
DMA_Cmd(I2C2_DMA_CHANNEL_TX, DISABLE);
/* Clear the DMA Transfer complete flag */
DMA_ClearFlag(DMA1_FLAG_TC4);
}
/* EV8_2: Wait until BTF is set before programming the STOP */
while ((I2Cx->SR1 & 0x00004) != 0x000004);
/* Program the STOP */
I2Cx->CR1 |= CR1_STOP_Set;
/* Make sure that the STOP bit is cleared by Hardware */
while ((I2Cx->CR1&0x200) == 0x200);
}
else if (Mode == Polling) /* I2Cx Master Transmission using Polling */
{
Timeout = 0xFFFF;
/* Send START condition */
I2Cx->CR1 |= CR1_START_Set;
/* Wait until SB flag is set: EV5 */
while ((I2Cx->SR1&0x0001) != 0x0001)
{
if (Timeout-- == 0)
return Error;
}
/* Send slave address */
/* Reset the address bit0 for write*/
SlaveAddress &= OAR1_ADD0_Reset;
Address = SlaveAddress;
/* Send the slave address */
I2Cx->DR = Address;
Timeout = 0xFFFF;
/* Wait until ADDR is set: EV6 */
while ((I2Cx->SR1 &0x0002) != 0x0002)
{
if (Timeout-- == 0)
return Error;
}
/* Clear ADDR flag by reading SR2 register */
temp = I2Cx->SR2;
/* Write the first data in DR register (EV8_1) */
I2Cx->DR = *pBuffer;
/* Increment */
pBuffer++;
/* Decrement the number of bytes to be written */
NumByteToWrite--;
/* While there is data to be written */
while (NumByteToWrite--)
{
/* Poll on BTF to receive data because in polling mode we can not guarantee the
EV8 software sequence is managed before the current byte transfer completes */
while ((I2Cx->SR1 & 0x00004) != 0x000004);
/* Send the current byte */
I2Cx->DR = *pBuffer;
/* Point to the next byte to be written */
pBuffer++;
}
/* EV8_2: Wait until BTF is set before programming the STOP */
while ((I2Cx->SR1 & 0x00004) != 0x000004);
/* Send STOP condition */
I2Cx->CR1 |= CR1_STOP_Set;
/* Make sure that the STOP bit is cleared by Hardware */
while ((I2Cx->CR1&0x200) == 0x200);
}
else /* I2Cx Master Transmission using Interrupt with highest priority in the application */
{
/* Enable EVT IT*/
I2Cx->CR2 |= I2C_IT_EVT;
/* Enable BUF IT */
I2Cx->CR2 |= I2C_IT_BUF;
/* Set the I2C direction to Transmission */
I2CDirection = I2C_DIRECTION_TX;
SlaveAddress &= OAR1_ADD0_Reset;
Address = SlaveAddress;
if (I2Cx == I2C1) NumbOfBytes1 = NumByteToWrite;
else NumbOfBytes2 = NumByteToWrite;
/* Send START condition */
I2Cx->CR1 |= CR1_START_Set;
/* Wait until the START condition is generated on the bus: the START bit is cleared by hardware */
while ((I2Cx->CR1&0x100) == 0x100);
/* Wait until BUSY flag is reset: a STOP has been generated on the bus signaling the end
of transmission */
while ((I2Cx->SR2 &0x0002) == 0x0002);
}
return Success;
}
В polling mode посылается адрес устройства с первым битом настроеным на запись или чтение... и сразу пишутся/читаются данные. Нигде не указан адрес регистра с которого читать/писать данные. Я что то не понимаю?