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

AD524X(AD5241/AD5242/AD5280/AD5282) 디지털 포텐셔미터 STM32 HAL 기반 디바이스 드라이버 구현

by linuxgo 2025. 8. 28.
반응형

1. 개요

이 보고서는 아나로그 디바이스(Analog Devices)의 AD5241, AD5242, AD5280, AD5282 디지털 포텐셔미터를 STM32 마이크로컨트롤러에서 제어하기 위한 디바이스 드라이버 구현 내용을 설명합니다. 드라이버는 STM32 HAL 라이브러리를 기반으로 작성되었으며, I2C 인터페이스를 통해 디바이스의 모든 주요 기능을 지원하도록 설계되었습니다. 보고서는 디바이스의 상세 사양, 구현된 드라이버의 세부 사항, STM32L432KC 기준으로 한 예제 코드, 그리고 완전한 드라이버 코드를 포함합니다.

2. AD5241/AD5242/AD5280/AD5282 주요 사양

2.1 주요 특징

AD5241, AD5242, AD5280, AD5282는 고정밀 디지털 포텐셔미터로, 저항 값을 디지털 신호로 제어할 수 있습니다. 주요 특징은 다음과 같습니다.

AD5241

  • 해상도: 8비트(256단계, 0~255)
  • 저항 옵션:
    • AD5241/AD5242: 10kΩ, 100kΩ, 1MΩ
    • AD5280/AD5282: 20kΩ, 50kΩ, 200kΩ
  • 채널 수:
    • AD5241/AD5280: 단일 채널
    • AD5242/AD5282: 듀얼 채널
  • 인터페이스: I2C(Serial Interface) 프로토콜
  • 추가 기능:
    • 출력 핀(O1, O2): 디지털 출력 제어 가능
    • 셧다운 모드: 저항 출력 비활성화
    • 중간값 리셋: 전원 인가 시 저항 값 자동 초기화
  • 전력 소비: 저전력 동작, 일반적으로 15µA(typ)
  • 패키지: TSSOP-14, SOIC-14

2.2 명령어 구조

AD5241/AD5242/AD5280/AD5282는 I2C를 통해 다음과 같은 명령어를 지원합니다:

  • RDAC 쓰기: 특정 RDAC 채널(0 또는 1)에 8비트 저항 값 설정
  • 출력 핀(O1, O2) 제어: 디지털 출력 핀 상태 설정
  • 셧다운 모드: RDAC 출력 비활성화
  • I2C 주소: AD0, AD1 핀 설정에 따라 결정(기본 예: 0x2C)

2.3 애플리케이션

  • 오디오 시스템: 볼륨 조절
  • 산업용 제어: 센서 캘리브레이션
  • 계측: 가변 저항 제어
  • 프로토타이핑: 아날로그 회로 테스트

3. STM32 디바이스 드라이버 구현 내용

3.1 구현 개요

AD524X 디바이스 드라이버는 STM32L432KC를 포함한 STM32 시리즈를 대상으로 하며, STM32 HAL 라이브러리를 사용하여 I2C 통신을 구현하였습니다. 드라이버는 AD5241, AD5242, AD5280, AD5282의 모든 주요 기능을 지원하며, 다음과 같은 요구사항을 충족합니다.

  • I2C 통신: 저항 값 설정, 출력 핀 제어, 셧다운 모드 설정
  • 모듈화: 재사용 가능하고 명확한 함수 구조
  • 확장성: 단일/듀얼 채널 디바이스 모두 지원
  • 에러 처리: I2C 연결 확인 및 오류 상태 관리

3.2 구현 세부 사항

3.2.1 헤더 파일 (AD524X.h)

  • 상수 정의: I2C 주소, 채널 수, 기본값(중간값 127) 정의
  • 함수 프로토타입: 초기화, 저항 값 쓰기, 출력 핀 제어, 셧다운 모드 설정, 연결 확인 함수 선언
  • 구조체 정의: 디바이스 정보(I2C 주소, 핸들, 채널 수)를 저장하는 AD524X_t 구조체

