본문 바로가기
아날로그회로(Analog Circuit)/ADC관련

[ZSSC3240]STM32 I2C 인터페이스 코드 구현 가이드

by linuxgo 2025. 8. 12.
반응형

이 문서는 ZSSC3240 센서 신호 컨디셔너 IC의 데이터시트를 기반으로 한 STM32 마이크로컨트롤러와 I2C 인터페이스 구현에 대한 가이드입니다. Command List 설명, NVM 설정(Raw Mode와 Cyclic Mode), 코드 구현(모든 명령어)을 내용을 포함하고, 코드에는 상세한 주석을 추가하였습니다.

1.  기본 사양 및 Command List 설명

ZSSC3240 센서 신호 컨디셔너 IC의 데이터시트 기반으로 작성되었으며, ZSSC3240 IC 특징 다음과 같습니다:

  • Description: ZSSC3240은 저항성 센서(브리지, 하프-브리지 등)의 신호 증폭, 디지털화, 보정을 위한 IC입니다. I2C/SPI/OWI 인터페이스 지원, 26-bit math core로 오프셋/감도/온도/비선형 보정.
  • Features: SPI/I2C/OWI 인터페이스, PGA(1.32~540V/V), ADC(12~24-bit), DAC(13~16-bit), 온도 센서(내부/외부), 진단 기능 등.
  • Applications: 압력/유량/레벨 센싱, 산업/의료 등.
  • Block Diagram 및 Pin Assignments: 데이터시트 페이지 1~7에 상세 설명.
  • Electrical Characteristics: 페이지 8~10, 공급 전압 2.7~5.5V, 전류 소비 2.3mA 등.
  • Device Description: 페이지 11~58, 모드(Sleep/Command/Cyclic), 아날로그 프론트엔드(PGA/ADC), 인터페이스, 측정 옵션 등.

Command List 

Command Code (Byte) Return Description Available in Sleep Mode Available in Command Mode Available in Cyclic Mode
00HEX to 3FHEX 16-bit data Memory Read address 00HEX to 3FHEX: NVM에서 지정된 주소 내용을 읽음. Yes Yes No
40HEX to 75HEX followed by data (0000HEX to FFFFHEX) Memory Write addresses 00HEX to 35HEX: NVM에 데이터 쓰기. Yes Yes No
90HEX Calculate NVM Checksum and write it to the memory: NVM 체크섬 계산. Yes Yes No
A2HEX 24-bit raw data Raw Sensor Measurement: 원시 센서 측정. Yes Yes No
A4HEX 24-bit raw data Raw Temperature Measurement: 원시 온도 측정. Yes Yes No
A8HEX START_SLEEP: Sleep Mode 진입. No Yes Yes
A9HEX START_CM: Command Mode 진입. Yes No Yes
AAHEX 24-bit SSC-corrected sensor data and 24-bit SSC-corrected temperature data Measure: 전체 측정 및 SSC 보정. Yes Yes No
ABHEX START_CYC: Cyclic Mode 진입. Yes Yes No
ACHEX 24-bit SSC-corrected sensor data and 24-bit SSC-corrected temperature data Oversample-2 Measure: 2회 평균 측정. Yes Yes No
ADHEX 24-bit SSC-corrected sensor data and 24-bit SSC-corrected temperature data Oversample-4 Measure: 4회 평균 측정. Yes Yes No
AEHEX 24-bit SSC-corrected sensor data and 24-bit SSC-corrected temperature data Oversample-8 Measure: 8회 평균 측정. Yes Yes No
AFHEX 24-bit SSC-corrected sensor data and 24-bit SSC-corrected temperature data Oversample-16 Measure: 16회 평균 측정. Yes Yes No
B0HEX 16-bit diagnostic result data CHECK_DIAG: 진단 레지스터 읽기. Yes Yes No
B1HEX RESET_DIAG: 진단 레지스터 리셋. Yes Yes No
B2HEX UPDATE_DIAG: 전체 진단 업데이트. Yes Yes No
B3HEX followed by data (0000HEX to FFFFHEX) DAC Diagnostic: DAC 출력 테스트. No Yes No
B4HEX followed by 00XXHEX 24-bit raw data Self-Diagnostic Measure: 셀프 진단 측정. No Yes No
D1HEX followed by XXXXHEX Set Post-Calibration Offset: 오프셋 조정. Yes Yes No
D2HEX Startup OWI: OWI 초기화. Yes Yes Yes
D6HEX followed by data (0000HEX to FFFFHEX) Overwrite SM_config1 shadow register: 쉐도우 레지스터 덮어쓰기. No Yes No
D7HEX followed by data (0000HEX to FFFFHEX) Overwrite SM_config2 shadow register: 쉐도우 레지스터 덮어쓰기. No Yes No

2. 원시 데이터(Raw Data) 읽기 전 NVM 설정 내용

원시 데이터(Raw Sensor Measurement: A2_HEX, Raw Temperature Measurement: A4_HEX)를 읽기 전에 NVM에 설정해야 할 주요 항목들은 센서 공급 방식, 아날로그 프론트엔드(PGA/ADC) 구성, 자동 영점 보정(Auto-Zero) 활성화 등입니다. 이는 power-on 시 NVM에서 로드되어 쉐도우 레지스터로 복사되며, 원시 측정 명령어를 실행할 때 사용됩니다. NVM 설정은 Memory Write 명령어로 프로그래밍한 후, 체크섬 계산(90_HEX)으로 무결성을 확인해야 합니다. 아래는 필수/권장 설정 항목입니다(데이터시트 Table 34 기반, NVM 주소 순서대로):

1. 인터페이스 및 기본 모드 설정 (권장, 측정 전 인터페이스 안정화 목적)

  • NVM 주소 02_HEX (Interface Configuration):
    • Slave_Addr (비트 6:0): I2C/OWI 슬레이브 주소 설정 (기본 00_HEX, 범위 00_HEX ~ 7F_HEX). 원시 데이터 읽기를 위한 디지털 인터페이스(SPI/I2C/OWI) 안정화에 필요.
    • INT_setup (비트 8:7): 인터럽트(EOC 핀) 구성. 원시 측정 시 인터럽트가 필요 없으면 기본 00_BIN.
    • SS_polarity (비트 9): SPI 슬레이브 셀렉트 극성 (0: active low).
    • CKP_CKE (비트 11:10): SPI 클럭 극성/위상 (기본 00_BIN).
    • CYC_period (비트 14:12): 사이클릭 모드 업데이트 주기. 원시 측정은 Command Mode에서 하므로 선택적.
    • SOT_curve (비트 15): 2차 곡선 보정 타입 (0: Parabolic). SSC 보정 관련이지만, 원시 데이터에도 간접 영향.

