본문 바로가기
MCU/AVR

[AVR128DB48] PWM 사용 방법 및 예제 코드

by linuxgo 2025. 8. 20.
반응형

1. AVR128DB48 PWM 모듈 개요

Microchip의 AVR128DB48은 AVR DB 시리즈의 8비트 마이크로컨트롤러로, PWM(Pulse Width Modulation)을 활용한 LED 밝기 제어, 모터 속도 제어, 신호 발생 등 다양한 애플리케이션에 적합합니다. AVR128DB48의 TCA(Timer/Counter Type A)와 TCB(Timer/Counter Type B) 모듈은 고해상도 PWM 출력을 제공하며, 유연한 설정과 높은 정밀도를 지원합니다. 이 문서에서는 AVR128DB48의 PWM 설정 방법, Bitfield 구조를 활용한 레지스터 설정, 그리고 실용적인 예제 코드를 제공하여 초보자와 숙련된 개발자 모두 쉽게 활용할 수 있도록 돕습니다.

주요 사양

  • PWM 모듈:
    • TCA: 16비트 타이머/카운터, 최대 6채널 PWM 출력
    • TCB: 16비트 타이머/카운터, 단일 채널 PWM 출력
  • 포트:
    • TCA: PORTA, PORTC, PORTF (WO0~WO5)
    • TCB: PORTA, PORTB, PORTC, PORTD, PORTE, PORTF
  • 클럭 소스: 시스템 클럭 (최대 24MHz, OSCHF 내부 오실레이터), 외부 클럭, 프리스케일러 지원
  • PWM 모드:
    • TCA: 단일 슬로프, 이중 슬로프, 분할 모드
    • TCB: 8비트 PWM, 단일 슬로프
  • 해상도: TCA는 16비트, TCB는 8비트 또는 16비트
  • 주요 레지스터:
    • TCA.CTRLA: 타이머 활성화 및 클럭 설정
    • TCA.CTRLB: PWM 모드 및 출력 설정
    • TCA.PER: 주기 설정
    • TCA.CMPn: 비교 레지스터 (듀티 사이클 설정, n=0~5)
    • TCB.CTRLA: 타이머 활성화 및 클럭 설정
    • TCB.CTRLB: PWM 모드 설정
    • TCB.CCMP: 비교 레지스터 (주기 및 듀티 사이클)
  • 전력 관리: 저전력 모드에서 PWM 동작 지원
  • 전압 레벨: 1.8V~5.5V 동작 지원

2. PWM Bitfield 설정 상세

AVR128DB48의 PWM 관련 레지스터는 Bitfield 구조로 정의되어 있으며, <avr/io.h> 헤더 파일을 통해 접근합니다. 주요 레지스터는 다음과 같습니다:

2.1 TCA.CTRLA (타이머 제어 레지스터 A)

  • bit.ENABLE: 타이머 활성화 (1: 활성화)
  • bit.CLKSEL: 클럭 소스 선택 (예: CLKSEL_DIV1_gc, CLKSEL_DIV64_gc)

2.2 TCA.CTRLB (타이머 제어 레지스터 B)

  • bit.CMPnEN: PWM 출력 활성화 (n=0~5, 1: 활성화)
  • bit.WGMODE: 파형 생성 모드 (예: WGMODE_SINGLESLOPE_gc)

2.3 TCA.PER (주기 레지스터)

  • 주기 값 설정 (PWM 주파수 결정)

2.4 TCA.CMPn (비교 레지스터, n=0~5)

  • 듀티 사이클 설정 (PWM 출력의 High 시간)

2.5 TCB.CTRLA (타이머 제어 레지스터 A)

  • bit.ENABLE: 타이머 활성화 (1: 활성화)
  • bit.CLKSEL: 클럭 소스 선택

2.6 TCB.CTRLB (타이머 제어 레지스터 B)

  • bit.CNTMODE: PWM 모드 설정 (예: CNTMODE_PWM8BIT_gc)

2.7 TCB.CCMP (비교 레지스터)

  • 상위 8비트: 주기, 하위 8비트: 듀티 사이클 (8비트 PWM)