3.2.2 소스 파일 (AD524X.c)

드라이버의 주요 함수는 다음과 같습니다:

  1. AD524X_Init: 디바이스 초기화, I2C 연결 확인, 기본 저항 값 설정
  2. AD524X_IsConnected: I2C 디바이스 연결 상태 확인
  3. AD524X_Write: 특정 RDAC 채널에 저항 값 쓰기
  4. AD524X_WriteWithOutputs: 저항 값과 함께 O1, O2 출력 핀 제어
  5. AD524X_SetShutdown: 셧다운 모드 활성화/비활성화
  6. AD524X_GetAddress: 디바이스 I2C 주소 반환

3.2.3 주요 구현 특징

  • STM32 HAL 기반: 안정성과 호환성 보장
  • 모듈화: 단일 책임 원칙 준수
  • 채널 관리: 단일/듀얼 채널 디바이스 동적 지원
  • 타이밍 관리: I2C 전송 후 안정화 대기 시간 포함
  • 확장성: 다양한 저항 옵션 및 애플리케이션 지원

3.3 사용 방법

  1. I2C 설정: STM32CubeMX 또는 코드로 I2C1 설정(100 kHz, 7비트 주소)
  2. 초기화: AD524X_Init 호출
  3. 저항 값 설정: AD524X_Write 또는 AD524X_WriteWithOutputs 호출
  4. 셧다운 모드: AD524X_SetShutdown 호출
  5. 디바이스 연결 확인: AD524X_IsConnected 호출

3.4 제한사항 및 주의사항

  • 하드웨어 연결: I2C 핀(SDA, SCL)과 AD0, AD1 핀 올바른 연결 필수
  • I2C 주소: AD0, AD1 핀 상태에 따라 주소 설정 확인(데이터시트 참조)
  • 타이밍: 애플리케이션에 따라 I2C 전송 대기 시간 조정 가능
  • 셧다운 핀: 하드웨어 셧다운 핀이 활성화된 경우 소프트웨어 명령 무시 가능

4. 구현 코드

4.1 헤더 파일 (AD524X.h)

/*
 * 파일명: AD524X.h
 * 설명: AD5241/AD5242/AD5280/AD5282 디지털 포텐셔미터를 STM32 마이크로컨트롤러에서
 *       제어하기 위한 헤더 파일. I2C 통신을 통해 저항 값 설정, 출력 핀 제어,
 *       셧다운 모드 설정 등을 지원
 */

#ifndef AD524X_H_
#define AD524X_H_

#include "stm32l4xx_hal.h"
#include <stdbool.h>
#include <stdint.h>

/* 상수 정의 */
#define AD524X_MIDPOINT 127 // 중간값 (256단계 중)

/* 디바이스 구조체 정의 */
typedef struct {
    uint8_t i2c_address;    // 디바이스 I2C 주소 (7비트)
    I2C_HandleTypeDef *hi2c; // I2C 핸들
    uint8_t num_channels;   // 채널 수 (1: AD5241/AD5280, 2: AD5242/AD5282)
} AD524X_t;

/* 함수 프로토타입 */

/**
 * @brief AD524X 디바이스 초기화
 * @param dev AD524X_t 구조체 포인터
 * @param hi2c I2C 핸들
 * @param i2c_address 디바이스 I2C 주소 (7비트)
 * @param num_channels 채널 수 (1: AD5241/AD5280, 2: AD5242/AD5282)
 * @return HAL_StatusTypeDef
 */
HAL_StatusTypeDef AD524X_Init(AD524X_t *dev, I2C_HandleTypeDef *hi2c, uint8_t i2c_address, uint8_t num_channels);

/**
 * @brief 디바이스 연결 확인
 * @param dev AD524X_t 구조체 포인터
 * @return HAL_StatusTypeDef
 */
HAL_StatusTypeDef AD524X_IsConnected(AD524X_t *dev);

