STM32 내부 Flash Memory 는 파일 시스템으로 구현하거나 복잡한 메모리 맵핑을 구현해야하는 관계로,
간단한 메모리 기능을 활용하기 위해 별도로 EEPROM와 같은 외부 메모리를 STM32 보드에 실장을 해서,
메모리 Read / Write 기능을 구현하면 어떨까 해서 개발을 해봤다.
그래서 적용할 외부 메모리를 찾다가, Atmel사의 AT24C128/256 EEPROM 메모리를 사용하였고,
모델명에서 128은 128k bits, 256은 256k bits만큼 메모리에 저장을 할 수 있다는 의미이다.
이 EEPROM을 I2C 데이터 통신 라이브러리를 사용하여 소스 구현을 하였는데, 그 소스는 아래와 같다.
void AT24CXXX_EEPROM_Write(uint8_t Address, uint16_t addr, uint8_t* pBuffer, uint16_t NumByteToWrite)
{
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on EV5 and clear it */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* Send slave address for write */
I2C_Send7bitAddress(I2C1,Address, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, addr >> 8);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, addr & 0x00FF);
/* Test on EV6 and clear it */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, *pBuffer);
pBuffer++;
NumByteToWrite--;
/* While there is data to be written */
while (NumByteToWrite--)
{
while ((I2C_GetLastEvent(I2C1) & 0x04) != 0x04); /* Poll on BTF */
/* Send the current byte */
I2C_SendData(I2C1, *pBuffer);
/* Point to the next byte to be written */
pBuffer++;
}
/* Test on EV8_2 and clear it, BTF = TxE = 1, DR and shift registers are empty */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* Send STOP condition */
I2C_GenerateSTOP(I2C1, ENABLE);
}
void AT24CXXX_EEPROM_Read(uint8_t Address, uint16_t addr, uint8_t* pBuffer, uint16_t NumByteToWrite)
{
__IO uint32_t temp;
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on EV5 and clear it */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* Send slave address for write */
I2C_Send7bitAddress(I2C1,Address, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, addr >> 8);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, addr & 0x00FF);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_AcknowledgeConfig(I2C1, DISABLE);
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on EV5 and clear it */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* Send EEPROM address for read */
I2C_Send7bitAddress(I2C1,Address, I2C_Direction_Receiver);
/* Wait until ADDR is set */
while (!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR));
/* Clear ACK */
I2C_AcknowledgeConfig(I2C1, DISABLE);
__disable_irq();
/* Clear ADDR flag */
temp = I2C1->SR2;
/* Program the STOP */
I2C_GenerateSTOP(I2C1, ENABLE);
__enable_irq();
while ((I2C_GetLastEvent(I2C1) & 0x0040) != 0x000040); /* Poll on RxNE */
/* Read the data */
*pBuffer = I2C_ReceiveData(I2C1);
/* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
while ((I2C1->CR1&0x200) == 0x200);
/* Enable Acknowledgement to be ready for another reception */
I2C_AcknowledgeConfig(I2C1, ENABLE);
}
I2C 라이브러리는 STM32 공식 라이브러리를 사용하였으니, STM32 홈페이지에서 참조를 하시면 될테다.
찾는 수고를 덜어드리기 위해, 라이브러리를 첨부하였으니 참조하시길 바랍니다!
그리고 AT24C128/256 데이터시트와 함께 첨부를 하니 참조를 하시길 바란다! (데이터시트내 I2C 통신 방법 참조)
궁금하신 사항이 있다면, 댓글을~