3. PWM 설정 절차

  1. 시스템 초기화:
    •   set_system_clock()로 시스템 클럭 설정 (24MHz, XOSC32K 오토튜닝)
    •   인터럽트 비활성화 (cli())
  2. 타이머 클럭 활성화:
    •   TCA.CTRLA 또는 TCB.CTRLA로 클럭 소스 설정
  3. PWM 모드 설정:
    •   TCA.CTRLB 또는 TCB.CTRLB로 PWM 모드 선택
  4. 주기 및 듀티 사이클 설정:
    •   TCA.PER 및 TCA.CMPn 또는 TCB.CCMP 설정
  5. 출력 핀 설정:
    •   PORTMUX로 PWM 출력 핀 매핑
    •   PORTx.DIRSET으로 출력 핀 설정
  6. 타이머 활성화:
    •   TCA.CTRLA 또는 TCB.CTRLA로 타이머 시작
  7. 인터럽트 설정 (필요 시):
    •   TCA.INTCTRL 또는 TCB.INTCTRL로 인터럽트 활성화

4. PWM 설정 고려사항

  • 클럭 설정: 시스템 클럭(24MHz) 및 프리스케일러 설정으로 PWM 주파수 조정
  • 해상도: TCA는 고해상도(16비트), TCB는 저해상도(8비트) 애플리케이션 적합
  • 포트 멀티플렉싱: PORTMUX 설정으로 PWM 출력 핀 충돌 방지
  • 저전력: 불필요한 타이머 비활성화로 전력 소모 감소
  • 듀티 사이클: CMPn 값은 PER 이하로 설정 (오버플로우 방지)

5. 실용적인 PWM 예제 코드 

아래는 AVR128DB48의 PWM을 Bitfield 구조로 설정한 4개의 예제 코드로, TCA의 단일 슬로프, 이중 슬로프, TCB의 8비트 PWM, 그리고 TCA의 분할 모드(데드타임 삽입)를 각각 다룹니다. 각 예제는 Atmel Studio 또는 MPLAB X IDE와 AVR-GCC 환경에서 실행 가능하며, PWM 주파수 계산식과 상세한 주석이 포함되어 있습니다.

5.1 예제 1: TCA 단일 슬로프 PWM (LED 밝기 제어)

// File: pwm_tca_singleslope.c
// Description: AVR128DB48 TCA 단일 슬로프 PWM 예제 (LED 밝기 제어)
// Compiler: AVR-GCC
// Target: AVR128DB48

#include <avr/io.h>        // AVR 입출력 관련 헤더 파일
#include <util/delay.h>    // 지연 함수 관련 헤더 파일

#define F_CPU 24000000UL  // 시스템 클록 주파수를 24 MHz로 정의 (지연 함수 정확도를 위해 필요)

void set_system_clock(void) {
    // 32.768 kHz 외부 크리스털 오실레이터(XOSC32K) 활성화
    _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, CLKCTRL_ENABLE_bm | CLKCTRL_RUNSTDBY_bm);
    // CLKCTRL.XOSC32KCTRLA: 쓰기 보호 해제 후 XOSC32K 활성화 및 스탠바이 모드 동작 설정
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm));
    // XOSC32K 안정화 대기 (CLKCTRL_XOSC32KS_bm 비트가 1이 될 때까지)
    
    // 내부 OSCHF를 24 MHz로 설정하고 XOSC32K 참조로 오토튜닝 활성화
    _PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, CLKCTRL_FRQSEL_24M_gc | CLKCTRL_AUTOTUNE_bm);
    // CLKCTRL.OSCHFCTRLA: 24 MHz 설정 및 XOSC32K를 참조한 오토튜닝 활성화
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSCHF_gc);
    // CLKCTRL.MCLKCTRLA: 시스템 클럭 소스를 OSCHF로 선택
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, 0x00);
    // CLKCTRL.MCLKCTRLB: 클럭 프리스케일러 비활성화 (24 MHz 그대로 사용)
}

void pwm_init(void) {
    // PA0(WO0)를 PWM 출력으로 설정
    PORTA.DIRSET = PIN0_bm; // PA0를 출력으로 설정 (Curiosity Nano의 LED 연결 가능)
    PORTMUX.TCAROUTEA = PORTMUX_TCA0_PORTA_gc; // TCA0 출력 포트를 PORTA로 설정 (WO0~WO5)
    
    // TCA 설정: 단일 슬로프 PWM
    // PWM 주파수 계산: f_PWM = F_CPU / (프리스케일러 * (PER + 1))
    // 현재 설정: 24MHz / (1 * (65535 + 1)) ≈ 366 Hz
    TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc; // 클럭 분주비 1 (프리스케일러 없음)
    TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_SINGLESLOPE_gc | TCA_SINGLE_CMP0EN_bm; 
    // 단일 슬로프 모드 선택, WO0(PA0) PWM 출력 활성화
    TCA0.SINGLE.PER = 65535; // 주기 설정 (16비트 최대값)
    TCA0.SINGLE.CMP0 = 32768; // 듀티 사이클 50% (32768/65536)
    TCA0.SINGLE.CTRLA |= TCA_SINGLE_ENABLE_bm; // TCA 타이머 활성화
}

