본문 바로가기
MCU/AVR

[AVR128DB48] 클럭 설정 상세 가이드

by linuxgo 2025. 8. 20.
반응형

AVR128DB48 마이크로컨트롤러의 클럭 시스템은 유연성과 저전력 설계를 지원하며, 다양한 클럭 소스와 설정 옵션을 제공합니다. 이 문서는 클럭 시스템의 구조, 설정 절차, 그리고 특히 내부 고주파 오실레이터(OSCHF)의 오토튜닝(자동 튜닝) 기능을 포함한 다양한 예제 코드를 상세한 주석과 함께 제공합니다. Microchip의 공식 데이터시트와 TB3234 기술 문서를 기반으로 하며, _PROTECTED_WRITE 매크로를 사용하여 CCP 보호 레지스터를 안전하게 수정합니다. 

1. 클럭 시스템 개요

AVR128DB48의 클럭 시스템은 CPU와 주변 장치(peripherals)를 구동하는 핵심 구성 요소입니다. 시스템 성능, 전력 효율성, 그리고 특정 애플리케이션 요구사항을 충족하도록 설계되었습니다.

1.1 클럭 소스

AVR128DB48은 다음과 같은 클럭 소스를 지원합니다:

  • 내부 고주파 오실레이터 (OSCHF): 1~24 MHz, 기본 24 MHz, 자동 튜닝 지원. 지원 주파수는 1, 2, 3, 4, 8, 12, 16, 20, 24 MHz입니다. 오토튜닝은 내부 32 kHz 오실레이터(OSC32K) 또는 외부 32.768 kHz 크리스털(XOSC32K)을 참조하여 주파수 안정성을 보정합니다.
  • 내부 저주파 오실레이터 (OSC32K): 32.768 kHz, 주로 RTC(실시간 카운터)에 사용.
  • 외부 32.768 kHz 크리스털 오실레이터 (XOSC32K): 저전력 RTC 애플리케이션에 적합, 오토튜닝 참조 클럭으로 사용 가능.
  • 외부 고주파 크리스털 오실레이터 (XOSC): 최대 32 MHz, 고정밀 타이밍 요구 시 사용.
  • 외부 클럭 입력 (EXTCLK): 최대 24 MHz의 외부 클럭 신호 입력, PA0 핀 사용.

1.2 클럭 도메인

  • CLK_MAIN: CPU와 대부분의 주변 장치 구동.
  • CLK_RTC: RTC와 주기적 인터럽트 타이머(PIT) 구동.
  • CLKOUT: 클럭 신호를 외부 핀(PA7)으로 출력하여 디버깅 또는 동기화에 사용.

1.3 주요 레지스터

클럭 시스템은 CLKCTRL 모듈로 제어됴며, 주요 레지스터는 다음과 같습니다:

  • CLKCTRL.MCLKCTRLA: 메인 클럭 소스 선택 및 CLKOUT 설정.
  • CLKCTRL.MCLKCTRLB: 프리스케일러 설정.
  • CLKCTRL.MCLKSTATUS: 클럭 상태 확인.
  • CLKCTRL.OSCHFCTRLA: 내부 고주파 오실레이터 주파수 및 오토튜닝 설정.
  • CLKCTRL.XOSC32KCTRLA: 외부 32.768 kHz 크리스털 설정.
  • CLKCTRL.XOSCCFG: 외부 고주파 크리스털 또는 외부 클럭 설정.

1.4 보호 메커니즘

클럭 설정 변경은 Configuration Change Protection (CCP) 메커니즘으로 보호됩니다. CLKCTRL 레지스터를 수정하려면 _PROTECTED_WRITE 매크로를 사용하여 CPU_CCP 레지스터에 시그니처 0xD8(CCP_IOREG_gc)을 작성하고 값을 기록해야 합니다.

1.5 오토튜닝 기능

OSCHF는 오토튜닝 기능을 지원하여 주파수 안정성을 향상시킵니다. 이 기능은 CLKCTRL.OSCHFCTRLA의 AUTOTUNE 비트를 설정하여 활성화하며, 내부 OSC32K 또는 외부 XOSC32K를 참조 클럭으로 사용합니다. 오토튜닝은 주로 UART 통신, 타이밍 크리티컬 작업 등에서 정확한 클럭을 유지하는 데 유용합니다. TB3234에 따르면, 오토튜닝은 24 MHz 설정에서도 효과적으로 동작하며, CLKOUT 핀(PA7)을 통해 오실로스코프로 주파수 정확성을 비교할 수 있습니다.

2. 클럭 설정 절차