2. 센서 공급 및 소스 구성 (필수, 센서 신호 입력 경로 결정)

  • NVM 주소 03_HEX (SSF1: Smart Sensor Feature Configuration Register 1):
    • default_mode (비트 1:0): Power-on 후 기본 모드 (00_BIN: Command Mode 추천, 원시 측정에 적합).
    • sensor_sup (비트 3:2): 센서 공급 방식 (00_BIN: Ratiometric voltage, 01_BIN: Current mode 등). 원시 센서 측정(A2_HEX)의 입력 신호 범위와 공통 모드 전압(VCMin)을 결정하므로 반드시 설정.
    • temp_source (비트 6:4): 온도 소스 선택 (000_BIN: 내부 온도 센서, 100_BIN: 외부 다이오드/PTC 등). 원시 온도 측정(A4_HEX) 시 필수.
    • Tbiasout (비트 9:7): Current Mode 센서 바이어스 전류 (000_BIN: 5µA 등). Current mode 사용 시 입력 공통 모드(VCMin ~0.85V) 제약 준수.
    • internal_rt (비트 12:10): 내부 저항(Rt) 값 (000_BIN: 1.34kΩ 등). 브리지 온도 센서 사용 시.
    • extra_rt (비트 13): 추가 Rt' 활성화 (0: 비활성). 대칭 온도 여기 필요 시.
    • owi_off (비트 13): OWI 인터페이스 비활성 (1: off). 인터페이스에 따라 설정.
    • owi_su_length (비트 15:14): OWI 스타트업 윈도우 길이. OWI 사용 시.

3. 아날로그 출력 및 자동 영점 보정 (필수, 원시 데이터 품질 향상)

  • NVM 주소 04_HEX (SSF2: Smart Sensor Feature Configuration Register 2):
    • AOUT_setup (비트 2:0): 아날로그 출력 타입 (001_BIN: Ratiometric voltage 등). 원시 데이터는 디지털이지만, 병행 아날로그 사용 시.
    • diagouten (비트 3): 진단 출력 활성화 (1: on). 오류 시 AOUT 신호화.
    • AZMs_on (비트 4): 센서 채널 자동 영점 보정 활성화 (1: on). 원시 센서 측정(A2_HEX)에서 오프셋 취소와 노이즈 감소에 필수.
    • AZMt_on (비트 5): 온도 채널 자동 영점 보정 활성화 (1: on). 원시 온도 측정(A4_HEX) 시.
    • cont_ANAoutn (비트 6): 연속 아날로그 출력 비활성 (1: off). OWI와 병행 시 설정.
    • owi_su_case (비트 7): OWI/아날로그 동시 사용 모드 (1: continuous OWI).
    • VDD_ldoctrl_target (비트 9:8): 외부 LDO 타겟 전압 (00_BIN: 4.6V 등). 고전압 애플리케이션 시.
    • sel_ref1 (비트 10): 센서 ADC 참조 전압 선택 (1: Ratiometric).
    • sel_ref2 (비트 11): 온도 ADC 참조 전압 선택 (1: Ratiometric).
    • select_checks (비트 15:12): 진단 체크 선택. 연결 체크 등.

4. 센서 측정 구성 (필수, PGA/ADC 설정)

  • NVM 주소 14_HEX (SM_config1: Sensor Measurement Config 1):
    • Gain_stage1 (비트 3:0): PGA 1단계 게인 (0000_BIN: 1.2V/V 등). 입력 신호 범위 결정.
    • Gain_stage2 (비트 6:4): PGA 2단계 게인 (000_BIN: 1.1V/V 등).
    • Gain_polarity (비트 7): 게인 극성 (0: Positive).
    • adc_bits (비트 11:8): ADC 해상도 (0000_BIN: 12-bit 등). 원시 데이터 해상도 직접 영향.
    • adc_offset (비트 14:12): ADC 오프셋 시프트 (000_BIN: 0%).
    • adc_en_shift (비트 15): ADC 오프셋 시프트 활성화 (1: on, 입력 범위 조정).
  • NVM 주소 15_HEX (SM_config2: Sensor Measurement Config 2):
    • ioffsc (비트 4:0): 절대 오프셋 시프트 (00000_BIN: 0mV 등). 오프셋 보상.
    • pga_en_shift (비트 5): PGA 공통 모드 자동 조정 (1: on).
    • Tbiasout (비트 8:6): 바이어스 전류 (Current mode 시, SSF1과 중복 가능).

5. 온도 측정 구성 (온도 원시 데이터 시 필수)

  • NVM 주소 16_HEX (extTemp_config1: External Temperature Config 1):
    • 외부 온도 PGA/ADC 설정.
    • 내부 온도 사용 시 Renesas 사전 프로그래밍 값 사용.
    • Gain_stage1/2, adc_bits 등 (SM_config1과 유사).
  • NVM 주소 17_HEX (extTemp_config2): ioffsc, pga_en_shift 등 (SM_config2와 유사).

설정 순서 및 주의사항

  1. 초기 프로그래밍: Memory Write로 위 NVM 주소에 값 쓰기. 예: sensor_sup=00_BIN (ratiometric), adc_bits=0111_BIN (15-bit).
  2. 체크섬 계산: 90_HEX 명령어로 NVM 무결성 확인.
  3. Power-on 후 확인: Shadow Registers가 NVM에서 로드됨. Overwrite 명령어(D6_HEX 등)로 임시 테스트 가능.
  4. 제약: Current mode 시 Tbiasout과 센서 저항으로 VCMin(0.85V) 준수. 자동 영점(AZMs_on 등) 활성화 추천 (노이즈 감소).
  5. 테스트: Command Mode에서 A2_HEX/A4_HEX 실행 전 상태 바이트 확인 (Busy=0).

이 설정 없이 원시 데이터 읽으면 기본값(대부분 0)으로 동작해 오류 발생 가능. 자세한 값은 센서 타입(브리지/전압 소스)에 따라 조정하세요.