/**
 * @brief RDAC 채널에 저항 값 쓰기
 * @param dev AD524X_t 구조체 포인터
 * @param rdac 채널 번호 (0 또는 1)
 * @param value 저항 값 (0~255)
 * @return HAL_StatusTypeDef
 */
HAL_StatusTypeDef AD524X_Write(AD524X_t *dev, uint8_t rdac, uint8_t value);

/**
 * @brief RDAC 채널에 저항 값과 출력 핀(O1, O2) 쓰기
 * @param dev AD524X_t 구조체 포인터
 * @param rdac 채널 번호 (0 또는 1)
 * @param value 저항 값 (0~255)
 * @param o1 출력 핀 O1 상태 (0 또는 1)
 * @param o2 출력 핀 O2 상태 (0 또는 1)
 * @return HAL_StatusTypeDef
 */
HAL_StatusTypeDef AD524X_WriteWithOutputs(AD524X_t *dev, uint8_t rdac, uint8_t value, uint8_t o1, uint8_t o2);

/**
 * @brief 셧다운 모드 설정
 * @param dev AD524X_t 구조체 포인터
 * @param rdac 채널 번호 (0 또는 1)
 * @param shutdown 셧다운 상태 (1: 활성화, 0: 비활성화)
 * @return HAL_StatusTypeDef
 */
HAL_StatusTypeDef AD524X_SetShutdown(AD524X_t *dev, uint8_t rdac, uint8_t shutdown);

/**
 * @brief 디바이스 I2C 주소 가져오기
 * @param dev AD524X_t 구조체 포인터
 * @return 7비트 I2C 주소
 */
uint8_t AD524X_GetAddress(AD524X_t *dev);

#endif /* AD524X_H_ */

4.2 소스 파일 (AD524X.c)

/*
 * 파일명: AD524X.c
 * 설명: AD5241/AD5242/AD5280/AD5282 디지털 포텐셔미터를 STM32 마이크로컨트롤러에서
 *       제어하기 위한 드라이버 구현. I2C 통신을 통해 저항 값 설정, 출력 핀 제어,
 *       셧다운 모드 설정 등을 수행
 */

#include "AD524X.h"

/**
 * @brief 디바이스 초기화
 * @param dev AD524X_t 구조체 포인터
 * @param hi2c I2C 핸들
 * @param i2c_address 디바이스 I2C 주소 (7비트)
 * @param num_channels 채널 수 (1: AD5241/AD5280, 2: AD5242/AD5282)
 * @return HAL_StatusTypeDef
 */
HAL_StatusTypeDef AD524X_Init(AD524X_t *dev, I2C_HandleTypeDef *hi2c, uint8_t i2c_address, uint8_t num_channels) {
    if (num_channels != 1 && num_channels != 2) {
        return HAL_ERROR; // 지원하지 않는 채널 수
    }

    dev->hi2c = hi2c;
    dev->i2c_address = i2c_address << 1; // 7비트 주소를 8비트로 변환
    dev->num_channels = num_channels;

    // I2C 연결 확인
    if (AD524X_IsConnected(dev) != HAL_OK) {
        return HAL_ERROR;
    }

    // 디바이스 초기화 (중간값으로 설정)
    for (uint8_t rdac = 0; rdac < dev->num_channels; rdac++) {
        AD524X_Write(dev, rdac, AD524X_MIDPOINT);
    }

    return HAL_OK;
}

/**
 * @brief 디바이스 연결 확인
 * @param dev AD524X_t 구조체 포인터
 * @return HAL_StatusTypeDef
 */
HAL_StatusTypeDef AD524X_IsConnected(AD524X_t *dev) {
    return HAL_I2C_IsDeviceReady(dev->hi2c, dev->i2c_address, 1, 100);
}

/**
 * @brief RDAC 채널에 저항 값 쓰기
 * @param dev AD524X_t 구조체 포인터
 * @param rdac 채널 번호 (0 또는 1)
 * @param value 저항 값 (0~255)
 * @return HAL_StatusTypeDef
 */
