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

AD5421 DAC 분석 및 STM32 SPI 드라이버 코드 가이드 (AD5421 DAC Analysis and STM32 SPI Driver Code Guide)

by linuxgo 2025. 8. 11.
반응형

이 문서는 AD5421 DAC 데이터시트 상세 분석, SPI 통신 절차, STM32L432KC용 SPI 드라이버 코드, 레지스터 상세 설명 및 비트필드 정의를 포함한 모든 내용을 상세하게 정리한 것입니다 (This document is a detailed summary of all content including AD5421 DAC datasheet analysis, SPI communication procedure, SPI driver code for STM32L432KC, register details, and bitfield definitions). 데이터시트는 Rev. I를 기반으로 합니다 (The datasheet is based on Rev. I). AD5421 DAC를 사용하는 개발자나 엔지니어를 위한 실무 가이드로, 산업 제어 시스템과 스마트 트랜스미터 애플리케이션에 유용합니다 (Practical guide for developers and engineers using AD5421 DAC, useful for industrial control systems and smart transmitter applications).

1. AD5421 DAC 데이터시트 상세 분석 (Detailed Analysis of AD5421 DAC Datasheet)

AD5421은 Analog Devices에서 개발한 완전한 루프-전원 공급형 4 mA ~ 20 mA 디지털-아날로그 변환기(DAC)로, 산업 제어 애플리케이션의 스마트 트랜스미터를 위해 설계되었습니다 (The AD5421 is a complete loop-powered 4 mA to 20 mA digital-to-analog converter (DAC) developed by Analog Devices, designed for smart transmitters in industrial control applications).

 

제품 개요 및 기능 (Product Overview and Features)

  • 16비트 해상도 및 단조성 (16-bit resolution and monotonicity).
  • 핀 선택 가능한 NAMUR 준수 범위: 4 mA ~ 20 mA, 3.8 mA ~ 21 mA, 3.2 mA ~ 24 mA (Pin-selectable NAMUR-compliant ranges: 4 mA to 20 mA, 3.8 mA to 21 mA, 3.2 mA to 24 mA).
  • NAMUR 준수 알람 전류: 다운스케일 = 3.2 mA, 업스케일 = 22.8 mA/24 mA (NAMUR-compliant alarm currents: Downscale = 3.2 mA, Upscale = 22.8 mA/24 mA).
  • 총 미조정 오류(TUE): 최대 0.05% (Total unadjusted error (TUE): 0.05% maximum).
  • INL 오류: 최대 0.0035% FSR (INL error: 0.0035% FSR maximum).
  • 출력 TC: 전형적으로 3 ppm/°C (Output TC: 3 ppm/°C typical).
  • 대기 전류: 최대 300 μA (Quiescent current: 300 μA maximum).
  • SPI 호환 인터페이스(최대 30 MHz) 및 Schmitt 입력 (SPI-compatible interface (up to 30 MHz) with Schmitt inputs).
  • FAULT 핀 또는 알람 전류를 통한 오류 경고; 자동 오류 레지스터 판독 (Fault alerts via FAULT pin or alarm current; automatic fault register readback).
  • 슬루율 제어, 이득/오프셋 조정 (Slew rate control, gain/offset adjusts).
  • 온칩 기준 TC: 최대 4 ppm/°C (On-chip reference TC: 4 ppm/°C maximum).
  • 선택 가능한 규제 출력: 1.8 V ~ 12 V (Selectable regulated output: 1.8 V to 12 V).
  • 루프 전압: 5.5 V ~ 52 V (Loop voltage: 5.5 V to 52 V).
  • 온도 범위: −40°C ~ +105°C (Temperature range: −40°C to +105°C).
  • 패키지: 28리드 TSSOP, 32리드 LFCSP (Packages: 28-lead TSSOP, 32-lead LFCSP).

애플리케이션: 산업 프로세스 제어, 루프-전원 공급 트랜스미터, 스마트 트랜스미터, HART 연결 (Applications: Industrial process control, loop-powered transmitters, smart transmitters, HART connectivity).

