본문 바로가기

[TI]/MSP0M

[MSPM0G3507 SSM] 12bit DAC 테스트 - 사인파 출력하기

 

MSPM0G3507의 특징으로 12Bit DAC가 있다. MSPM0L 시리즈는 8bit DAC가 있어 약간 아쉬움이 있었는데… 12bit DAC로 좀더 고성능 DAC를 테스트 해 볼 수 있을것 같다. 

 

 



MSPM0의 아날로그 기능은 다양한 옵션설정으로 고성능의 프로젝트에 적용할 수 있다. 

 


우선 SysConfig로 DAC12를 추가 하고 레퍼런스 및 핀맵을 설정하자.

 

 

DAC의 클럭 베이스는 MFPCLK인데 디폴트는 사용하지 않는 것으로 되어 있기 때문에 체크 해 주어야 한다.

 


DAC12 출력은 다양한 아날로그 기능에 설정할 수 있는데 단순히 DAC출력을 확인하기 위해 Output Amp에 할당하자.

 

 

SysConfig 설정후 빌드하면 자동 코드가 생성되는데 DL_DAC12_output12 함수로 DAC 출력을 할 수 있다. 

#include "ti_msp_dl_config.h"

int main(void)
{
    SYSCFG_DL_init();

    /* 원하는 출력 값 설정 (예: 절반 스케일 0x7FF = 2047) */
    DL_DAC12_output12(DAC0, 0x07FF);
    
    while (1) {
        __WFI();
    }
}

 

테스트 결과 DAC핀으로 레퍼런스의 1/2 전압이 정상적으로 출력되는것을 확인 할 수 있다.

 


이제 MSPM0G3507에서 DAC로 사인파 출력 예제를 작성해 보자.

우선 타이머 인터럽트를 추가 하고 주기적으로 사인파 테이블 값을 DAC로 출력 하는 코드를 작성해 보자.

 

#include "ti_msp_dl_config.h"
#include <math.h>
#include <stdint.h>

#define TABLE_SIZE   256
#define DAC_MAX      0x0FFF

volatile uint32_t phase_acc = 0;
volatile uint32_t phase_step = 0;   // 주파수 제어 변수
uint16_t sine_table[TABLE_SIZE];

// 샘플링 주파수 (타이머 인터럽트 발생률)
#define FS  100000   // 100 kHz

void make_sine_table(void)
{
    for (int i = 0; i < TABLE_SIZE; i++) {
        double theta = (2.0 * M_PI * i) / TABLE_SIZE;
        sine_table[i] = (uint16_t)((sin(theta) * 0.5 + 0.5) * DAC_MAX);
    }
}
extern volatile uint32_t interruptVectors[];

/* GPTIMER ISR */
void TIMER_0_INST_IRQHandler(void)
{
    //DL_TimerA_clearInterruptStatus(TIMER_0_INST, DL_TIMERG_INTERRUPT_LOAD);
    switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST)) {
        case DL_TIMER_IIDX_ZERO:

            phase_acc += phase_step;
            uint16_t idx = phase_acc >> 24;  // 상위 8비트 사용 (256포인트 LUT)

            DL_DAC12_output12(DAC0, sine_table[idx]);

            break;
        default:
            break;
    }
}

int main(void)
{
    SYSCFG_DL_init();
    make_sine_table();

    NVIC_EnableIRQ(GPIO_SWITCHES_INT_IRQN);
    NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);

    // 초기 출력 주파수 = 1 kHz
    // Δ = f_out / f_s * 2^32
    double fout = 1000.0;
    phase_step = (uint32_t)((fout * (double)(1ULL<<32)) / FS);
    
    DL_TimerG_startCounter(TIMER_0_INST);
    
    while (1) {
        __WFI();
    }
}

void GROUP1_IRQHandler(void)
{
    switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) {
        case GPIO_SWITCHES_INT_IIDX:
            /* If SW is high, turn the LED off */
            if (DL_GPIO_readPins(
                    GPIO_SWITCHES_PORT, GPIO_SWITCHES_USER_SWITCH_1_PIN)) {
                DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            }
            /* Otherwise, turn the LED on */
            else {
                DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            }
            break;
    }
}

 

코드 테스트 결과 MSPM0G3507의 DAC핀으로 1khz의 사인파가 DAC12로 출력 되는것을 확인 할수 있다.

DAC DMA를 이용하면 15.625kHz로 출력 가능하다고 한다. 다음에는 DAC DMA를 이용해여 고속 사인파 출력 테스트를 해 봐야 할것 같다.

 

반응형