HAL_StatusTypeDef AD524X_Write(AD524X_t *dev, uint8_t rdac, uint8_t value) {
    if (rdac >= dev->num_channels) {
        return HAL_ERROR;
    }

    uint8_t data[2];
    data[0] = (rdac & 0x01); // RDAC 선택 (0 또는 1)
    data[1] = value;         // 저항 값 (0~255)

    return HAL_I2C_Master_Transmit(dev->hi2c, dev->i2c_address, data, 2, 100);
}

/**
 * @brief RDAC 채널에 저항 값과 출력 핀(O1, O2) 쓰기
 * @param dev AD524X_t 구조체 포인터
 * @param rdac 채널 번호 (0 또는 1)
 * @param value 저항 값 (0~255)
 * @param o1 출력 핀 O1 상태 (0 또는 1)
 * @param o2 출력 핀 O2 상태 (0 또는 1)
 * @return HAL_StatusTypeDef
 */
HAL_StatusTypeDef AD524X_WriteWithOutputs(AD524X_t *dev, uint8_t rdac, uint8_t value, uint8_t o1, uint8_t o2) {
    if (rdac >= dev->num_channels) {
        return HAL_ERROR;
    }

    uint8_t data[2];
    data[0] = (rdac & 0x01) | (o1 << 2) | (o2 << 3); // RDAC 및 O1, O2 설정
    data[1] = value;                                  // 저항 값 (0~255)

    return HAL_I2C_Master_Transmit(dev->hi2c, dev->i2c_address, data, 2, 100);
}

/**
 * @brief 셧다운 모드 설정
 * @param dev AD524X_t 구조체 포인터
 * @param rdac 채널 번호 (0 또는 1)
 * @param shutdown 셧다운 상태 (1: 활성화, 0: 비활성화)
 * @return HAL_StatusTypeDef
 */
HAL_StatusTypeDef AD524X_SetShutdown(AD524X_t *dev, uint8_t rdac, uint8_t shutdown) {
    if (rdac >= dev->num_channels) {
        return HAL_ERROR;
    }

    uint8_t data[2];
    data[0] = (rdac & 0x01) | (1 << 7); // 셧다운 명령
    data[1] = shutdown ? 0x80 : 0x00;   // 셧다운 모드 활성화/비활성화

    return HAL_I2C_Master_Transmit(dev->hi2c, dev->i2c_address, data, 2, 100);
}

/**
 * @brief 디바이스 I2C 주소 가져오기
 * @param dev AD524X_t 구조체 포인터
 * @return 7비트 I2C 주소
 */
uint8_t AD524X_GetAddress(AD524X_t *dev) {
    return dev->i2c_address >> 1; // 7비트 주소 반환
}

4.3 STM32L432KC 예제 코드 (main.c)

/*
 * 파일명: main.c
 * 설명: STM32L432KC에서 AD5242 드라이버를 사용해 저항 값을 설정하고 상태를 UART로 출력하는 예제
 *       시스템 클럭 80 MHz, I2C 통신을 통해 AD5242 제어
 */

#include "stm32l4xx_hal.h" // STM32L4 HAL 라이브러리 포함
#include "AD524X.h"        // AD524X 드라이버 헤더 파일 포함
#include <stdio.h>         // 표준 입출력 함수 사용 (snprintf 등)
#include <string.h>        // 문자열 처리 함수 사용 (strlen 등)

/* 전역 변수 선언 */
I2C_HandleTypeDef hi2c1;         // I2C1 핸들러: AD5242와의 통신을 위해 사용
UART_HandleTypeDef huart2;       // USART2 핸들러: 디버깅 출력을 위해 사용
char uart_buf[50];               // UART 전송 버퍼: 출력 메시지 저장
int uart_buf_len;                // UART 전송 버퍼 길이: 전송할 데이터 크기

/* 함수 프로토타입 선언 */
void SystemClock_Config(void);    // 시스템 클럭 설정 함수
static void MX_GPIO_Init(void);   // GPIO 초기화 함수
static void MX_I2C1_Init(void);   // I2C1 초기화 함수
static void MX_USART2_UART_Init(void); // USART2 초기화 함수