주요 사양 (Key Specifications)

매개변수 (Parameter) 값 (C 등급, 내부 R_SET) (Value (C Grade, Internal R_SET)) 값 (C 등급, 외부 R_SET 24 kΩ) (Value (C Grade, External R_SET 24 kΩ))
해상도 (Resolution) 16 비트 (16 Bits) 16 비트 (16 Bits)
TUE −0.126% ~ +0.126% FSR −0.048% ~ +0.048% FSR
25°C에서의 TUE (TUE at 25°C) −0.041% ±0.0064% ~ +0.041% FSR −0.027% ±0.002% ~ +0.027% FSR
INL 오류 (INL Error) −0.0035% ~ +0.0035% FSR −0.0035% ~ +0.0035% FSR
DNL 오류 (DNL Error) −1 ~ +1 LSB (단조성) (-1 to +1 LSB (monotonic)) −1 ~ +1 LSB (단조성) (-1 to +1 LSB (monotonic))
오프셋 오류 (Offset Error) −0.056% ~ +0.056% FSR -
이득 오류 (Gain Error) −0.107% ~ +0.107% FSR -
대기 전류 (Quiescent Current) 260 μA ~ 300 μA -
REFOUT1 2.498 V ~ 2.503 V (25°C), TC 1.5 ~ 4 ppm/°C -
REFOUT2 1.18 V ~ 1.28 V (25°C) -
루프 준수 전압 (Loop Compliance Voltage) LOOP− + 5.5 V (REG_OUT < 5.5 V, 24 mA), LOOP− + 12.5 V (REG_OUT = 12 V) -

전원 요구사항: REG_IN 5.5 V ~ 52 V, IODV_DD 1.71 V ~ 5.5 V (Power requirements: REG_IN 5.5 V to 52 V, IODV_DD 1.71 V to 5.5 V).

기능 블록 다이어그램 설명 (Functional Block Diagram Description)

통합 아키텍처: 16비트 DAC, 입력/제어 레지스터, 온도 센서, 기준 전압(REFOUT1 2.5 V, REFOUT2 1.22 V), 전압 레귤레이터, 루프 모니터 및 외부 NMOS 드라이브 (Integrated architecture: 16-bit DAC, input/control registers, temperature sensor, references (REFOUT1 2.5 V, REFOUT2 1.22 V), voltage regulator, loop monitor, and external NMOS drive). 24 kΩ R_SET(내부/외부)는 전류 설정에 핵심적입니다 (The 24 kΩ R_SET (internal/external) is key for current setting).

 

핀 구성 및 설명 (Pin Configuration and Descriptions)

핀 (TSSOP/LFCSP) (Pin (TSSOP/LFCSP)) 이름 (Name) 설명 (Description)
1/29 IODV_DD 디지털 인터페이스 공급 (1.71 V ~ 5.5 V) (Digital interface supply (1.71 V to 5.5 V)).
2/30 SDO 직렬 데이터 출력 (Serial data output).
3/31 SCLK 직렬 클럭 입력 (최대 30 MHz) (Serial clock input (up to 30 MHz)).
4/32 SYNC 프레임 동기화, 액티브 로우 (Frame sync, active low).
5/1 SDIN 직렬 데이터 입력 (Serial data input).
6/2 LDAC DAC 로드, 액티브 로우 (Load DAC, active low).
7/3 FAULT 오류 경고, 액티브 하이 (Fault alert, active high).
8/5 DV_DD 3.3 V 디지털 공급 출력 (3.3 V digital supply output).
9/6 ALARM_CURRENT_DIRECTION 알람 전류 방향 선택 (Alarm current direction select).
10/7 R_INT/R_EXT R_SET 선택 (R_SET select).
11,12/8,10 RANGE0, RANGE1 범위 선택 (Range select).
13,14/4,11,12 COM 접지 기준 (Ground reference).
15-17/13-15 REG_SEL0-2 레귤레이터 전압 선택 (Regulator voltage select).
18/17 REFIN 기준 입력 (2.5 V) (Reference input (2.5 V)).
19/18 REFOUT2 1.22 V 기준 출력 (1.22 V reference output).
20/19 REFOUT1 2.5 V 기준 출력 (2.5 V reference output).
21/20 C_IN 슬루/HART 커패시터 (Slew/HART capacitor).
22,23/21,22 R_EXT1,2 외부 R_SET 연결 (External R_SET connection).
24/23 LOOP− 루프 전류 반환 (Loop current return).
25/23 V_LOOP 루프 전압 모니터 (Loop voltage monitor).
26/26 DRIVE 외부 MOSFET 게이트 (External MOSFET gate).
27/27 REG_IN 레귤레이터 입력 (5.5 V ~ 52 V) (Regulator input (5.5 V to 52 V)).
28/28 REG_OUT 레귤레이터 출력 (1.8 V ~ 12 V) (Regulator output (1.8 V to 12 V)).