int main(void) {
    set_system_clock(); // 시스템 클럭 설정 함수 호출
    pwm_init();         // PWM 초기화 함수 호출

    while (1) {
        // PWM 출력 유지 (LED 밝기 고정)
    }

    return 0; // 프로그램 종료 (실제로는 도달하지 않음)
}

설명:

  • 기능: PA0에서 50% 듀티 사이클의 단일 슬로프 PWM 출력으로 LED 밝기 제어
  • 설정: TCA0 단일 슬로프 모드, 366Hz PWM, PA0 출력
  • 출력: PA0에서 PWM 신호 출력
  • 주파수 계산: f_PWM = F_CPU / (프리스케일러 * (PER + 1)) = 24MHz / (1 * (65535 + 1)) ≈ 366 Hz

5.2 예제 2: TCA 이중 슬로프 PWM (모터 제어)

// File: pwm_tca_dualslope.c
// Description: AVR128DB48 TCA 이중 슬로프 PWM 예제 (모터 제어)
// Compiler: AVR-GCC
// Target: AVR128DB48

#include <avr/io.h>        // AVR 입출력 관련 헤더 파일
#include <util/delay.h>    // 지연 함수 관련 헤더 파일

#define F_CPU 24000000UL  // 시스템 클록 주파수를 24 MHz로 정의

void set_system_clock(void) {
    // 32.768 kHz 외부 크리스털 오실레이터(XOSC32K) 활성화
    _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, CLKCTRL_ENABLE_bm | CLKCTRL_RUNSTDBY_bm);
    // CLKCTRL.XOSC32KCTRLA: 쓰기 보호 해제 후 XOSC32K 활성화 및 스탠바이 모드 동작 설정
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm));
    // XOSC32K 안정화 대기 (CLKCTRL_XOSC32KS_bm 비트가 1이 될 때까지)
    
    // 내부 OSCHF를 24 MHz로 설정하고 XOSC32K 참조로 오토튜닝 활성화
    _PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, CLKCTRL_FRQSEL_24M_gc | CLKCTRL_AUTOTUNE_bm);
    // CLKCTRL.OSCHFCTRLA: 24 MHz 설정 및 XOSC32K를 참조한 오토튜닝 활성화
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSCHF_gc);
    // CLKCTRL.MCLKCTRLA: 시스템 클럭 소스를 OSCHF로 선택
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, 0x00);
    // CLKCTRL.MCLKCTRLB: 클럭 프리스케일러 비활성화 (24 MHz 그대로 사용)
}

void pwm_init(void) {
    // PA0(WO0)를 PWM 출력으로 설정
    PORTA.DIRSET = PIN0_bm; // PA0를 출력으로 설정 (모터 드라이버 연결 가능)
    PORTMUX.TCAROUTEA = PORTMUX_TCA0_PORTA_gc; // TCA0 출력 포트를 PORTA로 설정 (WO0~WO5)
    
    // TCA 설정: 이중 슬로프 PWM
    // PWM 주파수 계산: f_PWM = F_CPU / (프리스케일러 * 2 * PER)
    // 현재 설정: 24MHz / (1 * 2 * 16383) ≈ 732 Hz
    TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc; // 클럭 분주비 1 (프리스케일러 없음)
    TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_DSBOTTOM_gc | TCA_SINGLE_CMP0EN_bm; 
    // 이중 슬로프 모드 선택, WO0(PA0) PWM 출력 활성화
    TCA0.SINGLE.PER = 16383; // 주기 설정
    TCA0.SINGLE.CMP0 = 8192; // 듀티 사이클 50% (8192/16383)
    TCA0.SINGLE.CTRLA |= TCA_SINGLE_ENABLE_bm; // TCA 타이머 활성화
}