/**
 * @brief 시스템 클럭 설정
 * @details STM32L432KC의 시스템 클럭을 80 MHz로 설정
 *          HSI 오실레이터와 PLL을 사용하여 클럭 구성
 */
void SystemClock_Config(void) {
    RCC_OscInitTypeDef RCC_OscInitStruct = {0}; // 오실레이터 설정 구조체 초기화
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; // 클럭 설정 구조체 초기화

    // HSI 오실레이터 활성화 (16 MHz)
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; // HSI 오실레이터 선택
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;                   // HSI 활성화
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; // HSI 기본 캘리브레이션 값
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;               // PLL 활성화
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;       // PLL 소스로 HSI 선택
    RCC_OscInitStruct.PLL.PLLM = 1;                            // PLL 입력 분주: 16 MHz / 1 = 16 MHz
    RCC_OscInitStruct.PLL.PLLN = 10;                           // PLL 배수: 16 MHz * 10 = 160 MHz
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;                // PLLP 분주 (사용 안 함)
    RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;                // PLLQ 분주 (사용 안 함)
    RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;                // PLLR 분주: 160 MHz / 2 = 80 MHz
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {     // 오실레이터 설정 적용
        while (1); // 설정 실패 시 무한 루프
    }

    // 시스템 클럭 설정
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; // 설정할 클럭 종류
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 시스템 클럭 소스로 PLL 선택
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;        // AHB 클럭: 80 MHz
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;         // APB1 클럭: 80 MHz
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;         // APB2 클럭: 80 MHz
    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) { // 클럭 설정 적용, 플래시 레이턴시 4
        while (1); // 설정 실패 시 무한 루프
    }

    // 시스템 타이머 클럭 활성화
    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000); // 1ms 단위로 시스템 틱 설정
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); // 시스템 틱 클럭 소스 설정
    HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); // 시스템 틱 인터럽트 우선순위 설정
}

/**
 * @brief I2C1 초기화
 * @details I2C1을 표준 모드(100 kHz)로 설정, AD5242와 통신을 위해 250 kHz 클럭 사용
 */
static void MX_I2C1_Init(void) {
    hi2c1.Instance = I2C1;                             // I2C1 모듈 선택
    hi2c1.Init.Timing = 0x10909CEC;                    // 100 kHz 타이밍 설정
    hi2c1.Init.OwnAddress1 = 0;                        // 자체 주소 (사용 안 함)
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; // 7비트 주소 모드
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; // 듀얼 주소 비활성화
    hi2c1.Init.OwnAddress2 = 0;                        // 두 번째 주소 (사용 안 함)
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; // 일반 호출 비활성화
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;  // 클럭 스트레칭 비활성화
    if (HAL_I2C_Init(&hi2c1) != HAL_OK) {              // I2C 초기화
        while (1); // 초기화 실패 시 무한 루프
    }
}

/**
 * @brief USART2 초기화
 * @details 디버깅 출력을 위해 USART2를 115200 baud로 설정
 */
static void MX_USART2_UART_Init(void) {
    huart2.Instance = USART2;                          // USART2 모듈 선택
    huart2.Init.BaudRate = 115200;                    // 전송 속도 115200 baud
    huart2.Init.WordLength = UART_WORDLENGTH_8B;       // 8비트 데이터 길이
    huart2.Init.StopBits = UART_STOPBITS_1;           // 1 스톱 비트
    huart2.Init.Parity = UART_PARITY_NONE;            // 패리티 비활성화
    huart2.Init.Mode = UART_MODE_TX_RX;               // 송수신 모드
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;      // 하드웨어 흐름 제어 비활성화
    huart2.Init.OverSampling = UART_OVERSAMPLING_16;  // 16배 오버샘플링
    huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; // 1비트 샘플링 비활성화
    huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1; // UART 클럭 분주 1
    if (HAL_UART_Init(&huart2) != HAL_OK) {           // UART 초기화
        while (1); // 초기화 실패 시 무한 루프
    }
}