절대 최대 등급 (Absolute Maximum Ratings)

  • REG_IN to COM: -0.3 V ~ +60 V.
  • 디지털 입력: -0.3 V ~ +7 V (Digital inputs: -0.3 V to +7 V).
  • 작동 온도: -40°C ~ +105°C (Operating temperature: -40°C to +105°C).
  • 접합 온도: 125°C (Junction temperature: 125°C).
  • ESD: HBM 3 kV, FICDM 2 kV, MM 200 V.

전기적 특성 (Electrical Characteristics)

DC 성능 (DC Performance)

TUE: -0.126% ~ +0.126% FSR (C 등급 내부 R_SET) (TUE: -0.126% to +0.126% FSR (C grade internal R_SET)). INL: -0.0035% ~ +0.0035% FSR (INL: -0.0035% to +0.0035% FSR).

동적 성능 (Dynamic Performance)

정착 시간: 0.1% FSR까지 50 μs (Settling time: 50 μs to 0.1% FSR). 슬루율: 400 μA/μs (Slew rate: 400 μA/μs).

타이밍 특성 (Timing Characteristics)

SCLK 주기: 최소 33 ns (SCLK cycle: min 33 ns). 데이터 설정/유지: 최소 5 ns (Data setup/hold: min 5 ns).

작동 이론 (Theory of Operation)

DAC, 증폭기, 레귤레이터를 통합하여 루프 전류 제어 (Integrates DAC, amplifier, regulator for loop current control). R_SET으로 전압-전류 변환(이득 221) (Uses R_SET for voltage-to-current conversion (gain 221)). 오류 감지: SPI, 온도(>125°C), 루프 전압 (Fault detection: SPI, temp (>125°C), loop voltage).

애플리케이션 정보 (Applications Information)

HART 트랜스미터용 (For HART transmitters). 오류 예산: 최악 0.21%, 캘리브레이션 0.102% (Error budgeting: worst-case TUE 0.21%, calibratable to 0.102%).

주문 가이드 (Ordering Guide)

모델 (Model) 패키지 (Package) 옵션 (Option)
AD5421ACPZ-REEL7 LFCSP CP-32-12
AD5421BCPZ-REEL7 LFCSP CP-32-12
AD5421BREZ TSSOP_EP RE-28-2
EVAL-AD5421SDZ 평가 보드 (Evaluation Board) -

2. SPI 통신 절차 (SPI Communication Procedure)