필수 NVM 레지스터 설정

  1. 주소 02_HEX (Interface Configuration):
    • Slave_Addr (비트 6:0): I2C 슬레이브 주소 (예: 0x28, 즉 0101000_BIN).
    • INT_setup (비트 8:7): 인터럽트 설정 (00_BIN: 기본 EOC).
    • SS_polarity, CKP_CKE (비트 11:9): SPI 관련, I2C 사용 시 무시.
    • CYC_period (비트 14:12): 사이클릭 모드 주기 (Command Mode 사용 시 선택적).
    • SOT_curve (비트 15): 2차 보정 곡선 (0: Parabolic, 선택적).
    • 예시 설정값: 0x0128 (Slave_Addr=0x28, 나머지 기본값).
  2. 주소 03_HEX (SSF1: Smart Sensor Feature Configuration Register 1):
    • default_mode (비트 1:0): 00_BIN (Command Mode, 원시 데이터 읽기에 적합).
    • sensor_sup (비트 3:2): 00_BIN (Ratiometric voltage) 또는 01_BIN (Current mode). 센서 타입에 따라 선택.
    • temp_source (비트 6:4): 000_BIN (내부 온도 센서) 또는 100_BIN (외부 다이오드/PTC).
    • Tbiasout (비트 9:7): Current mode 시 바이어스 전류 (예: 001_BIN, 10µA). VCMin(0.85V) 준수.
    • internal_rt, extra_rt (비트 12:10, 13): 온도 센서 저항 (예: 000_BIN, 1.34kΩ; extra_rt=0).
    • owi_off (비트 13): 1 (OWI 비활성, I2C 사용).
    • owi_su_length (비트 15:14): I2C 사용 시 무시.
    • 예시 설정값: 0x2004 (default_mode=00, sensor_sup=00, temp_source=000, owi_off=1).
  3. 주소 04_HEX (SSF2: Smart Sensor Feature Configuration Register 2):
    • AOUT_setup (비트 2:0): 001_BIN (Ratiometric 출력, 선택적).
    • diagouten (비트 3): 1 (진단 출력 활성).
    • AZMs_on (비트 4): 1 (센서 자동 영점 보정 활성, A2_HEX에 필수).
    • AZMt_on (비트 5): 1 (온도 자동 영점 보정 활성, A4_HEX에 필수).
    • cont_ANAoutn (비트 6): 1 (아날로그 출력 비활성, 디지털 원시 데이터에 집중).
    • owi_su_case (비트 7): 0 (I2C 사용 시 무시).
    • VDD_ldoctrl_target (비트 9:8): 00_BIN (4.6V, 외부 LDO 사용 시).
    • sel_ref1, sel_ref2 (비트 10, 11): 1 (Ratiometric 참조 전압).
    • select_checks (비트 15:12): 0000_BIN (기본 진단, 선택적).
    • 예시 설정값: 0x0C30 (AZMs_on=1, AZMt_on=1, sel_ref1=1, sel_ref2=1).
  4. 주소 14_HEX, 15_HEX (SM_config1, SM_config2: Sensor Measurement Config):
    • SM_config1 (14_HEX):
      • Gain_stage1 (비트 3:0): 0010_BIN (4V/V).
      • Gain_stage2 (비트 6:4): 000_BIN (1.1V/V).
      • Gain_polarity (비트 7): 0 (Positive).
      • adc_bits (비트 11:8): 0100_BIN (16-bit ADC).
      • adc_offset (비트 14:12): 000_BIN (0% 오프셋).
      • adc_en_shift (비트 15): 0 (오프셋 시프트 비활성).
      • 예시 설정값: 0x0408.
    • SM_config2 (15_HEX):
      • ioffsc (비트 4:0): 00000_BIN (0mV 오프셋).
      • pga_en_shift (비트 5): 1 (PGA 공통 모드 자동 조정).
      • Tbiasout (비트 8:6): Current mode 시 설정 (SSF1과 동일).
      • 예시 설정값: 0x0020.
  5. 주소 16_HEX, 17_HEX (extTemp_config1, extTemp_config2):
    • 내부 온도 센서 사용 시 Renesas 사전 설정값 유지.
    • 외부 온도 센서 사용 시 SM_config1/2와 유사하게 Gain, ADC 설정.
    • 예시 설정값: 내부 온도 사용 시 기본값 유지.

3. Cyclic Mode 사용 전 NVM 설정 내용

Cyclic Mode를 사용하기 전에 ZSSC3240의 NVM(비휘발성 메모리)에서 완료해야 할 설정은 데이터시트(REN_ZSSC3240_DST_20241211.pdf)의 Table 34(NVM Content Assignments)를 기반으로 하며, Cyclic Mode가 자동 반복 측정, SSC(Sensor Signal Conditioning) 보정, 디지털/아날로그 출력 업데이트를 수행하므로 모든 센서 구성, 보정 계수, 측정 스케줄링, 인터페이스, 진단 등이 사전 프로그래밍되어야 합니다. 이는 Cyclic Mode가 autonomous(자율) 운영 모드이므로, power-on 후 또는 START_CYC 명령어(AB_HEX)로 진입 시 NVM에서 로드되는 쉐도우 레지스터를 사용하기 때문입니다.

Cyclic Mode 전에 NVM 설정을 완료하지 않으면 기본값(대부분 0)으로 동작하여 센서 신호 오류, 부정확한 업데이트 속도, 진단 실패 등이 발생할 수 있습니다. 설정 후 Memory Write 명령어(40_HEX ~ 75_HEX)로 프로그래밍하고, 체크섬 계산(90_HEX)으로 무결성을 확인하세요. 아래는 Cyclic Mode를 위한 필수 및 권장 NVM 설정 목록입니다(주소 순서대로, 데이터시트 섹션 6.5.2, 6.6.2, Table 34 기반). Cyclic Mode는 아날로그 출력 애플리케이션에 추천되므로, 관련 설정도 포함합니다.

