MCU
|
STM32F103(ST)
|
IDE
|
Atollic(TrueSTUDIO), STM32CubeMX
|
목표
|
HAL driver를 사용하여 I2C EEPROM 쓰고 읽기
|
1. STM32F103C8 - I2C EEPROM 회로도

- SDA, SCL pull-up 저항 값은 아래와 같이 설정되므로 적당히 아무거나(10k) 붙이면 통신이 안될수도 있음(NXP, UM10204 참고)

2. STM32CubeMX : I2C 설정
- 'Pinout & Configuration' Tab으로 이동
1) I2C1 선택
2) I2C : I2C 선택
3) I2C Clock Speed는 기본 100kHz로 설정된다. 사용하려는 device가 이 속도를 지원하는지 확인 할것
- PB7(I2C1_SDA), PB6(I2C1_SCL) 자동 할당(녹색 표시)

- GENERATE CODE 클릭
3. ATOLLIC : main.c 수정
- main() : 변수 선언
int main(void)
{
/* USER CODE BEGIN 1 */
HAL_StatusTypeDef status = HAL_ERROR;
int i = 0;
uint16_t FM24V02_addr = 0xA0;
uint8_t tx_buffer[65] = {};
uint8_t rx_buffer[65] = {};
/* USER CODE END 1 */
- Address는 A2, A1, A0를 GND('0')에 연결하여 '0b1010000'이다.

- HAL_I2C_Mem_Write(), Read() 사용하려면 7bit address를 <<1 shift 하라고 되어있으므로 최종 주소는 '0xA0' (HAL_I2C_Mem_Write() 설명은 ATOLLIC에서 함수 이름에 마우스 커서를 올려놓거나, 키보드 F3을 누르거나 또는 HAL lib manual에서 확인 가능)

- main() : 실행 코드 작성
/* USER CODE BEGIN 2 */
tx_buffer[0] = 0x12;
// Byte Write
status = HAL_I2C_Mem_Write(&hi2c1, FM24V02_addr, 0x0001, 2, tx_buffer, 1, 1000);
if(status != HAL_OK)
{
printf("I2C Byte Write error\n");
}
// Byte Read
status = HAL_I2C_Mem_Read(&hi2c1, FM24V02_addr, 0x0001, 2, rx_buffer, 1, 1000);
if(status == HAL_OK)
{
printf("Byte Read : %d\n", rx_buffer[0]);
}
else
{
printf("I2C Byte Read error\n");
}
// Page Write
for (i = 0; i < 64; i++)
{
tx_buffer[i] = i;
}
status = HAL_I2C_Mem_Write(&hi2c1, FM24V02_addr, 0x0100, 2, tx_buffer, 64, 1000);
if(status != HAL_OK)
{
printf("I2C Page Write error\n");
}
// Page Read
status = HAL_I2C_Mem_Read(&hi2c1, FM24V02_addr, 0x0100, 2, rx_buffer, 64, 1000);
if(status == HAL_OK)
{
for (i = 0; i < 64; i++)
{
printf("Page Read(%d) : %d\n", i, rx_buffer[i]);
}
}
else
{
printf("I2C Page Read error\n");
}
/* USER CODE END 2 */
- 실행 결과

- 실행 결과 이하 생략
- 참고 : 일부러 Address를 틀리게 썼을때 실행 결과

4. 8bit 데이터는 위와 같이 하면 문제 없이 동작하나, 16bit 데이터(256이상)를 쓰고 읽어오려면 약간 다른 방법으로 해야 한다.
- write() : 16bit 데이터를 8bit로 쪼개서 쓰기
- read() : 8bit씩 읽어서 16bit로 합침
uint16_t FM24V02_addr = 0xA0;
uint8_t reg_addr = 0x0001;
uint8_t data_8bit = 0;
uint16_t data_16bit[65] = {};
void eeprom_i2c_write(uint16_t size)
{
HAL_StatusTypeDef status = HAL_ERROR;
reg_addr = 0x0001;
for(int i = 0; i< size; i++)
{
data_8bit = (uint8_t)(data_16bit[i] >> 8);
status = HAL_I2C_Mem_Write(&hi2c1, FM24V02_addr, reg_addr+(i*2), 2, &data_8bit, 1, 1000);
HAL_Delay(10);
data_8bit = (uint8_t)(data_16bit[i] & 0xff);
status = HAL_I2C_Mem_Write(&hi2c1, FM24V02_addr, reg_addr+(i*2)+1, 2, &data_8bit, 1, 1000);
if(status != HAL_OK)
{
printf("EEPROM Byte Write error : %d\n", status);
}
}
}
void eeprom_i2c_read(uint16_t size)
{
HAL_StatusTypeDef status = HAL_ERROR;
reg_addr = 0x0001;
for(int i = 0; i< size; i++)
{
status = HAL_I2C_Mem_Read(&hi2c1, FM24V02_addr, reg_addr+(i*2), 2, &data_8bit , 1, 1000);
data_16bit[i] = data_8bit << 8;
HAL_Delay(10);
status = HAL_I2C_Mem_Read(&hi2c1, FM24V02_addr, reg_addr+(i*2)+1, 2, &data_8bit , 1, 1000);
data_16bit[i] += data_8bit;
if(status == HAL_OK)
{
printf("EEPROM Page Read(%d) : %d\n", i, data_16bit[i]);
}
else
{
printf("EEPROM Byte Read error\n");
}
}
}
'ST > STM32F103C8' 카테고리의 다른 글
STM32F103C8 - I2C HAL driver 오류 (0) | 2025.08.08 |
---|---|
STM32F103C8 - ADC(DMA interrupt) (1) | 2025.08.08 |
STM32F103C8 - RTC(Systick handler) (0) | 2025.08.08 |
STM32F103C8 - PWM (0) | 2025.08.08 |
STM32F103C8 - TIMER (1) | 2025.08.08 |