AD5421의 SPI 인터페이스는 최대 30 MHz, MSB 우선, CPOL=0, CPHA=1 (Mode 1) (The AD5421's SPI interface supports up to 30 MHz, MSB first, CPOL=0, CPHA=1 (Mode 1)).

SPI 인터페이스 개요 (SPI Interface Overview)

3-와이어(선택 4-와이어), CRC 옵션 (8비트, 다항식 x^8 + x^2 + x + 1) (3-wire (optional 4-wire), CRC option (8-bit, polynomial x^8 + x^2 + x + 1)).

핀: SYNC (CS), SCLK, SDIN, SDO, LDAC (Pins: SYNC (CS), SCLK, SDIN, SDO, LDAC).

쓰기 작동 절차 (Write Operation Procedure)

  1. SYNC 로우 (SYNC low).
  2. 8비트 주소/명령 + 16비트 데이터 클럭킹 (Clock 8-bit address/command + 16-bit data).
  3. SYNC 하이로 래치 (Latch on SYNC high).
  4. LDAC로 업데이트 (Update with LDAC).

읽기 작동 절차 (Read Operation Procedure)

  1. 자동 판독 비활성 (제어 D11=1) (Disable auto readback (control D11=1)).
  2. 읽기 명령 발행 (주소 MSB=1) (Issue read command (address MSB=1)).
  3. SDO에서 데이터 수신 (Receive data on SDO).

타이밍 특성 (Timing Characteristics)

파라미터 (Parameter) 설명 (Description) 최소/최대 값 (Min/Max Value)
t1 SCLK 주기 시간 (SCLK cycle time) 최소 33 ns (min 33 ns)
t2 SCLK 하이 시간 (SCLK high time) 최소 17 ns (min 17 ns)
t7 데이터 설정 시간 (Data setup time) 최소 5 ns (min 5 ns)

오류 처리 (Fault Handling)

오류 감지: SPI 오류, 타임아웃 (Fault detection: SPI errors, timeout). FAULT 핀 하이, 알람 전류 (FAULT pin high, alarm current).

3. STM32L432KC용 SPI 드라이버 코드 (SPI Driver Code for STM32L432KC)

STM32Cube HAL 기반, SPI1 사용, polling 모드 (Based on STM32Cube HAL, using SPI1, polling mode).

헤더 파일 (spi_driver.h) (Header File (spi_driver.h))

// This header file defines the SPI driver for AD5421 on STM32L432KC, including register addresses and bitfield structures for clarity and ease of use.
// It includes necessary includes, extern declarations, pin definitions, register commands, and union structures for bitfields.
// Detailed bitfield definitions are based on AD5421 datasheet tables 15-23.
#ifndef SPI_DRIVER_H
#define SPI_DRIVER_H

#include "stm32l4xx_hal.h"
#include <stdint.h>  // For uint16_t and int16_t types used in bitfields.

extern SPI_HandleTypeDef hspi1;  // External declaration for SPI handle.

#define SPI_CS_PORT     GPIOA  // GPIO port for CS (SYNC) pin.
#define SPI_CS_PIN      GPIO_PIN_4  // Pin number for CS.
#define SPI_LDAC_PORT   GPIOA  // GPIO port for LDAC pin.
#define SPI_LDAC_PIN    GPIO_PIN_8  // Pin number for LDAC.

// Register address/command byte definitions (write/read).
// Based on datasheet: Write commands start with 0, read with 1 in MSB.
#define DAC_REG_WRITE       0x01  // DAC register write: 00000001
#define DAC_REG_READ        0x81  // DAC register read: 10000001
#define CONTROL_REG_WRITE   0x02  // Control register write: 00000010
#define CONTROL_REG_READ    0x82  // Control register read: 10000010
#define OFFSET_REG_WRITE    0x03  // Offset adjust register write: 00000011
#define OFFSET_REG_READ     0x83  // Offset adjust register read: 10000011
#define GAIN_REG_WRITE      0x04  // Gain adjust register write: 00000100
#define GAIN_REG_READ       0x84  // Gain adjust register read: 10000100
#define FAULT_REG_READ      0x85  // Fault register read (read-only): 10000101

// DAC register bitfield structure (Table 15: Simple 16-bit DAC code).
// Datasheet: 16-bit unsigned value, code 0 = min current (e.g., 4 mA), 65535 = max current (e.g., 20 mA).
typedef union {
    struct {
        uint16_t dac_data : 16;  // D15:D0: DAC code (0 to 65535).
    } bits;
    uint16_t reg;  // Full 16-bit register value.
} DAC_Register_t;

// Control register bitfield structure (Table 17: Various function configurations).
// Datasheet: Configures CRC, auto readback, watchdog, slew control. Default 0x0000.
typedef union {
    struct {
        uint16_t sr_step      : 4;   // D3:D0: Slew step size (Table 20: 0000=1 LSB, ..., 1111=64 LSB).
        uint16_t sr_clock     : 3;   // D6:D4: Slew clock speed (Table 19: 000=300 kHz, ..., 111=5.8 kHz).
        uint16_t slew_en      : 1;   // D7: Slew rate control enable (1=enable, 0=disable).
        uint16_t wd_period    : 3;   // D10:D8: Watchdog timer period (Table 18: 000=disable, 001=43 ms, ..., 111=5814 ms).
        uint16_t reserved1    : 1;   // D11: Reserved (always 0).
        uint16_t auto_fault_readback_dis : 1;  // D12: Disable auto fault register readback (1=disable, 0=enable).
        uint16_t reserved2    : 1;   // D13: Reserved (always 0).
        uint16_t crc_en       : 1;   // D14: CRC enable (1=enable, 0=disable).
        uint16_t reserved3    : 1;   // D15: Reserved (always 0).
    } bits;
    uint16_t reg;  // Full 16-bit register value.
} Control_Register_t;

// Offset adjust register bitfield structure (Table 21: Offset calibration).
// Datasheet: 16-bit signed value (2's complement), -32768 to +32767. Added to DAC code.
typedef union {
    struct {
        int16_t offset : 16;  // D15:D0: Offset value (signed, -32768 to +32767).
    } bits;
    uint16_t reg;  // Full 16-bit register value (use with caution for signed access).
} Offset_Register_t;

// Gain adjust register bitfield structure (Table 22: Gain calibration).
// Datasheet: 16-bit unsigned value, 0 to 65535. Multiplied to DAC code (GAIN / 65536).
typedef union {
    struct {
        uint16_t gain : 16;  // D15:D0: Gain value (0 to 65535, default 0xFFFF = 1.0).
    } bits;
    uint16_t reg;  // Full 16-bit register value.
} Gain_Register_t;

// Fault register bitfield structure (Table 23: Fault status, read-only).
// Datasheet: Fault flags, some cleared on read. Linked to FAULT pin.
typedef union {
    struct {
        uint16_t reserved1    : 7;   // D6:D0: Reserved (0000000).
        uint16_t spi_watchdog_timeout : 1;  // D7: Watchdog timeout (1=fault).
        uint16_t spi_sclk_count_error : 1;  // D8: SCLK count error (not 24/32 bits, 1=fault).
        uint16_t spi_crc_error : 1;  // D9: CRC error (1=fault).
        uint16_t reserved2    : 1;   // D10: Reserved (0).
        uint16_t over_temp    : 1;   // D11: Overtemperature (>125°C, 1=fault).
        uint16_t loop_voltage_fault : 1;  // D12: Loop voltage fault (1=fault).
        uint16_t reserved3    : 3;   // D15:D13: Reserved (000).
    } bits;
    uint16_t reg;  // Full 16-bit register value.
} Fault_Register_t;

// Function declarations for the driver.
HAL_StatusTypeDef SPI_Driver_Init(void);
HAL_StatusTypeDef SPI_Write_24bit(uint8_t address_cmd, uint16_t data);
HAL_StatusTypeDef SPI_Read_24bit(uint8_t address_cmd, uint16_t* data_out);
void SPI_CS_Low(void);
void SPI_CS_High(void);
void SPI_LDAC_Pulse(void);
HAL_StatusTypeDef SPI_Init_Control_Register(void);  // Initialize control register.
HAL_StatusTypeDef SPI_Read_Fault_Register(uint16_t* fault_data);  // Read fault register.

#endif /* SPI_DRIVER_H */
    

소스 파일 (spi_driver.c) (Source File (spi_driver.c))


// This source file implements the SPI driver functions for AD5421 on STM32L432KC.
// It includes initialization, write/read operations, and helper functions with detailed comments based on AD5421 datasheet and STM32 HAL.
// All functions are designed for polling mode; interrupt or DMA can be added as extensions.
#include "spi_driver.h"

SPI_HandleTypeDef hspi1;  // Global SPI handle instance.

// Function to set SPI CS (SYNC) pin low to start SPI frame transmission.
// Datasheet Figure 2: SYNC low triggers data clocking. Schmitt input for noise immunity.
void SPI_CS_Low(void) {
    HAL_GPIO_WritePin(SPI_CS_PORT, SPI_CS_PIN, GPIO_PIN_RESET);  // Set pin to low (active).
}

// Function to set SPI CS (SYNC) pin high to end SPI frame and latch data.
// Datasheet: On SYNC rising edge, input shift register is latched to the addressed register.
void SPI_CS_High(void) {
    HAL_GPIO_WritePin(SPI_CS_PORT, SPI_CS_PIN, GPIO_PIN_SET);  // Set pin to high (inactive).
}

// Function to generate a pulse on LDAC pin to update DAC register.
// Datasheet Table 4: LDAC pulse width min 10 ns (t10). If LDAC fixed low, updates on SYNC high.
// HAL_Delay(1) is in ms; for precise ns delay, use timer if needed.
void SPI_LDAC_Pulse(void) {
    HAL_GPIO_WritePin(SPI_LDAC_PORT, SPI_LDAC_PIN, GPIO_PIN_RESET);  // Start pulse (low).
    HAL_Delay(1);  // Delay to ensure min pulse width (adjust for precision if required).
    HAL_GPIO_WritePin(SPI_LDAC_PORT, SPI_LDAC_PIN, GPIO_PIN_SET);  // End pulse (high).
}

// SPI interface and GPIO initialization function.
// Returns HAL_OK on success, HAL_ERROR on failure.
// Uses STM32L432KC SPI1: PA5(SCK), PA6(MISO), PA7(MOSI), PA4(CS), PA8(LDAC).
// Compatible with AD5421: Mode 1 (CPOL=0, CPHA=1), MSB first, up to 30 MHz (10 MHz example here).
// CRC initially disabled; enable via control register if needed.
// Calls SPI_Init_Control_Register() after init to set AD5421 control register defaults.
HAL_StatusTypeDef SPI_Driver_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};  // GPIO init structure.
    __HAL_RCC_GPIOA_CLK_ENABLE();  // Enable GPIOA clock.

    // Initialize CS (SYNC) pin: output, initial high (idle state).
    GPIO_InitStruct.Pin = SPI_CS_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  // Push-pull output.
    GPIO_InitStruct.Pull = GPIO_NOPULL;  // No pull-up/down.
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;  // High speed.
    HAL_GPIO_Init(SPI_CS_PORT, &GPIO_InitStruct);
    SPI_CS_High();  // Set to idle.

    // Initialize LDAC pin: output, initial high (no update).
    GPIO_InitStruct.Pin = SPI_LDAC_PIN;
    HAL_GPIO_Init(SPI_LDAC_PORT, &GPIO_InitStruct);
    HAL_GPIO_WritePin(SPI_LDAC_PORT, SPI_LDAC_PIN, GPIO_PIN_SET);

    __HAL_RCC_SPI1_CLK_ENABLE();  // Enable SPI1 clock.

    // Initialize SPI1 GPIO: alternate function AF5.
    GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;  // SCK, MISO, MOSI.
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;  // Alternate function push-pull.
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;  // Very high speed.
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;  // AF5 for SPI1.
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // Set up SPI handler: master mode, 8-bit data (24-bit split into 3 bytes).
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_MASTER;  // Master mode.
    hspi1.Init.Direction = SPI_DIRECTION_2LINES;  // Full duplex.
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;  // 8-bit frames.
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;  // CPOL=0 (idle low).
    hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;  // CPHA=1 (data on second edge).
    hspi1.Init.NSS = SPI_NSS_SOFT;  // Software NSS (CS manual).
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;  // 80MHz / 8 = 10MHz baud.
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;  // MSB first (AD5421 requirement).
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;  // No TI mode.
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;  // CRC disabled initially.
    hspi1.Init.CRCPolynomial = 0x107;  // AD5421 CRC polynomial: x^8 + x^2 + x + 1.

    if (HAL_SPI_Init(&hspi1) != HAL_OK) {  // Initialize SPI; check for errors.
        return HAL_ERROR;
    }

    return SPI_Init_Control_Register();  // Initialize AD5421 control register.
}