1. 기본 및 인터페이스 설정 (필수, 모드 및 인터페이스 안정화)

  • 주소 02_HEX (Interface Configuration):
    • Slave_Addr (비트 6:0): I2C/SPI/OWI 슬레이브 주소 (예: 0101000_BIN, 0x28). Cyclic Mode에서 디지털 출력 폴링 시 필요.
    • INT_setup (비트 8:7): 인터럽트(EOC 핀) 설정 (00_BIN: 기본 EOC, Cyclic Mode에서 출력 업데이트 신호화에 유용).
    • SS_polarity, CKP_CKE (비트 11:9): SPI 관련 (I2C 사용 시 무시).
    • CYC_period (비트 14:12): Cyclic Mode 업데이트 주기 (예: 000_BIN, 0.07kHz ~ 2.91kHz). 출력 업데이트 속도 결정.
    • SOT_curve (비트 15): 2차 곡선 보정 타입 (0: Parabolic). SSC 보정에 영향.
    • 왜 필요? Cyclic Mode에서 디지털 인터페이스 폴링과 인터럽트가 사용되므로 사전 설정 필수.
    • 예시 값: 0x0128 (Slave_Addr=0x28, CYC_period=000_BIN).
  • 주소 03_HEX (SSF1: Smart Sensor Feature Configuration Register 1):
    • default_mode (비트 1:0): 01_BIN (Cyclic Mode를 power-on 기본 모드로 설정. 00_BIN으로 하면 START_CYC로 수동 진입).
    • sensor_sup (비트 3:2): 센서 공급 방식 (00_BIN: Ratiometric voltage, 01_BIN: Current mode). 입력 신호 범위 결정.
    • temp_source (비트 6:4): 온도 소스 (000_BIN: 내부, 100_BIN: 외부 다이오드/PTC). 온도 보정 필수.
    • Tbiasout (비트 9:7): Current mode 바이어스 전류 (예: 001_BIN, 10µA). VCMin(0.85V) 준수.
    • internal_rt, extra_rt (비트 12:10, 13): 온도 센서 저항 (예: 000_BIN, 1.34kΩ; extra_rt=0_BIN).
    • owi_off (비트 13): OWI 비활성 (1: off, Cyclic Mode에서 디지털 인터페이스 선택 시).
    • owi_su_length (비트 15:14): OWI 스타트업 윈도우 (OWI 사용 시).
    • 왜 필요? Cyclic Mode는 반복 측정을 하므로 센서 공급과 온도 소스가 미설정 시 측정 실패.
    • 예시 값: 0x2005 (default_mode=01_BIN, sensor_sup=00_BIN, temp_source=000_BIN).
  • 주소 04_HEX (SSF2: Smart Sensor Feature Configuration Register 2):
    • AOUT_setup (비트 2:0): 아날로그 출력 타입 (001_BIN: Ratiometric voltage, Cyclic Mode 추천).
    • diagouten (비트 3): 진단 출력 활성 (1: on, Cyclic Mode에서 AOUT으로 오류 신호화).
    • AZMs_on (비트 4): 센서 자동 영점 보정 (1: on, 반복 측정 정확도 향상).
    • AZMt_on (비트 5): 온도 자동 영점 보정 (1: on).
    • cont_ANAoutn (비트 6): 연속 아날로그 출력 (0: on, Cyclic Mode에서 아날로그 업데이트 시).
    • owi_su_case (비트 7): OWI/아날로그 동시 모드 (1: continuous, 선택적).
    • VDD_ldoctrl_target (비트 9:8): 외부 LDO 타겟 (00_BIN: 4.6V, 고전압 시).
    • sel_ref1, sel_ref2 (비트 10, 11): ADC 참조 전압 (1: Ratiometric).
    • select_checks (비트 15:12): 진단 체크 선택 (예: 0000_BIN).
    • 왜 필요? Cyclic Mode에서 아날로그 출력과 자동 영점 보정이 핵심.
    • 예시 값: 0x0C30 (AOUT_setup=001_BIN, AZMs_on=1_BIN, AZMt_on=1_BIN).

2. 센서 및 온도 측정 구성 (필수, 입력 신호 처리)

  • 주소 14_HEX (SM_config1: Sensor Measurement Config 1):
    • Gain_stage1 (비트 3:0): PGA 1단계 게인 (예: 0010_BIN, 4V/V).
    • Gain_stage2 (비트 6:4): 2단계 게인 (000_BIN, 1.1V/V).
    • Gain_polarity (비트 7): 극성 (0: Positive).
    • adc_bits (비트 11:8): ADC 해상도 (0100_BIN: 16-bit, Cyclic Mode 업데이트 속도 영향).
    • adc_offset (비트 14:12): ADC 오프셋 (000_BIN: 0%).
    • adc_en_shift (비트 15): 오프셋 시프트 (0: off).
    • 왜 필요? Cyclic Mode 반복 측정의 PGA/ADC 설정이 미설정 시 신호 범위 오류.
    • 예시 값: 0x0408.
  • 주소 15_HEX (SM_config2: Sensor Measurement Config 2):
    • ioffsc (비트 4:0): 절대 오프셋 (00000_BIN: 0mV).
    • pga_en_shift (비트 5): PGA 공통 모드 조정 (1: on).
    • Tbiasout (비트 8:6): Current mode 바이어스 (SSF1과 동일).
    • 예시 값: 0x0020.
  • 주소 16_HEX ~ 17_HEX (extTemp_config1/2: External Temperature Config):
    • 내부 온도 사용 시 기본값 유지 (Renesas 사전 설정).
    • 외부 온도 시 Gain, ADC 설정 (SM_config1/2와 유사).
    • 왜 필요? 온도 보정이 Cyclic Mode SSC에 필수.

3. SSC 보정 계수 (필수, 신호 보정)

  • 주소 05_HEX ~ 13_HEX:
    • S_Offset (05_HEX): 센서 오프셋.
    • T_Offset (06_HEX): 온도 오프셋.
    • Gain (07_HEX): 게인.
    • T1_Coeff (08_HEX): 1차 온도 계수.
    • T2_Coeff (09_HEX): 2차 온도 계수.
    • S2T1, S2T2 등 (0A_HEX ~ 13_HEX): 비선형 및 교차 보정 계수 (24-bit 형식, Table 35).
    • 왜 필요? Cyclic Mode에서 SSC corrections를 수행하므로, 보정 계수가 없으면 부정확한 출력.
    • 예시 값: 보정 과정에서 계산된 값 (데이터시트 섹션 6.6.3, 7 참조). 초기 0으로 설정 시 선형 가정.

4. Cyclic Mode 스케줄링 (필수, 자동 운영 정의)

  • 주소 18_HEX (cyc_setup: Cyclic Mode Setup):
    • meas_sch (비트 3:0): 측정 슬롯 수 (예: 0111_BIN, 7 슬롯, Figure 18 참조).
    • meas_sc (비트 7:4): SSC 업데이트 빈도 (예: 0011_BIN, 3 슬롯당 1회).
    • meas_diag (비트 11:8): 진단 체크 빈도 (예: 0001_BIN, 1 슬롯당 1회).
    • oversamp_cyc (비트 15:14): 디지털 오버샘플링 (00_BIN: 없음, 01_BIN: Oversample-4).
    • 왜 필요? Cyclic Mode의 측정 시퀀스와 에너지/속도 균형을 정의 (페이지 47, Figure 18).
    • 예시 값: 0x1237 (meas_sch=0111_BIN, meas_sc=0011_BIN 등).
  • 주소 19_HEX ~ 20_HEX (cyc_meas1/2/3: Cyclic Measurement Sequence):
    • Cyclic Mode 슬롯별 측정 타입 (센서, 온도, 자동 영점, 진단 등 시퀀스).
    • 왜 필요? 반복 측정 순서 정의 (페이지 34, Figure 18).
    • 예시 값: 애플리케이션에 따라 (예: cyc_meas1=0x0001, 센서 측정 슬롯).