클럭 설정은 애플리케이션 요구사항에 따라 다르며, 아래는 다양한 시나리오에 대한 상세 절차와 예제 코드입니다. 

2.1 예제 1: 내부 고주파 오실레이터 (OSCHF) 설정 - 24 MHz

내부 오실레이터를 24 MHz로 설정하고 프리스케일러를 적용하는 예제입니다.

#include <avr/io.h>
#include <avr/cpufunc.h>

// 내부 24 MHz 오실레이터 설정 함수
void configure_oshcf_24mhz(void) {
    // 1. OSCHF 주파수를 24 MHz로 설정하고 자동 튜닝 활성화
    // FRQSEL_24M_gc: 24 MHz 선택 (데이터시트 FRQSEL[3:0]=0x09)
    // AUTOTUNE_bm: 주파수 안정성을 위한 자동 튜닝 활성화 (OSC32K 또는 XOSC32K 참조)
    CLKCTRL.OSCHFCTRLA = CLKCTRL_FRQSEL_24M_gc | CLKCTRL_AUTOTUNE_bm;
    
    // 2. 오실레이터가 안정화될 때까지 대기
    // OSCHFRDY_bm: 오실레이터 준비 완료 상태 비트
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_OSCHFRDY_bm));
    
    // 3. 메인 클럭 소스를 OSCHF로 변경
    // CLKSEL_OSCHF_gc: OSCHF를 메인 클럭 소스로 선택
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSCHF_gc);
    
    // 4. 클럭 소스 전환 완료 대기
    // SOSC_bm: 클럭 소스 전환 진행 중 상태 비트
    while (CLKCTRL.MCLKSTATUS & CLKCTRL_SOSC_bm);
    
    // 5. 프리스케일러 설정 (예: 2X, 24 MHz / 2 = 12 MHz)
    // PDIV_2X_gc: 2배 프리스케일러 선택
    // PEN_bm: 프리스케일러 활성화
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm);
}

2.2 예제 2: 24 MHz OSCHF 오토튜닝 테스트

24 MHz OSCHF를 설정하고 오토튜닝의 효과를 CLKOUT 핀(PA7)을 통해 확인하는 예제입니다. 오토튜닝 활성화/비활성화 시 주파수 정확성을 비교할 수 있습니다.

#include <avr/io.h>
#include <avr/cpufunc.h>

// 24 MHz OSCHF 오토튜닝 테스트 함수
void configure_oshcf_autotune_test(void) {
    // 1. OSCHF를 24 MHz로 설정, 오토튜닝 비활성화
    // FRQSEL_24M_gc: 24 MHz 선택
    CLKCTRL.OSCHFCTRLA = CLKCTRL_FRQSEL_24M_gc;
    // 오실레이터 안정화 대기
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_OSCHFRDY_bm));
    
    // 2. 메인 클럭 소스를 OSCHF로 설정
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSCHF_gc);
    while (CLKCTRL.MCLKSTATUS & CLKCTRL_SOSC_bm);
    
    // 3. CLKOUT 활성화 (PA7 핀으로 출력)
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL.MCLKCTRLA | CLKCTRL_CLKOUT_bm);
    
    // 4. 오토튜닝 비활성화 상태에서 CLKOUT 확인 (오실로스코프 사용)
    // 임의 대기하여 오실로스코프로 주파수 측정
    for (volatile uint32_t i = 0; i < 1000000; i++);
    
    // 5. 오토튜닝 활성화
    // AUTOTUNE_bm: OSC32K 또는 XOSC32K를 참조하여 주파수 보정
    CLKCTRL.OSCHFCTRLA |= CLKCTRL_AUTOTUNE_bm;
    
    // 6. 오토튜닝 활성화 상태에서 CLKOUT 확인
    // 오실로스코프로 주파수 정확성 비교
    for (volatile uint32_t i = 0; i < 1000000; i++);
}

2.3 예제 3: 외부 고주파 크리스털 오실레이터 (XOSC) 설정 - 16 MHz

외부 16 MHz 크리스털을 메인 클럭 소스로 설정하는 예제입니다.

#include <avr/io.h>
#include <avr/cpufunc.h>