// Function to write 24-bit to AD5421: address/command byte + 16-bit data.
// address_cmd: 8-bit address/command (e.g., DAC_REG_WRITE = 0x01).
// data: 16-bit data word (register value).
// Returns HAL_OK on success.
// Datasheet: 24-bit frame (32-bit with CRC, not supported here). CS low -> transmit -> CS high.
// Auto LDAC pulse for DAC write to update output.
// Bitfield usage example: Control_Register_t ctrl; ctrl.reg = data; SPI_Write_24bit(CONTROL_REG_WRITE, ctrl.reg);
HAL_StatusTypeDef SPI_Write_24bit(uint8_t address_cmd, uint16_t data) {
    uint8_t tx_buffer[3];  // Transmit buffer for 3 bytes.
    tx_buffer[0] = address_cmd;  // Address/command byte.
    tx_buffer[1] = (data >> 8) & 0xFF;  // Data MSB.
    tx_buffer[2] = data & 0xFF;  // Data LSB.

    SPI_CS_Low();  // Start frame.
    HAL_StatusTypeDef status = HAL_SPI_Transmit(&hspi1, tx_buffer, 3, HAL_MAX_DELAY);  // Polling transmit.
    SPI_CS_High();  // End frame and latch.

    if (address_cmd == DAC_REG_WRITE) {  // If DAC write, pulse LDAC for update (datasheet requirement).
        SPI_LDAC_Pulse();
    }

    return status;  // Return transmission status.
}

