아래는 STM32L432KC에서 ZSC31014의 Normal Operation Mode(Update Mode 또는 Sleep Mode)에서 **센서 데이터(브리지 데이터, 14비트)**와 **온도 데이터(8비트 또는 11비트)**를 I²C 인터페이스를 통해 읽는 C 코드를 제공합니다. 이 코드는 이전에 제공한 EEPROM 읽기/쓰기 코드(zsc31014_eeprom.c)에 추가로 통합되며, 동일한 STM32 HAL 라이브러리를 사용합니다. ZSC31014 데이터시트(REN_ZSC31014_DST_20160120_1.pdf, 페이지 33~36)를 기반으로 작성되었습니다.
가정 및 설정
- MCU: STM32L432KC, HAL 라이브러리 사용.
- I²C 설정:
- ZSC31014 슬레이브 주소: 0x28 (EEPROM 워드 02HEX, 비트 [9:3], 7비트 주소 왼쪽 시프트).
- I²C 클럭 속도: 100kHz (데이터시트 페이지 20, 100kHz 또는 400kHz 지원).
- Normal Operation Mode:
- Update Mode: 설정된 주기(Update_Rate, 워드 01HEX 비트 [5:4])로 자동 측정.
- Sleep Mode: Read_MR 또는 Write_MR로 측정 요청 후 데이터 읽기.
- 데이터 읽기 명령: Read_DF2 (브리지 14비트), Read_DF3 (브리지 + 8비트 온도), Read_DF4 (브리지 + 11비트 온도).
- 데이터 구조 (페이지 33, Figure 3.6):
- 1바이트: {S[1:0], B[13:8]} (상태 비트 + 브리지 상위 6비트).
- 2바이트: {B[7:0]} (브리지 하위 8비트).
- 3바이트: {T[10:3]} (온도 상위 8비트).
- 4바이트: {T[2:0], xxxxx} (온도 하위 3비트 + 5비트 무시).
- EEPROM 설정:
- 워드 01HEX: Output_Mode = 0 (I²C), Temp_Res = 1 (11비트 온도), ClkSpeed = 0 (1MHz).
- 워드 0FHEX (B_Config): PreAmp_Gain = 010 (6), A2D_Offset = 1000 (-1/2 ~ 1/2).
- 주의사항:
- Sleep Mode에서 첫 번째 Write_MR은 초기화되지 않은 데이터 반환 가능(페이지 31).
- 상태 비트(S[1:0] = 11)로 EEPROM 무결성/센서 오류 확인(페이지 24).
- 이전 코드의 함수(zsc31014_start_cm, zsc31014_start_nom 등)를 재사용.
#include "stm32l4xx_hal.h" // STM32 HAL 라이브러리 포함 (I2C 및 GPIO 제어에 필요)
#include <string.h> // 메모리 조작 함수 (예: memset)
#include <stdio.h> // printf 함수 사용 (디버깅 로그 출력)
// I2C 핸들러: STM32CubeMX에서 설정된 I2C1 핸들러를 extern으로 선언
// 이 핸들러는 I2C 통신을 담당하며, CubeMX에서 생성된 코드에서 정의됨
extern I2C_HandleTypeDef hi2c1;
// ZSC31014 I2C 슬레이브 주소: 데이터시트 페이지 20에 따라 기본 7비트 주소 0x28
// 왼쪽 시프트(<<1)하여 8비트 주소로 변환 (HAL_I2C에서 요구)
#define ZSC31014_I2C_ADDR (0x28 << 1)
// 명령 코드: 데이터시트 페이지 37, Table 3.6 참조
// CMD_START_CM: Command Mode 진입 명령
// CMD_START_NOM: Normal Operation Mode 복귀 명령
// CMD_EEPROM_READ_BASE: EEPROM 읽기 명령 베이스 (워드 주소 + 베이스)
// CMD_EEPROM_WRITE_BASE: EEPROM 쓰기 명령 베이스 (워드 주소 + 베이스)
#define CMD_START_CM 0xA0
#define CMD_START_NOM 0x80
#define CMD_EEPROM_READ_BASE 0x00
#define CMD_EEPROM_WRITE_BASE 0x40
// I2C 통신 타임아웃: 100ms로 설정 (HAL_I2C 함수에서 사용)
#define I2C_TIMEOUT 100
// GPIO for VDD control: ZSC31014 VDD 전원 제어를 위한 GPIO 핀 정의
// 가정: GPIOA의 Pin 0을 사용, HIGH = VDD ON, LOW = VDD OFF
// STM32CubeMX에서 Output으로 설정해야 함
#define ZSC_VDD_GPIO_PORT GPIOA
#define ZSC_VDD_GPIO_PIN GPIO_PIN_0
// 함수 프로토타입 선언: 코드 컴파일을 위해 미리 선언
HAL_StatusTypeDef zsc31014_power_cycle(void); // 전원 사이클링 함수
HAL_StatusTypeDef zsc31014_start_cm(void); // Command Mode 진입
HAL_StatusTypeDef zsc31014_start_nom(void); // Normal Operation Mode 복귀
HAL_StatusTypeDef zsc31014_read_sensor_data(uint16_t *bridge_data, uint16_t *temp_data, uint8_t temp_res_11bit); // 센서 데이터 읽기
HAL_StatusTypeDef zsc31014_trigger_measurement(void); // Sleep Mode에서 측정 트리거 (Write_MR)
HAL_StatusTypeDef zsc31014_read_eeprom(uint8_t word_addr, uint16_t *data); // 단일 EEPROM 워드 읽기
HAL_StatusTypeDef zsc31014_write_eeprom(uint8_t word_addr, uint16_t data); // 단일 EEPROM 워드 쓰기
HAL_StatusTypeDef zsc31014_read_all_eeprom(uint16_t *data_array); // 전체 EEPROM 읽기 (0x00 ~ 0x13)
HAL_StatusTypeDef zsc31014_write_all_eeprom(uint16_t *data_array); // 전체 EEPROM 쓰기 (0x00 ~ 0x13)
/**
* @brief ZSC31014 VDD 전원 OFF/ON (리셋 용도)
* 데이터시트 페이지 23 (2.3.6 POR) 참조: IC 리셋을 위해 전원 사이클링 필요
* @retval HAL_OK 성공, 그 외 에러
*/
HAL_StatusTypeDef zsc31014_power_cycle(void) {
// VDD OFF: GPIO를 LOW로 설정하여 외부 스위치 OFF (전원 차단)
HAL_GPIO_WritePin(ZSC_VDD_GPIO_PORT, ZSC_VDD_GPIO_PIN, GPIO_PIN_RESET);
HAL_Delay(10); // 최소 10ms OFF 유지: POR 안정화 위해 지연 (데이터시트 POR 레벨 1.8~2.5V, 페이지 7 Table 1.3)
// VDD ON: GPIO를 HIGH로 설정하여 외부 스위치 ON (전원 공급)
HAL_GPIO_WritePin(ZSC_VDD_GPIO_PORT, ZSC_VDD_GPIO_PIN, GPIO_PIN_SET);
HAL_Delay(10); // ON 후 안정화 대기: 데이터시트 페이지 28 Figure 3.2 참조 (Power-Up 후 ~3ms 대기)
printf("ZSC31014 전원 사이클링 완료\n"); // 디버깅 로그 출력
return HAL_OK;
}
/**
* @brief Command Mode 진입 (전원 사이클링 후)
* 데이터시트 페이지 37: Start_CM 명령 (0xA0) + don't care 데이터 2바이트
* @retval HAL_OK 성공, 그 외 에러
*/
HAL_StatusTypeDef zsc31014_start_cm(void) {
HAL_StatusTypeDef status;
// Start_CM 전에 전원 사이클링: IC 상태 클리어 (사용자 지적 사항 적용, 데이터시트 페이지 26 3.1 참조)
status = zsc31014_power_cycle();
if (status != HAL_OK) return status;
// Start_CM 명령 + don't care 데이터 (0x0000) 전송
uint8_t tx_data[3] = {CMD_START_CM, 0x00, 0x00};
status = HAL_I2C_Master_Transmit(&hi2c1, ZSC31014_I2C_ADDR, tx_data, 3, I2C_TIMEOUT);
if (status != HAL_OK) {
printf("Start_CM 실패: %d\n", status); // 에러 로그
return status;
}
HAL_Delay(1); // 명령 완료 대기: 데이터시트 페이지 37 (10us 대기)
return HAL_OK;
}
/**
* @brief Normal Operation Mode 복귀 및 EEPROM 서명 업데이트
* 데이터시트 페이지 37: Start_NOM 명령 (0x80) + don't care 데이터 2바이트
* @retval HAL_OK 성공, 그 외 에러
*/
HAL_StatusTypeDef zsc31014_start_nom(void) {
HAL_StatusTypeDef status;
// Start_NOM 명령 + don't care 데이터 (0x0000) 전송
uint8_t tx_data[3] = {CMD_START_NOM, 0x00, 0x00};
status = HAL_I2C_Master_Transmit(&hi2c1, ZSC31014_I2C_ADDR, tx_data, 3, I2C_TIMEOUT);
if (status != HAL_OK) {
printf("Start_NOM 실패: %d\n", status); // 에러 로그
return status;
}
// 서명 업데이트 포함 최대 15ms 대기: 데이터시트 페이지 37
HAL_Delay(15);
return HAL_OK;
}
/**
* @brief 센서(브리지) 데이터와 온도 데이터 읽기
* 데이터시트 페이지 33 Figure 3.6: Read_DF3 (8비트 온도) 또는 Read_DF4 (11비트 온도)
* @param bridge_data 브리지 데이터(14비트) 저장 포인터
* @param temp_data 온도 데이터(8비트 또는 11비트) 저장 포인터
* @param temp_res_11bit 온도 해상도 (0: 8비트, 1: 11비트) - 데이터시트 페이지 38 Config_Reg[3]
* @retval HAL_OK 성공, 그 외 에러
*/
HAL_StatusTypeDef zsc31014_read_sensor_data(uint16_t *bridge_data, uint16_t *temp_data, uint8_t temp_res_11bit) {
HAL_StatusTypeDef status;
uint8_t rx_data[4]; // 최대 4바이트 수신 버퍼 (브리지 2바이트 + 온도 1~2바이트)
uint8_t byte_count = temp_res_11bit ? 4 : 3; // 11비트 온도: 4바이트, 8비트: 3바이트
// 데이터 읽기: HAL_I2C_Master_Receive로 Read_DF 요청 (데이터시트 페이지 34)
status = HAL_I2C_Master_Receive(&hi2c1, ZSC31014_I2C_ADDR, rx_data, byte_count, I2C_TIMEOUT);
if (status != HAL_OK) {
printf("센서 데이터 수신 실패: %d\n", status); // 에러 로그
return status;
}
// 상태 비트 확인: 데이터시트 페이지 24 Table 2.9 (첫 바이트 상위 2비트 S[1:0])
uint8_t status_bits = (rx_data[0] >> 6) & 0x03;
if (status_bits == 0x03) {
printf("진단 오류: EEPROM 무결성 또는 센서 오류\n"); // 오류: EEPROM/센서 문제
return HAL_ERROR;
} else if (status_bits == 0x02) {
printf("경고: Stale 데이터\n"); // 경고: 오래된 데이터
}
// 브리지 데이터 (14비트) 조합: 첫 바이트 하위 6비트 + 두 번째 바이트
*bridge_data = ((rx_data[0] & 0x3F) << 8) | rx_data[1];
// 온도 데이터 조합
if (byte_count >= 3) {
if (temp_res_11bit) {
// 11비트 온도: 세 번째 바이트 << 3 + 네 번째 바이트 상위 3비트
*temp_data = (rx_data[2] << 3) | ((rx_data[3] >> 5) & 0x07);
} else {
// 8비트 온도: 세 번째 바이트만
*temp_data = rx_data[2];
}
} else {
*temp_data = 0; // 온도 데이터 요청되지 않음
}
// 디버깅 로그: 읽은 데이터 출력
printf("브리지 데이터: 0x%04X, 온도 데이터: 0x%04X\n", *bridge_data, *temp_data);
return HAL_OK;
}
/**
* @brief Sleep Mode에서 측정 요청 (Write_MR)
* 데이터시트 페이지 36 Figure 3.9: Write_MR (빈 쓰기)로 깨우기
* @retval HAL_OK 성공, 그 외 에러
*/
HAL_StatusTypeDef zsc31014_trigger_measurement(void) {
HAL_StatusTypeDef status;
uint16_t config_reg;
// Write_MR 전송: 빈 데이터 쓰기 (HAL_I2C_Master_Transmit에 size 0)
status = HAL_I2C_Master_Transmit(&hi2c1, ZSC31014_I2C_ADDR, NULL, 0, I2C_TIMEOUT);
if (status != HAL_OK) {
printf("Write_MR 실패: %d\n", status); // 에러 로그
return status;
}
// 클럭 설정 읽기: Config_Reg (워드 0x00) 비트 [10]으로 1MHz/4MHz 확인 (페이지 38 Table 3.7)
status = zsc31014_read_eeprom(0x00, &config_reg);
if (status != HAL_OK) {
printf("Config_Reg 읽기 실패\n");
return status;
}
uint8_t clk_4mhz = (config_reg & (1 << 10)) ? 1 : 0; // 비트 10: 1=4MHz, 0=1MHz
// 측정 완료 대기: 데이터시트 페이지 31 Table 3.4-3.5 (Normal Integration 기준)
// 4MHz: ~1.5ms, 1MHz: ~6ms -> 안전하게 2ms/6ms 설정
HAL_Delay(clk_4mhz ? 2 : 6);
return HAL_OK;
}
/**
* @brief 특정 EEPROM 워드 읽기 (Command Mode에서 호출 가정)
* 데이터시트 페이지 37: 읽기 명령 (0x00 + word_addr) + 데이터 수신 (0x5A + 16비트)
* @param word_addr 워드 주소 (0x00 ~ 0x13)
* @param data 읽은 16비트 데이터 저장 포인터
* @retval HAL_OK 성공, 그 외 에러
*/
HAL_StatusTypeDef zsc31014_read_eeprom(uint8_t word_addr, uint16_t *data) {
HAL_StatusTypeDef status;
uint8_t tx_data[3] = {CMD_EEPROM_READ_BASE + word_addr, 0x00, 0x00}; // 읽기 명령 + don't care
uint8_t rx_data[3]; // 수신 버퍼: 0x5A + 데이터 2바이트
if (word_addr > 0x13) { // 유효 범위 확인: 데이터시트 페이지 38 Table 3.7 (0x00~0x13)
printf("잘못된 워드 주소: 0x%02X\n", word_addr);
return HAL_ERROR;
}
// 읽기 명령 전송
status = HAL_I2C_Master_Transmit(&hi2c1, ZSC31014_I2C_ADDR, tx_data, 3, I2C_TIMEOUT);
if (status != HAL_OK) {
printf("EEPROM 읽기 명령 전송 실패 (워드 0x%02X): %d\n", word_addr, status);
return status;
}
// 데이터 수신
status = HAL_I2C_Master_Receive(&hi2c1, ZSC31014_I2C_ADDR, rx_data, 3, I2C_TIMEOUT);
if (status != HAL_OK) {
printf("EEPROM 데이터 수신 실패 (워드 0x%02X): %d\n", word_addr, status);
return status;
}
// 첫 바이트 확인: 0x5A여야 함 (데이터시트 페이지 37)
if (rx_data[0] != 0x5A) {
printf("EEPROM 읽기 응답 오류 (워드 0x%02X): 0x%02X\n", word_addr, rx_data[0]);
return HAL_ERROR;
}
// 16비트 데이터 조합: 상위 바이트 + 하위 바이트
*data = (rx_data[1] << 8) | rx_data[2];
printf("워드 0x%02X: 0x%04X\n", word_addr, *data); // 디버깅 로그
return HAL_OK;
}
/**
* @brief 특정 EEPROM 워드 쓰기 (Command Mode에서 호출 가정)
* 데이터시트 페이지 37: 쓰기 명령 (0x40 + word_addr) + 16비트 데이터
* @param word_addr 워드 주소 (0x00 ~ 0x13)
* @param data 쓸 16비트 데이터
* @retval HAL_OK 성공, 그 외 에러
*/
HAL_StatusTypeDef zsc31014_write_eeprom(uint8_t word_addr, uint16_t data) {
HAL_StatusTypeDef status;
if (word_addr > 0x13) { // 유효 범위 확인
printf("잘못된 워드 주소: 0x%02X\n", word_addr);
return HAL_ERROR;
}
// T_Config(0x10), Osc_Trim(0x11) 쓰기 금지: 데이터시트 페이지 38 (공장 트림 유지)
if (word_addr == 0x10 || word_addr == 0x11) {
printf("오류: 워드 0x%02X 쓰기 금지 (공장 트림)\n", word_addr);
return HAL_ERROR;
}
// 쓰기 명령 + 데이터: 상위 바이트 + 하위 바이트
uint8_t tx_data[3] = {
CMD_EEPROM_WRITE_BASE + word_addr,
(data >> 8) & 0xFF,
data & 0xFF
};
// 명령 전송
status = HAL_I2C_Master_Transmit(&hi2c1, ZSC31014_I2C_ADDR, tx_data, 3, I2C_TIMEOUT);
if (status != HAL_OK) {
printf("EEPROM 쓰기 실패 (워드 0x%02X): %d\n", word_addr, status);
return status;
}
// 쓰기 완료 대기: 데이터시트 페이지 37 (10ms)
HAL_Delay(10);
printf("워드 0x%02X에 0x%04X 쓰기 완료\n", word_addr, data); // 디버깅 로그
return HAL_OK;
}
/**
* @brief 전체 EEPROM 읽기 (0x00 ~ 0x13)
* Command Mode에서 모든 워드 읽기 (중복 Mode 진입 방지 위해 루프 밖에서 Mode 설정)
* @param data_array 20개 워드(16비트)를 저장할 배열
* @retval HAL_OK 성공, 그 외 에러
*/
HAL_StatusTypeDef zsc31014_read_all_eeprom(uint16_t *data_array) {
HAL_StatusTypeDef status;
// Command Mode 진입: 루프 밖에서 한 번만 호출 (최적화)
status = zsc31014_start_cm();
if (status != HAL_OK) {
printf("Command Mode 진입 실패\n");
return status;
}
// 워드 0x00 ~ 0x13 읽기 루프
for (uint8_t word_addr = 0x00; word_addr <= 0x13; word_addr++) {
status = zsc31014_read_eeprom(word_addr, &data_array[word_addr]);
if (status != HAL_OK) {
printf("EEPROM 읽기 실패 (워드 0x%02X)\n", word_addr);
zsc31014_start_nom(); // 에러 시 NOM 복귀
return status;
}
}
// Normal Operation Mode 복귀
status = zsc31014_start_nom();
if (status != HAL_OK) {
printf("Normal Operation Mode 복귀 실패\n");
return status;
}
return HAL_OK;
}
/**
* @brief 전체 EEPROM 쓰기 (0x00 ~ 0x13)
* Command Mode에서 모든 워드 쓰기 (중복 Mode 진입 방지 위해 루프 밖에서 Mode 설정)
* @param data_array 쓸 20개 워드(16비트) 데이터 배열
* @retval HAL_OK 성공, 그 외 에러
*/
HAL_StatusTypeDef zsc31014_write_all_eeprom(uint16_t *data_array) {
HAL_StatusTypeDef status;
// Command Mode 진입: 루프 밖에서 한 번만 호출 (최적화)
status = zsc31014_start_cm();
if (status != HAL_OK) {
printf("Command Mode 진입 실패\n");
return status;
}
// 워드 0x00 ~ 0x13 쓰기 루프
for (uint8_t word_addr = 0x00; word_addr <= 0x13; word_addr++) {
status = zsc31014_write_eeprom(word_addr, data_array[word_addr]);
if (status != HAL_OK) {
printf("EEPROM 쓰기 실패 (워드 0x%02X)\n", word_addr);
zsc31014_start_nom(); // 에러 시 NOM 복귀
return status;
}
}
// Normal Operation Mode 복귀 및 서명 업데이트
status = zsc31014_start_nom();
if (status != HAL_OK) {
printf("Normal Operation Mode 복귀 실패\n");
return status;
}
return HAL_OK;
}
/**
* @brief 메인 함수 예시 (사용 예시)
* 실제 애플리케이션에서 호출하여 테스트
*/
void zsc31014_example(void) {
HAL_StatusTypeDef status;
uint16_t eeprom_data[20]; // 0x00 ~ 0x13 워드 저장 배열
uint16_t bridge_data, temp_data;
// 전체 EEPROM 읽기
printf("EEPROM 전체 읽기 시작\n");
status = zsc31014_read_all_eeprom(eeprom_data);
if (status != HAL_OK) {
printf("EEPROM 전체 읽기 실패\n");
return;
}
// 특정 워드 읽기 (예: 워드 0x01)
uint16_t single_data;
printf("워드 0x01 읽기 시작\n");
// 전체 읽기 후 Command Mode 재진입 필요 (단일 읽기 시 start_cm/start_nom 별도 호출)
status = zsc31014_start_cm();
if (status == HAL_OK) {
status = zsc31014_read_eeprom(0x01, &single_data);
zsc31014_start_nom();
if (status == HAL_OK) {
printf("워드 0x01: 0x%04X\n", single_data);
} else {
printf("워드 0x01 읽기 실패\n");
}
}
// 특정 워드 쓰기 (예: 워드 0x01에 0x0000 쓰기)
printf("워드 0x01에 0x0000 쓰기 시작\n");
status = zsc31014_start_cm();
if (status == HAL_OK) {
status = zsc31014_write_eeprom(0x01, 0x0000);
zsc31014_start_nom();
if (status == HAL_OK) {
printf("워드 0x01 쓰기 완료\n");
} else {
printf("워드 0x01 쓰기 실패\n");
}
}
// 전체 EEPROM 쓰기 예시 (샘플 데이터)
uint16_t sample_data[20];
memset(sample_data, 0, sizeof(sample_data)); // 배열 0으로 초기화
sample_data[0x01] = 0x0004; // 예: I2C, 1MHz, 11비트 온도, Update_Rate=25ms (페이지 38 Table 3.7)
sample_data[0x02] = 0x0280; // 슬레이브 주소 0x28
sample_data[0x0F] = 0x0A80; // PreAmp_Gain=6, A2D_Offset=-1/2 ~ 1/2 (페이지 16 Table 2.4)
printf("EEPROM 전체 쓰기 시작\n");
status = zsc31014_write_all_eeprom(sample_data);
if (status == HAL_OK) {
printf("EEPROM 전체 쓰기 완료\n");
} else {
printf("EEPROM 전체 쓰기 실패\n");
}
// Sleep Mode에서 센서 데이터와 온도 데이터 읽기
printf("Sleep Mode에서 센서/온도 데이터 읽기 시작\n");
status = zsc31014_trigger_measurement(); // Write_MR로 깨우기
if (status == HAL_OK) {
status = zsc31014_read_sensor_data(&bridge_data, &temp_data, 1); // 11비트 온도
if (status != HAL_OK) {
printf("Sleep Mode 데이터 읽기 실패\n");
}
} else {
printf("Write_MR 실패\n");
}
// Update Mode에서 센서 데이터와 온도 데이터 읽기 (직접 Read_DF 호출, 데이터시트 페이지 33)
printf("Update Mode에서 센서/온도 데이터 읽기 시작\n");
status = zsc31014_read_sensor_data(&bridge_data, &temp_data, 1); // 11비트 온도
if (status != HAL_OK) {
printf("Update Mode 데이터 읽기 실패\n");
}
}
코드 변경 및 추가사항
- 새 함수 추가:
- zsc31014_read_sensor_data():
- 센서(브리지) 데이터(14비트)와 온도 데이터(8비트 또는 11비트)를 읽음.
- temp_res_11bit 매개변수로 온도 해상도 선택(EEPROM 워드 01HEX 비트 2와 일치해야 함).
- 상태 비트(S[1:0]) 확인 후 오류/경고 처리.
- 데이터 패킷에서 브리지와 온도 데이터 추출.
- zsc31014_trigger_measurement():
- Sleep Mode에서 Write_MR 명령으로 측정 요청.
- 1MHz 클럭 기준 1.5ms 대기(페이지 31, Table 3.4).
- 기존 함수(zsc31014_start_cm, zsc31014_start_nom 등)는 변경 없이 재사용.
- zsc31014_read_sensor_data():
- 예시 함수 업데이트:
- zsc31014_example()에 Sleep Mode와 Update Mode에서의 데이터 읽기 추가.
- 샘플 EEPROM 데이터에 Update_Rate(25ms), PreAmp_Gain(6), A2D_Offset(-1/2 ~ 1/2) 설정 포함.
- sample_data[0x01] = 0x0004: I²C, 1MHz, 11비트 온도, Update_Rate=25ms.
- sample_data[0x0F] = 0x0A80: PreAmp_Gain=6, A2D_Offset=-1/2 ~ 1/2, Bsink 활성화.
- 타이밍:
- Sleep Mode Write_MR: 1.5ms 대기 (1MHz 클럭, 페이지 31).
- Update Mode: Update_Rate에 따라 주기적 데이터 갱신(예: 25ms, 페이지 29).
- HAL_Delay로 충분한 대기 시간 확보.
- 에러 처리:
- 상태 비트(S[1:0])로 진단 오류(11) 또는 Stale 데이터(10) 확인.
- HAL 함수 반환값으로 I²C 통신 오류 체크.
사용 방법
- STM32CubeMX 설정:
- I²C1: 100kHz, 7비트 주소, SCL(PB6), SDA(PB7), 풀업 저항(1kΩ~10kΩ, 페이지 6).
- UART: 디버깅용 printf 출력(선택 사항).
- hi2c1 핸들러 초기화.
- 코드 통합:
- 위 코드를 기존 프로젝트에 통합하거나 zsc31014_eeprom.c로 대체.
- main.c에서 zsc31014_example() 호출.
- 하드웨어 연결:
- ZSC31014 VDD: 3.3V (STM32L432KC와 동일).
- VSS: GND.
- SCL: PB6, SDA: PB7.
- VDD-GND 간 100nF~470nF 커패시터(페이지 6).
- I²C 라인에 2.2kΩ 풀업 저항.
- 빌드 및 테스트:
- STM32CubeIDE에서 빌드 및 플래시.
- 시리얼 터미널로 출력 확인(EEPROM 데이터, 센서/온도 데이터).
- Sleep Mode: Write_MR 후 Read_DF4로 데이터 읽기.
- Update Mode: 주기적 Read_DF4로 데이터 읽기.
- EEPROM 설정 확인:
- 워드 01HEX 비트 2 (Temp_Res)와 temp_res_11bit 매개변수 일치 필요.
- Update_Rate(워드 01HEX 비트 [5:4])로 Update Mode 주기 설정.
주의사항
- Sleep Mode 첫 데이터:
- 첫 번째 Write_MR은 초기화되지 않은 Auto-Zero/온도 데이터로 부정확할 수 있음. 두 번째 요청부터 확인(페이지 31).
- 상태 비트:
- S[1:0] = 11이면 EEPROM 서명 오류 또는 센서 단락. zsc31014_start_nom() 실행 후 재시도(페이지 24).
- EEPROM 설정:
- T_Config(0x10), Osc_Trim(0x11)은 공장 설정 유지 권장(페이지 41).
- sample_data는 응용에 맞게 수정(예: Gain_B, Offset_B 등).
- 타이밍:
- Sleep Mode에서 Write_MR 후 1.5ms 대기 필수. Update Mode는 Update_Rate에 따라 대기 조정.
- 디버깅:
- 시리얼 출력으로 상태 비트와 HAL 에러 코드 확인.
추가 참고
- 캘리브레이션:
- 센서 데이터가 부정확하면 워드 03HEX~09HEX (Gain_B, Offset_B, Tcg, Tco 등) 재설정 필요(페이지 44~48).
- Renesas 소프트웨어: 캘리브레이션 계수 계산에 사용(페이지 45).
- 문서: ZSC31014 Technical Note-Detailed Equations for Calibration Math 요청(페이지 56).