5. 진단 및 출력 설정 (권장, 안전성 향상)

  • 주소 21_HEX (select_checks): Cyclic Mode 진단 체크 선택 (비트 9:0, 페이지 23~24).
    • 예: sens_short_check=1 (단락 체크).
    • 왜 필요? Cyclic Mode에서 scheduled connection checks 수행.
    • 예시 값: 0x03FF (모든 체크 활성).
  • 주소 22_HEX ~ 35_HEX (Interrupt Thresholds, DAC Limits):
    • TRSH1/2 (22_HEX ~ 25_HEX): 인터럽트 임계값 (페이지 39).
    • DAC Limits (26_HEX ~ 35_HEX): DAC 상/하한 (아날로그 출력 시).
    • 왜 필요? Cyclic Mode 출력 인터럽트와 범위 제한 (선택적, 페이지 38~39).

설정 완료 절차 및 주의사항

  1. 순서: 인터페이스/센서 기본(02_HEX ~ 04_HEX) → 측정 구성(14_HEX ~ 17_HEX) → SSC 계수(05_HEX ~ 13_HEX) → Cyclic 스케줄링(18_HEX ~ 20_HEX) → 진단(21_HEX ~ 35_HEX).
  2. 보정: SSC 계수는 별도 보정 과정(섹션 7)에서 계산.
  3. 체크섬: 모든 설정 후 90_HEX 명령어로 NVM 무결성 확인.
  4. Cyclic Mode 진입: default_mode=01_BIN으로 power-on 자동, 또는 Command Mode에서 START_CYC(AB_HEX) 사용 (페이지 11).
  5. 제약: Cyclic Mode에서 제한된 명령어만 사용 가능 (Table 33, 예: START_CM, START_SLEEP). 출력 업데이트 속도(fSSCout ~1.45kHz, 페이지 9) 고려.
  6. 테스트: Command Mode에서 설정 확인 후 Cyclic Mode 전환.

이 설정으로 Cyclic Mode가 안정적으로 운영됩니다. 

4. STM32 I2C 구현 설명

STM32Cube HAL을 사용하여 ZSSC3240의 NVM 설정, 원시 데이터 읽기, Cyclic Mode 구현. I2C1 사용, 슬레이브 주소 0x28 가정. 

5. 예시 코드 (모든 Command List 구현)

아래 코드는 Table 33의 모든 명령어를 지원하도록 확장되었습니다. 각 명령어를 위한 함수를 추가하였습니다. 예시값은 데이터시트 기반으로 설정.

// zssc3240_full.c - ZSSC3240 데이터시트 기반 STM32 I2C 인터페이스 구현
// 작성일: August 12, 2025
// 설명: 모든 Command List(Table 33)를 지원하는 완전한 코드. NVM 설정, Raw Mode, Cyclic Mode 포함.
// 주의: STM32Cube HAL 라이브러리 필요. I2C1 사용, 슬레이브 주소 0x28 가정.
//       코드 실행 전 I2C_Init() 함수로 I2C 초기화 필요 (STM32CubeMX 사용 추천).
//       printf()는 디버깅용, 실제 애플리케이션에서 UART나 LCD로 대체.

// 기본 헤더 포함
#include "stm32f4xx_hal.h"
#include 

// ZSSC3240 슬레이브 주소 정의 (7-bit 0x28, HAL 형식으로 시프트)
#define ZSSC3240_ADDR (0x28 << 1) 

// 외부 I2C 핸들 선언 (STM32CubeMX에서 초기화)
extern I2C_HandleTypeDef hi2c1; 

// 상태 바이트 읽기 함수
// 설명: ZSSC3240의 상태 바이트를 읽음. Busy, Mode, Error 등을 확인.
// 반환: HAL_StatusTypeDef (HAL_OK 등).
HAL_StatusTypeDef ZSSC3240_Read_Status(uint8_t *status) {
    return HAL_I2C_Master_Receive(&hi2c1, ZSSC3240_ADDR | 1, status, 1, HAL_MAX_DELAY);
}

// START_CM 명령어 실행 (A9_HEX)
// 설명: Sleep Mode 또는 Cyclic Mode에서 Command Mode로 전환. 모든 명령어 지원 모드.
// 모드 변경 후 상태 확인 (데이터시트 6.4.2 권장).
HAL_StatusTypeDef ZSSC3240_Start_CM(void) {
    uint8_t cmd = 0xA9; // START_CM 명령어 코드
    HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        // 모드 전환 지연 및 상태 확인
        uint8_t status_byte;
        HAL_Delay(1); // 짧은 지연 (ms 단위)
        ZSSC3240_Read_Status(&status_byte);
        if (status_byte & 0x20) { // Busy 비트(비트 5) 확인
            return HAL_BUSY; // Busy 상태 시 에러 반환
        }
    }
    return status;
}

// START_CYC 명령어 실행 (AB_HEX)
// 설명: Cyclic Mode로 전환. 자동 반복 측정 모드.
// 모드 변경 후 상태 확인.
HAL_StatusTypeDef ZSSC3240_Start_CYC(void) {
    uint8_t cmd = 0xAB; // START_CYC 명령어 코드
    HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        uint8_t status_byte;
        HAL_Delay(1);
        ZSSC3240_Read_Status(&status_byte);
        if (status_byte & 0x20) {
            return HAL_BUSY;
        }
    }
    return status;
}

// Memory Read (00_HEX ~ 3F_HEX)
// 설명: NVM 주소(00_HEX ~ 3F_HEX)에서 16-bit 데이터 읽기. 설정 확인에 사용.
// Command Mode에서 실행 (START_CM 호출).
HAL_StatusTypeDef ZSSC3240_Memory_Read(uint8_t nvm_addr, uint16_t *data) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t cmd = nvm_addr; // Memory Read 명령어 (주소 자체가 명령어)
    uint8_t rx_buffer[3]; // 상태 바이트 + 16-bit 데이터
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status != HAL_OK) return status;

    uint8_t busy;
    do {
        ZSSC3240_Read_Status(&busy);
    } while (busy & 0x20); // Busy 대기

    status = HAL_I2C_Master_Receive(&hi2c1, ZSSC3240_ADDR | 1, rx_buffer, 3, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        *data = ((uint16_t)rx_buffer[1] << 8) | rx_buffer[2]; // 16-bit 데이터 조합
    }
    return status;
}