// 외부 16 MHz 크리스털 설정 함수
void configure_xosc_16mhz(void) {
    // 1. 외부 크리스털 활성화 및 주파수 범위 설정
    // FRQRANGE_16M_gc: 16 MHz 크리스털 주파수 범위 선택
    // ENABLE_bm: 크리스털 오실레이터 활성화
    CLKCTRL.XOSCCFG = CLKCTRL_FRQRANGE_16M_gc | CLKCTRL_ENABLE_bm;
    
    // 2. 크리스털 안정화 대기
    // XOSCRDY_bm: 크리스털 준비 완료 상태 비트
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSCRDY_bm));
    
    // 3. 메인 클럭 소스를 XOSC로 변경
    // CLKSEL_EXTCLK_gc: XOSC 또는 EXTCLK를 메인 클럭 소스로 선택
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_EXTCLK_gc);
    
    // 4. 클럭 소스 전환 완료 대기
    while (CLKCTRL.MCLKSTATUS & CLKCTRL_SOSC_bm);
    
    // 5. CLKOUT 활성화 (디버깅용, PA7 핀으로 출력)
    // CLKOUT_bm: 클럭 출력 활성화 비트
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL.MCLKCTRLA | CLKCTRL_CLKOUT_bm);
}

2.4 예제 4: 외부 32.768 kHz 크리스털 (XOSC32K) 및 RTC 설정

외부 32.768 kHz 크리스털을 RTC 클럭 소스로 설정하고, 파워-다운 모드에서 1초 주기 인터럽트를 생성하는 예제입니다.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/cpufunc.h>

// 외부 32.768 kHz 크리스털 및 RTC 설정 함수
void configure_xosc32k_rtc(void) {
    // 1. 외부 32.768 kHz 크리스털 활성화
    // ENABLE_bm: XOSC32K 오실레이터 활성화
    CLKCTRL.XOSC32KCTRLA = CLKCTRL_ENABLE_bm;
    
    // 2. 크리스털 안정화 대기
    // XOSC32KRDY_bm: XOSC32K 준비 완료 상태 비트
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KRDY_bm));
    
    // 3. RTC 클럭 소스로 XOSC32K 선택
    // CLKSEL_XOSC32K_gc: XOSC32K를 RTC 클럭 소스로 설정
    RTC.CLKSEL = RTC_CLKSEL_XOSC32K_gc;
    
    // 4. RTC 활성화 및 PIT 설정 (1초 주기)
    // RTCEN_bm: RTC 활성화
    // PERIOD_CYC32768_gc: 32768 사이클 (1초) 주기 설정
    // PITEN_bm: 주기적 인터럽트 타이머 활성화
    RTC.CTRLA = RTC_RTCEN_bm;
    RTC.PITCTRLA = RTC_PERIOD_CYC32768_gc | RTC_PITEN_bm;
    
    // 5. PIT 인터럽트 활성화
    // PI_bm: PIT 인터럽트 활성화 비트
    RTC.PITINTCTRL = RTC_PI_bm;
    
    // 6. 파워-다운 모드 설정
    // SMODE_PDOWN_gc: 파워-다운 모드 선택
    // SEN_bm: 슬립 모드 활성화
    _PROTECTED_WRITE(SLPCTRL.CTRLA, SLPCTRL_SMODE_PDOWN_gc | SLPCTRL_SEN_bm);
}

// PIT 인터럽트 서비스 루틴
ISR(RTC_PIT_vect) {
    // 인터럽트 플래그 클리어
    RTC.PITINTFLAGS = RTC_PI_bm;
    // 추가 작업 (예: LED 토글, 데이터 처리 등)
}

2.5 예제 5: 외부 클럭 입력 (EXTCLK) 설정

PA0 핀을 통해 최대 24 MHz의 외부 클럭 신호를 메인 클럭 소스로 사용하는 예제입니다.

#include <avr/io.h>
#include <avr/cpufunc.h>

// 외부 클럭 입력 설정 함수
void configure_extclk(void) {
    // 1. 외부 클럭 입력 활성화
    // SELHF_bm: 외부 클럭 입력 선택 (PA0 핀, 최대 24 MHz)
    // ENABLE_bm: 외부 클럭 활성화
    CLKCTRL.XOSCCFG = CLKCTRL_SELHF_bm | CLKCTRL_ENABLE_bm;
    
    // 2. 클럭 안정화 대기
    // XOSCRDY_bm: 외부 클럭 준비 완료 상태 비트
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSCRDY_bm));
    
    // 3. 메인 클럭 소스를 EXTCLK로 변경
    // CLKSEL_EXTCLK_gc: EXTCLK를 메인 클럭 소스로 선택
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_EXTCLK_gc);
    
    // 4. 클럭 소스 전환 완료 대기
    while (CLKCTRL.MCLKSTATUS & CLKCTRL_SOSC_bm);
}

2.6 통합 예제: 다중 클럭 소스 설정 및 실행