// Function to read 24-bit from AD5421: transmit address/command, receive data.
// address_cmd: 8-bit address/command (e.g., FAULT_REG_READ = 0x85).
// data_out: Pointer to store 16-bit read data.
// Returns HAL_OK on success.
// Datasheet: Requires auto fault readback disabled (control D12=1) for manual reads. Transmit don't care data.
// Bitfield usage example: Fault_Register_t fault; SPI_Read_24bit(FAULT_REG_READ, &fault.reg); if (fault.bits.over_temp) { ... }
HAL_StatusTypeDef SPI_Read_24bit(uint8_t address_cmd, uint16_t* data_out) {
    uint8_t tx_buffer[3] = {address_cmd, 0x00, 0x00};  // Transmit: command + don't care.
    uint8_t rx_buffer[3];  // Receive buffer.

    SPI_CS_Low();  // Start frame.
    HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(&hspi1, tx_buffer, rx_buffer, 3, HAL_MAX_DELAY);  // Transmit/receive.
    SPI_CS_High();  // End frame.

    if (status == HAL_OK) {
        *data_out = (rx_buffer[1] << 8) | rx_buffer[2];  // Combine MSB + LSB.
    }

    return status;
}

// Function to initialize control register with default settings.
// Returns HAL_OK on success.
// Datasheet Table 17: Default 0x0000 (CRC disable, auto readback enable, watchdog/slew disable).
// Uses bitfield struct; modify bits as needed (e.g., ctrl.bits.crc_en = 1;).
// If CRC enabled, re-init HAL SPI with CRC calculation.
HAL_StatusTypeDef SPI_Init_Control_Register(void) {
    Control_Register_t ctrl = {0};  // Initialize with all bits 0 (default).
    // Example settings: Uncomment and modify as required for specific configurations.
    // ctrl.bits.slew_en = 1;  // Enable slew rate control.
    // ctrl.bits.sr_clock = 0b001;  // Set slew clock to 150 kHz (example value).
    // ctrl.bits.sr_step = 0b0010;  // Set slew step to 4 LSB (example value).
    // ctrl.bits.wd_period = 0b001;  // Set watchdog to 43 ms (example value).
    // ctrl.bits.auto_fault_readback_dis = 1;  // Disable auto fault readback for manual reads.
    // ctrl.bits.crc_en = 1;  // Enable CRC (expands frame to 32 bits).

    if (ctrl.bits.crc_en) {  // If CRC enabled, update HAL SPI config and re-init.
        hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE;
        HAL_SPI_Init(&hspi1);  // Re-initialize SPI with new config.
    }

    return SPI_Write_24bit(CONTROL_REG_WRITE, ctrl.reg);  // Write the register value.
}