// Memory Write (40_HEX ~ 75_HEX)
// 설명: NVM 주소(00_HEX ~ 35_HEX)에 16-bit 데이터 쓰기. 설정 변경에 사용.
// 쓰기 후 Busy 대기.
HAL_StatusTypeDef ZSSC3240_Memory_Write(uint8_t nvm_addr, uint16_t data) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t tx_buffer[3];
    tx_buffer[0] = 0x40 + nvm_addr; // Memory Write 명령어 (40_HEX + 주소)
    tx_buffer[1] = (data >> 8) & 0xFF; // MSB
    tx_buffer[2] = data & 0xFF; // LSB
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, tx_buffer, 3, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        uint8_t busy;
        do {
            ZSSC3240_Read_Status(&busy);
        } while (busy & 0x20); // Busy 대기
    }
    return status;
}

// Calculate NVM Checksum (90_HEX)
HAL_StatusTypeDef ZSSC3240_Calculate_Checksum(void) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t cmd = 0x90; // 체크섬 명령어
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        uint8_t busy;
        do {
            ZSSC3240_Read_Status(&busy);
        } while (busy & 0x20);
    }
    return status;
}

// Raw Sensor Measurement (A2_HEX)
HAL_StatusTypeDef ZSSC3240_Raw_Sensor_Measurement(uint32_t *raw_data) {
    return ZSSC3240_Read_Raw(0xA2, raw_data); // 기존 Read_Raw 함수 재사용 (센서 원시 측정)
}

// Raw Temperature Measurement (A4_HEX)
HAL_StatusTypeDef ZSSC3240_Raw_Temperature_Measurement(uint32_t *raw_data) {
    return ZSSC3240_Read_Raw(0xA4, raw_data); // 기존 Read_Raw 함수 재사용 (온도 원시 측정)
}

// START_SLEEP (A8_HEX)
HAL_StatusTypeDef ZSSC3240_Start_Sleep(void) {
    uint8_t cmd = 0xA8; // START_SLEEP 명령어
    HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        uint8_t busy;
        do {
            ZSSC3240_Read_Status(&busy);
        } while (busy & 0x20);
    }
    return status;
}

// Measure (AA_HEX)
HAL_StatusTypeDef ZSSC3240_Measure(uint32_t *sensor_data, uint32_t *temp_data) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t cmd = 0xAA; // Measure 명령어
    uint8_t rx_buffer[7]; // 상태 + 24-bit 센서 + 24-bit 온도
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status != HAL_OK) return status;

    uint8_t busy;
    do {
        ZSSC3240_Read_Status(&busy);
    } while (busy & 0x20);

    status = HAL_I2C_Master_Receive(&hi2c1, ZSSC3240_ADDR | 1, rx_buffer, 7, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        *sensor_data = ((uint32_t)rx_buffer[1] << 16) | ((uint32_t)rx_buffer[2] << 8) | rx_buffer[3];
        *temp_data = ((uint32_t)rx_buffer[4] << 16) | ((uint32_t)rx_buffer[5] << 8) | rx_buffer[6];
    }
    return status;
}

// Oversample-2 Measure (AC_HEX)
HAL_StatusTypeDef ZSSC3240_Oversample2_Measure(uint32_t *sensor_data, uint32_t *temp_data) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t cmd = 0xAC; // Oversample-2 명령어
    uint8_t rx_buffer[7];
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status != HAL_OK) return status;

    uint8_t busy;
    do {
        ZSSC3240_Read_Status(&busy);
    } while (busy & 0x20);

    status = HAL_I2C_Master_Receive(&hi2c1, ZSSC3240_ADDR | 1, rx_buffer, 7, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        *sensor_data = ((uint32_t)rx_buffer[1] << 16) | ((uint32_t)rx_buffer[2] << 8) | rx_buffer[3];
        *temp_data = ((uint32_t)rx_buffer[4] << 16) | ((uint32_t)rx_buffer[5] << 8) | rx_buffer[6];
    }
    return status;
}

// Oversample-4 Measure (AD_HEX)
HAL_StatusTypeDef ZSSC3240_Oversample4_Measure(uint32_t *sensor_data, uint32_t *temp_data) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t cmd = 0xAD; // Oversample-4 명령어
    uint8_t rx_buffer[7];
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status != HAL_OK) return status;

    uint8_t busy;
    do {
        ZSSC3240_Read_Status(&busy);
    } while (busy & 0x20);

    status = HAL_I2C_Master_Receive(&hi2c1, ZSSC3240_ADDR | 1, rx_buffer, 7, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        *sensor_data = ((uint32_t)rx_buffer[1] << 16) | ((uint32_t)rx_buffer[2] << 8) | rx_buffer[3];
        *temp_data = ((uint32_t)rx_buffer[4] << 16) | ((uint32_t)rx_buffer[5] << 8) | rx_buffer[6];
    }
    return status;
}

// Oversample-8 Measure (AE_HEX)
HAL_StatusTypeDef ZSSC3240_Oversample8_Measure(uint32_t *sensor_data, uint32_t *temp_data) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t cmd = 0xAE; // Oversample-8 명령어
    uint8_t rx_buffer[7];
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status != HAL_OK) return status;

    uint8_t busy;
    do {
        ZSSC3240_Read_Status(&busy);
    } while (busy & 0x20);

    status = HAL_I2C_Master_Receive(&hi2c1, ZSSC3240_ADDR | 1, rx_buffer, 7, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        *sensor_data = ((uint32_t)rx_buffer[1] << 16) | ((uint32_t)rx_buffer[2] << 8) | rx_buffer[3];
        *temp_data = ((uint32_t)rx_buffer[4] << 16) | ((uint32_t)rx_buffer[5] << 8) | rx_buffer[6];
    }
    return status;
}

// Oversample-16 Measure (AF_HEX)
HAL_StatusTypeDef ZSSC3240_Oversample16_Measure(uint32_t *sensor_data, uint32_t *temp_data) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t cmd = 0xAF; // Oversample-16 명령어
    uint8_t rx_buffer[7];
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status != HAL_OK) return status;

    uint8_t busy;
    do {
        ZSSC3240_Read_Status(&busy);
    } while (busy & 0x20);

    status = HAL_I2C_Master_Receive(&hi2c1, ZSSC3240_ADDR | 1, rx_buffer, 7, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        *sensor_data = ((uint32_t)rx_buffer[1] << 16) | ((uint32_t)rx_buffer[2] << 8) | rx_buffer[3];
        *temp_data = ((uint32_t)rx_buffer[4] << 16) | ((uint32_t)rx_buffer[5] << 8) | rx_buffer[6];
    }
    return status;
}