int main(void) {
    set_system_clock(); // 시스템 클럭 설정 함수 호출
    pwm_init();         // PWM 초기화 함수 호출

    while (1) {
        // PWM 출력 유지 (모터 속도 고정)
    }

    return 0; // 프로그램 종료 (실제로는 도달하지 않음)
}

설명:

  • 기능: PA0에서 50% 듀티 사이클의 이중 슬로프 PWM 출력으로 모터 속도 제어
  • 설정: TCA0 이중 슬로프 모드, 732Hz PWM, PA0 출력
  • 출력: PA0에서 대칭 PWM 신호 출력
  • 주파수 계산: f_PWM = F_CPU / (프리스케일러 * 2 * PER) = 24MHz / (1 * 2 * 16383) ≈ 732 Hz

5.3 예제 3: TCB 8비트 PWM (LED 페이딩)

// File: pwm_tcb_8bit.c
// Description: AVR128DB48 TCB 8비트 PWM 예제 (LED 페이딩)
// Compiler: AVR-GCC
// Target: AVR128DB48

#include <avr/io.h>        // AVR 입출력 관련 헤더 파일
#include <util/delay.h>    // 지연 함수 관련 헤더 파일

#define F_CPU 24000000UL  // 시스템 클록 주파수를 24 MHz로 정의

void set_system_clock(void) {
    // 32.768 kHz 외부 크리스털 오실레이터(XOSC32K) 활성화
    _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, CLKCTRL_ENABLE_bm | CLKCTRL_RUNSTDBY_bm);
    // CLKCTRL.XOSC32KCTRLA: 쓰기 보호 해제 후 XOSC32K 활성화 및 스탠바이 모드 동작 설정
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm));
    // XOSC32K 안정화 대기 (CLKCTRL_XOSC32KS_bm 비트가 1이 될 때까지)
    
    // 내부 OSCHF를 24 MHz로 설정하고 XOSC32K 참조로 오토튜닝 활성화
    _PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, CLKCTRL_FRQSEL_24M_gc | CLKCTRL_AUTOTUNE_bm);
    // CLKCTRL.OSCHFCTRLA: 24 MHz 설정 및 XOSC32K를 참조한 오토튜닝 활성화
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSCHF_gc);
    // CLKCTRL.MCLKCTRLA: 시스템 클럭 소스를 OSCHF로 선택
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, 0x00);
    // CLKCTRL.MCLKCTRLB: 클럭 프리스케일러 비활성화 (24 MHz 그대로 사용)
}

void pwm_init(void) {
    // PB0를 PWM 출력으로 설정
    PORTB.DIRSET = PIN0_bm; // PB0를 출력으로 설정 (Curiosity Nano의 LED 연결 가능)
    PORTMUX.TCBROUTEA = PORTMUX_TCB0_bm; // TCB0 출력 포트를 PB0로 설정
    
    // TCB 설정: 8비트 PWM
    // PWM 주파수 계산: f_PWM = F_CPU / (프리스케일러 * (CCMP[15:8] + 1))
    // 현재 설정: 24MHz / (1 * (255 + 1)) ≈ 93.75 kHz
    TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc; // 클럭 분주비 1 (프리스케일러 없음)
    TCB0.CTRLB = TCB_CNTMODE_PWM8BIT_gc | TCB_CCMPEN_bm; // 8비트 PWM 모드, 출력 활성화
    TCB0.CCMP = 0x00FF; // 주기 255 (CCMP[15:8]), 듀티 사이클 0% (CCMP[7:0])
    TCB0.CTRLA |= TCB_ENABLE_bm; // TCB 타이머 활성화
}

int main(void) {
    set_system_clock(); // 시스템 클럭 설정 함수 호출
    pwm_init();         // PWM 초기화 함수 호출

    while (1) {
        // LED 페이딩: 밝기 증가
        for (uint8_t duty = 0; duty < 255; duty++) {
            TCB0.CCMP = (duty << 8) | 0xFF; // 듀티 사이클 변경 (상위 8비트: 듀티, 하위 8비트: 주기)
            _delay_ms(10); // 10ms 지연으로 부드러운 페이딩 효과
        }
        // LED 페이딩: 밝기 감소
        for (uint8_t duty = 255; duty > 0; duty--) {
            TCB0.CCMP = (duty << 8) | 0xFF; // 듀티 사이클 변경
            _delay_ms(10); // 10ms 지연
        }
    }

    return 0; // 프로그램 종료 (실제로는 도달하지 않음)
}