내부 24 MHz OSCHF(오토튜닝 포함)와 외부 32.768 kHz 크리스털을 함께 사용하는 통합 예제입니다.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/cpufunc.h>

// 내부 24 MHz 오실레이터 설정 (오토튜닝 포함)
void configure_oshcf_24mhz(void) {
    // 1. OSCHF를 24 MHz로 설정, 오토튜닝 활성화
    // FRQSEL_24M_gc: 24 MHz 선택
    // AUTOTUNE_bm: OSC32K 또는 XOSC32K를 참조하여 주파수 보정
    CLKCTRL.OSCHFCTRLA = CLKCTRL_FRQSEL_24M_gc | CLKCTRL_AUTOTUNE_bm;
    // 2. 오실레이터 안정화 대기
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_OSCHFRDY_bm));
    // 3. 메인 클럭 소스 설정
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSCHF_gc);
    // 4. 클럭 소스 전환 대기
    while (CLKCTRL.MCLKSTATUS & CLKCTRL_SOSC_bm);
    // 5. 2X 프리스케일러 설정 (12 MHz)
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm);
}

// 외부 32.768 kHz 크리스털 및 RTC 설정
void configure_xosc32k_rtc(void) {
    // 1. XOSC32K 활성화
    CLKCTRL.XOSC32KCTRLA = CLKCTRL_ENABLE_bm;
    // 2. 크리스털 안정화 대기
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KRDY_bm));
    // 3. RTC 클럭 소스 설정
    RTC.CLKSEL = RTC_CLKSEL_XOSC32K_gc;
    // 4. RTC 및 PIT 설정 (1초 주기)
    RTC.CTRLA = RTC_RTCEN_bm;
    RTC.PITCTRLA = RTC_PERIOD_CYC32768_gc | RTC_PITEN_bm;
    // 5. PIT 인터럽트 활성화
    RTC.PITINTCTRL = RTC_PI_bm;
    // 6. 파워-다운 모드 설정
    _PROTECTED_WRITE(SLPCTRL.CTRLA, SLPCTRL_SMODE_PDOWN_gc | SLPCTRL_SEN_bm);
}

// PIT 인터럽트 서비스 루틴
ISR(RTC_PIT_vect) {
    // 인터럽트 플래그 클리어
    RTC.PITINTFLAGS = RTC_PI_bm;
    // 추가 작업
}

int main(void) {
    // 글로벌 인터럽트 활성화
    sei();
    // 내부 오실레이터 설정 (오토튜닝 포함)
    configure_oshcf_24mhz();
    // RTC 및 외부 크리스털 설정
    configure_xosc32k_rtc();
    
    while (1) {
        // 파워-다운 모드 진입
        __asm("sleep");
    }
}

3. 설정 시 주의사항

  • CCP 보호: CLKCTRL 레지스터 수정 시 _PROTECTED_WRITE 매크로를 사용하여 CPU_CCP에 0xD8(CCP_IOREG_gc)을 작성해야 합니다.
  • 오실레이터 안정화: 외부 크리스털 또는 클럭 소스는 안정화 시간이 필요하므로 MCLKSTATUS 레지스터를 확인하세요.
  • 하드웨어 연결:
    •   외부 크리스털(XOSC, XOSC32K)은 적절한 부하 커패시터(예: 12.5 pF)를 사용해야 합니다.
    •   EXTCLK는 PA0 핀에 연결되며, 최대 24 MHz 입력을 지원합니다.
  • 오토튜닝 참조 클럭: 오토튜닝을 사용하려면 OSC32K 또는 XOSC32K가 활성화되어 있어야 하며, XOSC32K가 더 높은 정확도를 제공합니다.
  • 디버깅: CLKOUT(PA7 핀)을 사용하여 클럭 주파수를 오실로스코프로 확인하세요. 오토튜닝 활성화/비활성화 시 주파수 차이를 비교할 수 있습니다.

4. MPLAB Code Configurator (MCC) 활용

MCC를 사용하면 클럭 설정을 간편하게 구성할 수 있습니다:

  1. MPLAB X IDE에서 MCC 실행 (Tools > Embedded > MPLAB Code Configurator).
  2. 디바이스로 AVR128DB48 선택.
  3. System > Clock Control에서 클럭 소스와 프리스케일러 설정. 오토튜닝은 OSCHF 설정에서 활성화 가능.
  4. Generate 클릭하여 코드 생성.

5. 참고 자료

키워드 : AVR128DB48, AVR, 마이크로컨트롤러, Atmel Studio, MPLAB X IDE, System clock,클럭설정

반응형