// Function to read fault register for status check.
// fault_data: Pointer to store 16-bit data (use Fault_Register_t.reg).
// Returns HAL_OK on success.
// Datasheet Table 23: Fault flags (e.g., over_temp=1 for overtemperature). Some cleared on read.
// Recommended: Use bitfield - Fault_Register_t fault; fault.reg = *fault_data; if (fault.bits.loop_voltage_fault) { handle fault }.
HAL_StatusTypeDef SPI_Read_Fault_Register(uint16_t* fault_data) {
    return SPI_Read_24bit(FAULT_REG_READ, fault_data);  // Perform read operation.
}
    

4. 레지스터 상세 설명 (Register Details)

DAC 레지스터 (DAC Register)

쓰기: 0x01, 읽기: 0x81 (Write: 0x01, Read: 0x81). 16비트 DAC 코드 (0 ~ 65535) (16-bit DAC code (0 to 65535)). 기본 0x0000 (Default 0x0000).

비트 (Bit) 이름 (Name) 설명 (Description) 기본값 (Default)
D15:D0 DAC_DATA DAC 코드 (DAC code) 0x0000

제어 레지스터 (Control Register)

쓰기: 0x02, 읽기: 0x82 (Write: 0x02, Read: 0x82). 기능 구성 (Function configuration). 기본 0x0000 (Default 0x0000).