// CHECK_DIAG (B0_HEX)
HAL_StatusTypeDef ZSSC3240_Check_Diag(uint16_t *diag_data) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t cmd = 0xB0; // CHECK_DIAG 명령어
    uint8_t rx_buffer[3]; // 상태 + 16-bit 데이터
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status != HAL_OK) return status;

    uint8_t busy;
    do {
        ZSSC3240_Read_Status(&busy);
    } while (busy & 0x20);

    status = HAL_I2C_Master_Receive(&hi2c1, ZSSC3240_ADDR | 1, rx_buffer, 3, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        *diag_data = ((uint16_t)rx_buffer[1] << 8) | rx_buffer[2];
    }
    return status;
}

// RESET_DIAG (B1_HEX)
HAL_StatusTypeDef ZSSC3240_Reset_Diag(void) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t cmd = 0xB1; // RESET_DIAG 명령어
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        uint8_t busy;
        do {
            ZSSC3240_Read_Status(&busy);
        } while (busy & 0x20);
    }
    return status;
}

// UPDATE_DIAG (B2_HEX)
HAL_StatusTypeDef ZSSC3240_Update_Diag(void) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t cmd = 0xB2; // UPDATE_DIAG 명령어
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        uint8_t busy;
        do {
            ZSSC3240_Read_Status(&busy);
        } while (busy & 0x20);
    }
    return status;
}

// DAC Diagnostic (B3_HEX + data)
HAL_StatusTypeDef ZSSC3240_DAC_Diagnostic(uint16_t data) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t tx_buffer[3];
    tx_buffer[0] = 0xB3; // DAC Diagnostic 명령어
    tx_buffer[1] = (data >> 8) & 0xFF;
    tx_buffer[2] = data & 0xFF;
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, tx_buffer, 3, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        uint8_t busy;
        do {
            ZSSC3240_Read_Status(&busy);
        } while (busy & 0x20);
    }
    return status;
}

// Self-Diagnostic Measure (B4_HEX + 00XX_HEX)
HAL_StatusTypeDef ZSSC3240_Self_Diagnostic_Measure(uint8_t offset_shift, uint32_t *raw_data) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t tx_buffer[2];
    tx_buffer[0] = 0xB4; // Self-Diagnostic 명령어
    tx_buffer[1] = offset_shift; // 00XX_HEX (ioffsc 변경값)
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, tx_buffer, 2, HAL_MAX_DELAY);
    if (status != HAL_OK) return status;

    uint8_t busy;
    do {
        ZSSC3240_Read_Status(&busy);
    } while (busy & 0x20);

    uint8_t rx_buffer[4]; // 상태 + 24-bit 데이터
    status = HAL_I2C_Master_Receive(&hi2c1, ZSSC3240_ADDR | 1, rx_buffer, 4, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        *raw_data = ((uint32_t)rx_buffer[1] << 16) | ((uint32_t)rx_buffer[2] << 8) | rx_buffer[3];
    }
    return status;
}

// Set Post-Calibration Offset (D1_HEX + XXXX_HEX)
HAL_StatusTypeDef ZSSC3240_Set_Post_Calibration_Offset(uint16_t offset_value) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t tx_buffer[3];
    tx_buffer[0] = 0xD1; // Set Post-Calibration Offset 명령어
    tx_buffer[1] = (offset_value >> 8) & 0xFF;
    tx_buffer[2] = offset_value & 0xFF;
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, tx_buffer, 3, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        uint8_t busy;
        do {
            ZSSC3240_Read_Status(&busy);
        } while (busy & 0x20);
    }
    return status;
}

// Startup OWI (D2_HEX)
HAL_StatusTypeDef ZSSC3240_Startup_OWI(void) {
    uint8_t cmd = 0xD2; // Startup OWI 명령어
    HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, &cmd, 1, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        uint8_t busy;
        do {
            ZSSC3240_Read_Status(&busy);
        } while (busy & 0x20);
    }
    return status;
}

// Overwrite SM_config1 shadow register (D6_HEX + data)
HAL_StatusTypeDef ZSSC3240_Overwrite_SM_Config1(uint16_t data) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t tx_buffer[3];
    tx_buffer[0] = 0xD6; // Overwrite SM_config1 명령어
    tx_buffer[1] = (data >> 8) & 0xFF;
    tx_buffer[2] = data & 0xFF;
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, tx_buffer, 3, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        uint8_t busy;
        do {
            ZSSC3240_Read_Status(&busy);
        } while (busy & 0x20);
    }
    return status;
}

// Overwrite SM_config2 shadow register (D7_HEX + data)
HAL_StatusTypeDef ZSSC3240_Overwrite_SM_Config2(uint16_t data) {
    HAL_StatusTypeDef status = ZSSC3240_Start_CM();
    if (status != HAL_OK) return status;

    uint8_t tx_buffer[3];
    tx_buffer[0] = 0xD7; // Overwrite SM_config2 명령어
    tx_buffer[1] = (data >> 8) & 0xFF;
    tx_buffer[2] = data & 0xFF;
    status = HAL_I2C_Master_Transmit(&hi2c1, ZSSC3240_ADDR, tx_buffer, 3, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        uint8_t busy;
        do {
            ZSSC3240_Read_Status(&busy);
        } while (busy & 0x20);
    }
    return status;
}

// Cyclic Mode에서 SSC-corrected 데이터 읽기 (폴링 방식)
HAL_StatusTypeDef ZSSC3240_Read_Cyclic_Data(uint32_t *sensor_data, uint32_t *temp_data) {
    uint8_t busy;
    do {
        ZSSC3240_Read_Status(&busy);
    } while (busy & 0x20);

    uint8_t rx_buffer[7];
    HAL_StatusTypeDef status = HAL_I2C_Master_Receive(&hi2c1, ZSSC3240_ADDR | 1, rx_buffer, 7, HAL_MAX_DELAY);
    if (status == HAL_OK) {
        *sensor_data = ((uint32_t)rx_buffer[1] << 16) | ((uint32_t)rx_buffer[2] << 8) | rx_buffer[3];
        *temp_data = ((uint32_t)rx_buffer[4] << 16) | ((uint32_t)rx_buffer[5] << 8) | rx_buffer[6];
    }
    return status;
}