/**
 * @brief GPIO 초기화
 * @details I2C1 및 USART2 핀을 설정, ADS124S08 관련 GPIO 핀은 ADS124S08.c에서 설정
 */
static void MX_GPIO_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0}; // GPIO 설정 구조체 초기화

    // GPIO 포트 클럭 활성화
    __HAL_RCC_GPIOA_CLK_ENABLE(); // GPIOA 클럭 활성화 (UART2, ADS124S08 핀)
    __HAL_RCC_GPIOB_CLK_ENABLE(); // GPIOB 클럭 활성화 (ADS124S08 핀)

    // I2C1 핀 설정 (PB6: SCL, PB7: SDA)
    GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;     // I2C1 핀 선택
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;            // 대체 기능 오픈 드레인 모드
    GPIO_InitStruct.Pull = GPIO_PULLUP;                // 풀업 저항 활성화
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // 고속 동작
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;         // I2C1 대체 기능 매핑
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);           // GPIOB 핀 초기화

    // UART2 핀 설정 (PA2: TX, PA3: RX)
    GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;     // UART2 핀 선택
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;            // 대체 기능 푸시-풀 모드
    GPIO_InitStruct.Pull = GPIO_NOPULL;                // 풀업/풀다운 비활성화
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // 고속 동작
    GPIO_InitStruct.Alternate = GPIO_AF7_USART2;       // USART2 대체 기능 매핑
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);           // GPIOA 핀 초기화
}

/**
 * @brief 메인 함수
 * @details 시스템 초기화, AD5242 설정, 저항 값 설정 및 UART 출력
 */
int main(void) {
    // STM32 HAL 라이브러리 초기화
    HAL_Init(); // HAL 초기화, 기본 시스템 설정 수행

    // 시스템 클럭 설정 (80 MHz)
    SystemClock_Config(); // 시스템 클럭을 80 MHz로 설정

    // GPIO 및 주변 장치 초기화
    MX_GPIO_Init();       // I2C1 및 UART2 GPIO 핀 초기화
    MX_I2C1_Init();       // I2C1 초기화 (AD5242 통신용)
    MX_USART2_UART_Init(); // USART2 초기화 (디버깅 출력용)

    // AD5242 초기화 (I2C 주소: 0x2C, 채널 수: 2)
    AD524X_t ad5242;
    if (AD524X_Init(&ad5242, &hi2c1, 0x2C, 2) != HAL_OK) {
        // 초기화 실패 시 오류 메시지 출력
        uart_buf_len = snprintf(uart_buf, sizeof(uart_buf), "AD5242 Init Failed\r\n");
        HAL_UART_Transmit(&huart2, (uint8_t *)uart_buf, uart_buf_len, HAL_MAX_DELAY);
        while (1); // 무한 루프
    }

    // 초기화 성공 메시지 출력
    uart_buf_len = snprintf(uart_buf, sizeof(uart_buf), "AD5242 Initialized, Address: 0x%02X\r\n", AD524X_GetAddress(&ad5242));
    HAL_UART_Transmit(&huart2, (uint8_t *)uart_buf, uart_buf_len, HAL_MAX_DELAY);

    // 채널 0에 저항 값 100 설정
    if (AD524X_Write(&ad5242, 0, 100) == HAL_OK) {
        uart_buf_len = snprintf(uart_buf, sizeof(uart_buf), "RDAC0 set to 100\r\n");
        HAL_UART_Transmit(&huart2, (uint8_t *)uart_buf, uart_buf_len, HAL_MAX_DELAY);
    }

    // 채널 1에 저항 값 200, 출력 핀 O1=1, O2=0 설정
    if (AD524X_WriteWithOutputs(&ad5242, 1, 200, 1, 0) == HAL_OK) {
        uart_buf_len = snprintf(uart_buf, sizeof(uart_buf), "RDAC1 set to 200, O1=1, O2=0\r\n");
        HAL_UART_Transmit(&huart2, (uint8_t *)uart_buf, uart_buf_len, HAL_MAX_DELAY);
    }

    // 채널 0 셧다운 모드 활성화
    if (AD524X_SetShutdown(&ad5242, 0, 1) == HAL_OK) {
        uart_buf_len = snprintf(uart_buf, sizeof(uart_buf), "RDAC0 Shutdown Enabled\r\n");
        HAL_UART_Transmit(&huart2, (uint8_t *)uart_buf, uart_buf_len, HAL_MAX_DELAY);
    }

    // 무한 루프
    while (1) {
        HAL_Delay(1000); // 1초 대기
        // 주기적으로 저항 값 변경 예시
        uint8_t value = (HAL_GetTick() / 1000) % 256; // 0~255 순환
        if (AD524X_Write(&ad5242, 0, value) == HAL_OK) {
            uart_buf_len = snprintf(uart_buf, sizeof(uart_buf), "RDAC0 updated to %d\r\n", value);
            HAL_UART_Transmit(&huart2, (uint8_t *)uart_buf, uart_buf_len, HAL_MAX_DELAY);
        }
    }
}