설명:

  • 기능: PB0에서 8비트 PWM 출력으로 LED 페이딩 효과 구현
  • 설정: TCB0 8비트 PWM 모드, 93.75kHz PWM, PB0 출력
  • 출력: LED 밝기가 점진적으로 증가 및 감소
  • 주파수 계산: f_PWM = F_CPU / (프리스케일러 * (CCMP[15:8] + 1)) = 24MHz / (1 * (255 + 1)) ≈ 93.75 kHz

5.4 예제 4: TCA 분할 모드 PWM (데드타임 삽입, 모터 제어)

// File: pwm_tca_split_deadtime.c
// Description: AVR128DB48 TCA 분할 모드 PWM 예제 (데드타임 삽입, H-브리지 모터 제어)
// Compiler: AVR-GCC
// Target: AVR128DB48

#include <avr/io.h>        // AVR 입출력 관련 헤더 파일
#include <util/delay.h>    // 지연 함수 관련 헤더 파일

#define F_CPU 24000000UL  // 시스템 클록 주파수를 24 MHz로 정의

void set_system_clock(void) {
    // 32.768 kHz 외부 크리스털 오실레이터(XOSC32K) 활성화
    _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, CLKCTRL_ENABLE_bm | CLKCTRL_RUNSTDBY_bm);
    // CLKCTRL.XOSC32KCTRLA: 쓰기 보호 해제 후 XOSC32K 활성화 및 스탠바이 모드 동작 설정
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm));
    // XOSC32K 안정화 대기 (CLKCTRL_XOSC32KS_bm 비트가 1이 될 때까지)
    
    // 내부 OSCHF를 24 MHz로 설정하고 XOSC32K 참조로 오토튜닝 활성화
    _PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, CLKCTRL_FRQSEL_24M_gc | CLKCTRL_AUTOTUNE_bm);
    // CLKCTRL.OSCHFCTRLA: 24 MHz 설정 및 XOSC32K를 참조한 오토튜닝 활성화
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSCHF_gc);
    // CLKCTRL.MCLKCTRLA: 시스템 클럭 소스를 OSCHF로 선택
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, 0x00);
    // CLKCTRL.MCLKCTRLB: 클럭 프리스케일러 비활성화 (24 MHz 그대로 사용)
}

void pwm_init(void) {
    // PA0(WOL0), PA1(WOH0)를 PWM 출력으로 설정 (H-브리지 모터 제어용 상보 출력)
    PORTA.DIRSET = PIN0_bm | PIN1_bm; // PA0, PA1를 출력으로 설정
    PORTMUX.TCAROUTEA = PORTMUX_TCA0_PORTA_gc; // TCA0 출력 포트를 PORTA로 설정
    
    // TCA 설정: 분할 모드 PWM (8비트, 데드타임 삽입)
    // PWM 주파수 계산: f_PWM = F_CPU / (프리스케일러 * (PER + 1))
    // 현재 설정: 24MHz / (1 * (255 + 1)) ≈ 93.75 kHz
    TCA0.SPLIT.CTRLA = TCA_SPLIT_CLKSEL_DIV1_gc; // 클럭 분주비 1 (프리스케일러 없음)
    TCA0.SPLIT.CTRLB = TCA_SPLIT_LCMP0EN_bm | TCA_SPLIT_HCMP0EN_bm; 
    // 분할 모드에서 WOL0(PA0) 및 WOH0(PA1) PWM 출력 활성화
    TCA0.SPLIT.CTRLD = TCA_SPLIT_SPLITM_bm; // 분할 모드 활성화
    TCA0.SPLIT.LPER = 255; // 저채널 주기 설정 (8비트)
    TCA0.SPLIT.HPER = 255; // 고채널 주기 설정 (8비트)
    TCA0.SPLIT.LCMP0 = 128; // 저채널 듀티 사이클 50% (128/256)
    TCA0.SPLIT.HCMP0 = 128; // 고채널 듀티 사이클 50% (128/256)
    TCA0.SPLIT.CTRLC = 0x0F; // 데드타임 설정 (15 클럭 사이클, 약 625ns at 24MHz)
    TCA0.SPLIT.CTRLA |= TCA_SPLIT_ENABLE_bm; // TCA 타이머 활성화
}

int main(void) {
    set_system_clock(); // 시스템 클럭 설정 함수 호출
    pwm_init();         // PWM 초기화 함수 호출

    while (1) {
        // PWM 출력 유지 (H-브리지 모터 제어용 상보 PWM 출력)
    }

    return 0; // 프로그램 종료 (실제로는 도달하지 않음)
}