// 원시 데이터 읽기 전 NVM 설정 절차 (Raw Mode 설정)
void ZSSC3240_Raw_Mode_Setup(void) {
    ZSSC3240_Memory_Write(0x02, 0x0128); // 인터페이스 설정
    ZSSC3240_Memory_Write(0x03, 0x2004); // SSF1 설정
    ZSSC3240_Memory_Write(0x04, 0x0C30); // SSF2 설정
    ZSSC3240_Memory_Write(0x14, 0x0408); // SM_config1 설정
    ZSSC3240_Memory_Write(0x15, 0x0020); // SM_config2 설정
    ZSSC3240_Memory_Write(0x16, 0x0000); // extTemp_config1 설정
    ZSSC3240_Memory_Write(0x17, 0x0000); // extTemp_config2 설정
    ZSSC3240_Calculate_Checksum(); // 체크섬 계산
}

// Cyclic Mode NVM 설정 및 데이터 읽기 예시
void ZSSC3240_Cyclic_Setup_and_Read(void) {
    ZSSC3240_Memory_Write(0x02, 0x0128); // 인터페이스 설정
    ZSSC3240_Memory_Write(0x03, 0x2005); // SSF1 설정
    ZSSC3240_Memory_Write(0x04, 0x0C30); // SSF2 설정
    ZSSC3240_Memory_Write(0x05, 0x0000); // S_Offset
    ZSSC3240_Memory_Write(0x06, 0x0000); // T_Offset
    ZSSC3240_Memory_Write(0x07, 0x0100); // Gain
    ZSSC3240_Memory_Write(0x08, 0x0000); // T1_Coeff
    ZSSC3240_Memory_Write(0x09, 0x0000); // T2_Coeff
    ZSSC3240_Memory_Write(0x0A, 0x0000); // S2T1
    ZSSC3240_Memory_Write(0x0B, 0x0000); // S2T2
    ZSSC3240_Memory_Write(0x0C, 0x0000); // S3T0
    ZSSC3240_Memory_Write(0x0D, 0x0000); // S3T1
    ZSSC3240_Memory_Write(0x0E, 0x0000); // S3T2
    ZSSC3240_Memory_Write(0x0F, 0x0000); // S4T0
    ZSSC3240_Memory_Write(0x10, 0x0000); // S4T1
    ZSSC3240_Memory_Write(0x11, 0x0000); // S4T2
    ZSSC3240_Memory_Write(0x12, 0x0000); // S5T0
    ZSSC3240_Memory_Write(0x13, 0x0000); // S5T1
    ZSSC3240_Memory_Write(0x14, 0x0408); // SM_config1
    ZSSC3240_Memory_Write(0x15, 0x0020); // SM_config2
    ZSSC3240_Memory_Write(0x16, 0x0000); // extTemp_config1
    ZSSC3240_Memory_Write(0x17, 0x0000); // extTemp_config2
    ZSSC3240_Memory_Write(0x18, 0x1237); // cyc_setup
    ZSSC3240_Memory_Write(0x19, 0x0001); // cyc_meas1
    ZSSC3240_Memory_Write(0x1A, 0x0002); // cyc_meas2
    ZSSC3240_Memory_Write(0x1B, 0x0003); // cyc_meas3
    ZSSC3240_Memory_Write(0x21, 0x03FF); // select_checks
    ZSSC3240_Memory_Write(0x22, 0x0000); // TRSH1_LSB
    ZSSC3240_Memory_Write(0x23, 0x0000); // TRSH1_MSB
    ZSSC3240_Memory_Write(0x24, 0xFFFF); // TRSH2_LSB
    ZSSC3240_Memory_Write(0x25, 0xFFFF); // TRSH2_MSB
    ZSSC3240_Memory_Write(0x26, 0x0000); // DAC Limits
    ZSSC3240_Memory_Write(0x27, 0x0000);
    ZSSC3240_Memory_Write(0x28, 0x0000);
    ZSSC3240_Memory_Write(0x29, 0x0000);
    ZSSC3240_Memory_Write(0x2A, 0x0000);
    ZSSC3240_Memory_Write(0x2B, 0x0000);
    ZSSC3240_Memory_Write(0x2C, 0x0000);
    ZSSC3240_Memory_Write(0x2D, 0x0000);
    ZSSC3240_Memory_Write(0x2E, 0x0000);
    ZSSC3240_Memory_Write(0x2F, 0x0000);
    ZSSC3240_Memory_Write(0x30, 0x0000);
    ZSSC3240_Memory_Write(0x31, 0x0000);
    ZSSC3240_Memory_Write(0x32, 0x0000);
    ZSSC3240_Memory_Write(0x33, 0x0000);
    ZSSC3240_Memory_Write(0x34, 0x0000);
    ZSSC3240_Memory_Write(0x35, 0xFFFF);
    ZSSC3240_Calculate_Checksum();

    ZSSC3240_Start_CYC();

    uint32_t sensor_data, temp_data;
    if (ZSSC3240_Read_Cyclic_Data(&sensor_data, &temp_data) == HAL_OK) {
        printf("Cyclic Sensor Data: %lu\n", sensor_data);
        printf("Cyclic Temp Data: %lu\n", temp_data);
    }
}

// 원시 데이터 측정 모드 및 읽기 예시
void ZSSC3240_Raw_Mode_and_Read(void) {
    ZSSC3240_Raw_Mode_Setup();

    ZSSC3240_Start_CM();

    uint32_t raw_sensor, raw_temp;
    if (ZSSC3240_Raw_Sensor_Measurement(&raw_sensor) == HAL_OK) {
        printf("Raw Sensor Data: %lu\n", raw_sensor);
    }
    if (ZSSC3240_Raw_Temperature_Measurement(&raw_temp) == HAL_OK) {
        printf("Raw Temperature Data: %lu\n", raw_temp);
    }
}

// 메인 함수 예시 (모든 기능 테스트)
int main(void) {
    HAL_Init();
    // I2C_Init(); // 별도 초기화 함수 (STM32CubeMX에서 생성)
    // 예시 호출
    ZSSC3240_Raw_Mode_and_Read();
    ZSSC3240_Cyclic_Setup_and_Read();

    while (1) {
        // 루프 로직 (예: 데이터 읽기 반복)
    }
}

결론

이 문서는 ZSSC3240 데이터쉬트 기반으로 작성되었습니다. 코드 실행 시 STM32 하드웨어와 Cube HAL 라이브러리가 필요하며, 실제 애플리케이션에서 위 코드와 내용은 참고용으로 사용하세요.

반응형