/**
 * @brief 시스템 클럭 및 NVIC 설정 후 호출되는 사용자 정의 함수
 * @details 시스템 전역 설정 초기화
 */
void HAL_MspInit(void) {
    __HAL_RCC_SYSCFG_CLK_ENABLE(); // SYSCFG 클럭 활성화 (인터럽트 설정용)
    __HAL_RCC_PWR_CLK_ENABLE();    // PWR 클럭 활성화 (전원 관리용)
}

/**
 * @brief I2C MSP 초기화
 * @details I2C1 모듈의 클럭 활성화
 * @param hi2c I2C 핸들러
 */
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) {
    if (hi2c->Instance == I2C1) { // I2C1 모듈 확인
        __HAL_RCC_I2C1_CLK_ENABLE(); // I2C1 클럭 활성화
    }
}

/**
 * @brief UART MSP 초기화
 * @details USART2 모듈의 클럭 활성화
 * @param huart UART 핸들러
 */
void HAL_UART_MspInit(UART_HandleTypeDef* huart) {
    if (huart->Instance == USART2) { // USART2 모듈 확인
        __HAL_RCC_USART2_CLK_ENABLE(); // USART2 클럭 활성화
    }
}

/**
 * @brief I2C MSP 해제
 * @details I2C1 모듈의 클럭 비활성화
 * @param hi2c I2C 핸들러
 */
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c) {
    if (hi2c->Instance == I2C1) {
        __HAL_RCC_I2C1_CLK_DISABLE(); // I2C1 클럭 비활성화
    }
}

/**
 * @brief UART MSP 해제
 * @details USART2 모듈의 클럭 비활성화
 * @param huart UART 핸들러
 */
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) {
    if (huart->Instance == USART2) {
        __HAL_RCC_USART2_CLK_DISABLE(); // USART2 클럭 비활성화
    }
}

5. 결론

이 문서는 AD5241, AD5242, AD5280, AD5282 디지털 포텐셔미터를 STM32L432KC에서 제어하기 위한 디바이스 드라이버와 예제 구현을 상세히 설명하였습니다. 드라이버는 STM32 HAL 라이브러리를 기반으로 하며, I2C 통신을 통해 저항 값 설정, 출력 핀(O1, O2) 제어, 셧다운 모드 설정을 지원합니다. 예제 코드는 시스템 클럭을 80 MHz로 설정하고, AD5242의 두 채널을 제어하며 UART로 상태를 출력하며, 상세한 주석을 통해 코드의 각 부분을 명확히 설명하였습니다. 이 드라이버와 예제는 오디오 시스템, 산업용 제어, 계측 등 다양한 애플리케이션에 활용될 수 있으며, 필요에 따라 I2C 주소나 저항 값 설정을 확장할 수 있습니다.

반응형