비트 (Bit) 이름 (Name) 설명 (Description) 기본값 (Default)
D15 RESERVED 예약 (Reserved) 0
D14 CRC_EN CRC 활성화 (CRC enable) 0
D13 RESERVED 예약 (Reserved) 0
D12 AUTO_FAULT_READBACK_DIS 자동 오류 판독 비활성화 (Auto fault readback disable) 0
D11 RESERVED 예약 (Reserved) 0
D10:D8 WD_PERIOD 왓치독 기간 (Watchdog period) 000
D7 SLEW_EN 슬루 활성화 (Slew enable) 0
D6:D4 SR_CLOCK 슬루 클럭 (Slew clock) 000
D3:D0 SR_STEP 슬루 스텝 (Slew step) 0000

오프셋 조정 레지스터 (Offset Adjust Register)

쓰기: 0x03, 읽기: 0x83 (Write: 0x03, Read: 0x83). 오프셋 값 (-32768 ~ +32767) (Offset value (-32768 to +32767)). 기본 0x0000 (Default 0x0000).

이득 조정 레지스터 (Gain Adjust Register)

쓰기: 0x04, 읽기: 0x84 (Write: 0x04, Read: 0x84). 이득 값 (0 ~ 65535) (Gain value (0 to 65535)). 기본 0xFFFF (Default 0xFFFF).

오류 레지스터 (Fault Register)

읽기: 0x85 (Read: 0x85). 오류 상태 (Fault status).

비트 (Bit) 이름 (Name) 설명 (Description) 기본값 (Default)
D15:D13 RESERVED 예약 (Reserved) 000
D12 LOOP_VOLTAGE_FAULT 루프 전압 오류 (Loop voltage fault) 0
D11 OVER_TEMP 과온 (Overtemp) 0
D10 RESERVED 예약 (Reserved) 0
D9 SPI_CRC_ERROR CRC 오류 (CRC error) 0
D8 SPI_SCLK_COUNT_ERROR SCLK 카운트 오류 (SCLK count error) 0
D7 SPI_WATCHDOG_TIMEOUT 왓치독 타임아웃 (Watchdog timeout) 0
D6:D0 RESERVED 예약 (Reserved) 0000000

 

AD5421 상세한 사양에 대해서는  아래 링크 데이터쉬트를 참조하기 바랍니다.

https://www.analog.com/media/en/technical-documentation/data-sheets/ad5421.pdf

반응형