설명:

  • 기능: PA0(WOL0)와 PA1(WOH0)에서 데드타임 삽입된 상보 PWM 출력으로 H-브리지 모터 제어
  • 설정: TCA0 분할 모드, 93.75kHz PWM, 625ns 데드타임, PA0/PA1 출력
  • 출력: PA0와 PA1에서 상보 PWM 신호 출력 (데드타임 포함)
  • 주파수 계산: f_PWM = F_CPU / (프리스케일러 * (LPER + 1)) = 24MHz / (1 * (255 + 1)) ≈ 93.75 kHz
  • 데드타임 계산: Dead-time = CTRLC * (1/F_CPU) = 15 * (1/24MHz) ≈ 625 ns

6. 사용 방법

6.1 환경 설정

  • AVR-GCC 설치: Atmel Studio 또는 MPLAB X IDE에 AVR-GCC 툴체인 설치
  • 헤더 파일: <avr/io.h>, <util/delay.h> 포함
  • 프로젝트 설정: AVR128DB48 타겟으로 프로젝트 생성
  • 클럭 정의: #define F_CPU 24000000UL로 시스템 클럭 설정

6.2 코드 실행

  • 각 예제를 별도의 .c 파일로 저장하거나, main.c에 복사
  • 다른 예제 코드 주석 처리
  • Atmel Studio/MPLAB X IDE에서 빌드 및 플래싱

6.3 하드웨어 준비

  • PWM 출력: PA0, PA1, PB0에 LED 또는 모터 드라이버 및 전류 제한 저항(예: 330Ω) 연결
  • 데드타임 예제: PA0/PA1에 H-브리지 회로 연결 (상보 출력 확인)
  • 전원: 1.8V~5.5V 전원 공급
  • 테스트 장비: 오실로스코프 또는 로직 분석기로 PWM 신호 및 데드타임 확인

6.4 디버깅

  • Atmel Studio/MPLAB X IDE의 디버거 사용
  • TCA.PER, TCA.CMPn, TCA.LPER, TCA.HCMPn, TCB.CCMP 레지스터 확인
  • PWM 출력 핀의 신호 및 데드타임을 오실로스코프로 점검

7. 추가 팁

  • 클럭 설정: set_system_clock()로 XOSC32K 안정화 및 24MHz 설정 확인
  • 주파수 계산:
    •   단일 슬로프: f_PWM = F_CPU / (프리스케일러 * (PER + 1))
    •   이중 슬로프: f_PWM = F_CPU / (프리스케일러 * 2 * PER)
    •   TCB 8비트: f_PWM = F_CPU / (프리스케일러 * (CCMP[15:8] + 1))
    •   분할 모드: f_PWM = F_CPU / (프리스케일러 * (LPER + 1))
  • 데드타임: TCA.CTRLC로 설정, 데드타임 = CTRLC * (1/F_CPU)
  • Microchip 리소스: AVR128DB48 데이터시트, Application Notes (AN), AVR-GCC 예제
  • 문제 해결:
    •   출력 없음: PORTMUX 및 PORTx.DIRSET 설정 확인
    •   PWM 주파수 오류: TCA.PER, TCA.LPER, TCB.CCMP 값 확인
    •   데드타임 오류: TCA.CTRLC 설정 및 오실로스코프로 확인
    •   불안정한 출력: 클럭 소스 및 프리스케일러 설정 점검
  • 커뮤니티: Microchip Community, AVR Freaks 포럼 참고

8. 결론

이 문서는 AVR128DB48의 PWM 모듈 설정 방법과 Bitfield 구조를 활용한 예제 코드를 제공하여 LED 밝기 제어, 모터 제어, 페이딩 효과, 데드타임 삽입 등 다양한 애플리케이션에 적용 가능하도록 구성했습니다. 초보자는 단일 슬로프 PWM 예제부터 시작하고, 숙련자는 이중 슬로프, 8비트 PWM, 분할 모드(데드타임)를 활용하여 복잡한 시스템을 구현할 수 있습니다.

키워드: AVR128DB48, PWM, TCA, TCB, 마이크로컨트롤러, Atmel Studio, MPLAB X IDE, LED 밝기 제어, 모터 제어, 페이딩, 데드타임, 클럭 설정

반응형