본문 바로가기
MCU/AVR

AVR128DB48 ZCD 사용 방법 및 예제 코드

by linuxgo 2025. 8. 20.

1. AVR128DB48 ZCD 모듈 개요

Microchip의 AVR128DB48은 AVR DB 시리즈의 8비트 마이크로컨트롤러로, ZCD(Zero-Cross Detection) 모듈을 통해 AC 신호의 영점 교차를 감지하여 전원 주파수 동기화, 디밍 제어, 또는 전력 관리 애플리케이션에 적합합니다. ZCD 모듈은 AC 신호의 전압이 0V 근처를 통과할 때 이벤트를 감지하며, 인터럽트 또는 출력 신호를 통해 이를 처리할 수 있습니다. 이 문서에서는 AVR128DB48의 ZCD 설정 방법, Bitfield 구조를 활용한 레지스터 설정, 그리고 실용적인 예제 코드를 제공하여 초보자와 숙련된 개발자 모두 쉽게 활용할 수 있도록 돕습니다.

AVR128DB48 ZCD

주요 사양

  • ZCD 모듈 수 : 2개 (ZCD0, ZCD1)
  • : PA7(ZCD0), PC7(ZCD1)
  • 기능 :
    • 영점 교차 감지 (상승/하강 에지)
    • 인터럽트 지원
    • 출력 신호 생성 (외부 핀 또는 내부 이벤트 시스템 연결)
    • 입력 필터링 (노이즈 제거)
  • 클럭 소스 : 시스템 클럭 (최대 24MHz, OSCHF 내부 오실레이터)
  • 인터럽트 : ZCDx_INT (x=0~1)
  • 주요 레지스터 :
    • CDx.CTRLA: ZCD 제어 레지스터
    • A ZCDx.INTCTRL: 인터럽트 제어 레지스터
    • ZCDx.STATUS: 상태 레지스터
  • 전력 관리 : 저전력 모드에서 ZCD 동작 지원
  • 전압 레벨 : 1.8V~5.5V 동작 지원

2. ZCD Bitfield 설정 상세

2.1 ZCDx.CTRLA (제어 레지스터 A, Offset: 0x00, Reset: 0x00)

  • bit 7 - RUNSTDBY: 스탠바이 모드에서 ZCD 동작 (1: 활성화, 0: 비활성화)
  • bit 6 - OUTEN: 출력 핀 활성화 (1: ZCD 출력이 핀(PA7/PC7)에 나타남, 0: 비활성화)
  • bit 3 - INVERT: 출력 반전 (1: 반전, 0: 정상)
  • bit 0 - ENABLE: ZCD 활성화 (1: 활성화, 0: 비활성화)

2.2 ZCDx.INTCTRL (인터럽트 제어 레지스터, Offset: 0x02, Reset: 0x00)

  • bits 1:0 - INTMODE: 인터럽트 모드
    • 00: 비활성화
    • 01: 상승 에지
    • 10: 하강 에지
    • 11: 둘 다

2.3 ZCDx.STATUS (상태 레지스터, Offset: 0x03, Reset: 0x00)

  • bit 4 - STATE: 현재 ZCD 출력 상태 (1: High, 0: Low; 3사이클 지연 포함)
  • bit 0 - CROSSIF: 영점 교차 감지 플래그 (1: 감지됨, 쓰기 1로 클리어)

2.4 PORTMUX.ZCDROUTEA (ZCD 출력 라우팅 레지스터, Offset: 0x0A, Reset: 0x00)

  • bit 2 - ZCD2: ZCD2 출력 위치 (0: 기본 PA7, 1: 대체 PC7)
  • bit 1 - ZCD1: ZCD1 출력 위치 (0: 기본 PA7, 1: 대체 PC7)
  • bit 0 - ZCD0: ZCD0 출력 위치 (0: 기본 PA7, 1: 대체 PC7)

3. ZCD 설정 절차

  1. 시스템 초기화:
    •   set_system_clock()으로 시스템 클럭 설정 (최대 24MHz, XOSC32K 오토튜닝 가능).
    •   글로벌 인터럽트 비활성화 (cli()).
  2. ZCD 모듈 활성화:
    •   ZCDx.CTRLAENABLE 비트를 설정하여 ZCD 활성화.
    •   필요 시 PORTMUX.ZCDROUTEA로 출력 핀 선택 (예: ZCD0을 PC7로 라우팅).
  3. 출력 설정:
    •   ZCDx.CTRLAOUTEN으로 출력 핀 활성화 (필요 시).
    •   입력 필터링은 명시적 레지스터 비트 없음; 외부 회로(직렬 저항 R_SERIES)로 노이즈 완화.
  4. 인터럽트 설정 (필요 시):
    •   ZCDx.INTCTRLINTMODE로 인터럽트 모드 설정 (상승/하강/둘 다).
    •   글로벌 인터럽트 활성화 (sei()).
  5. ZCD 실행:
    •   설정 완료 후 ZCD 즉시 동작 (별도 활성화 불필요).

4. ZCD 설정 고려사항

  • 입력 신호: ZCD 핀(PA7, PC7)에 AC 신호 입력. 최대 입력 전압은 VDD(1.8V~5.5V) 준수.
  • 필터링: 명시적 FILTEN 비트 없음. 노이즈가 많은 환경에서는 외부 직렬 저항(R_SERIES)과 커패시터로 필터링 권장 (데이터시트 Equation 36-1 참조).
  • 인터럽트: 다중 ZCD 인터럽트 사용 시 우선순위 주의 (CPUINT.LVL1VEC 설정).
  • 출력 핀: OUTEN 활성화 시 ZCD 출력이 선택된 핀에 나타남. PORTMUX.ZCDROUTEA로 라우팅.
  • 멀티플렉싱: ZCD 핀은 GPIO 또는 다른 주변 장치와 충돌 가능성 있음. 핀 설정 확인.
  • 저전력: RUNSTDBY로 스탠바이 모드에서 ZCD 동작 가능.
  • 외부 회로: 직렬 저항(R_SERIES)으로 전류 제한 및 ESD 보호, 노이즈 완화를 위한 병렬 커패시터 권장.
  • AVR128DB48의 ZCD 레지스터는 Bitfield 구조로 정의되어 있으며, <avr/io.h> 헤더 파일을 통해 접근합니다. 주요 레지스터는 다음과 같습니다:

5. 실용적인 ZCD 예제 코드 (Bitfield 구조)

아래는 AVR128DB48 ZCD를 Bitfield 구조로 설정한 3개의 예제 코드입니다. 각 예제는 Atmel Studio 또는 MPLAB X IDE와 AVR-GCC 환경에서 실행 가능합니다.

5.1 예제 1: 기본 ZCD 출력 (LED 표시)

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

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


void set_system_clock(void) {
    // 32kHz 외부 오실레이터 활성화 및 스탠바이 설정
    _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, CLKCTRL_ENABLE_bm | CLKCTRL_RUNSTDBY_bm);
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm)) {
        ; // 오실레이터 안정화 대기
    }
    // 내부 24MHz 오실레이터 설정 및 오토튜닝 활성화
    _PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, CLKCTRL_FRQSEL_24M_gc | CLKCTRL_AUTOTUNE_bm);
    // 메인 클럭을 OSCHF로 설정
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSCHF_gc);
    // 클럭 분주 비활성화 (1:1)
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, 0x00);
}

void zcd_init(void) {
    // ZCD0(PA7) 설정
    PORTMUX.ZCDROUTEA = 0x00;  // ZCD0 출력 기본 핀 PA7 사용
    ZCD0.CTRLA = ZCD_ENABLE_bm | ZCD_OUTEN_bm | ZCD_RUNSTDBY_bm; // ZCD0 활성화, 출력 활성화, 스탠바이 모드 동작
    PORTB.DIRSET = PIN3_bm;    // PB3(LED0)를 출력으로 설정
}

int main(void) {
    set_system_clock(); // 시스템 클록 설정
    zcd_init();        // ZCD 초기화

    while (1) {
        if (ZCD0.STATUS & ZCD_CROSSIF_bm) {  // 영점 교차 감지
            PORTB.OUTTGL = PIN3_bm;          // PB3 LED 토글
            ZCD0.STATUS = ZCD_CROSSIF_bm;    // 영점 교차 플래그 클리어
            _delay_ms(10);                   // 안정적인 동작을 위한 대기
        }
    }

    return 0;
}

설명 :

  • 기능 : ZCD0(PA7)에서 영점 교차 감지 시 PB3 LED를 토글
  • 설정 : ZCD0 활성화, 출력 핀(PA7) 및 필터 활성화, PB3 출력
  • 출력 : AC 신호의 영점 교차마다 LED 점멸

5.2 예제 2: ZCD 인터럽트 (LED 토글)


#define F_CPU 24000000UL  // 시스템 클록 주파수를 24 MHz로 정의
#include <avr/io.h>        // AVR 입출력 관련 헤더 파일
#include <avr/interrupt.h> // 인터럽트 처리 관련 헤더 파일


volatile uint8_t led_state = 0; // LED 상태 저장 (0: 꺼짐, 1: 켜짐)

void set_system_clock(void) {
    // 32kHz 외부 오실레이터 활성화 및 스탠바이 설정
    _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, CLKCTRL_ENABLE_bm | CLKCTRL_RUNSTDBY_bm);
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm)) {
        ; // 오실레이터 안정화 대기
    }
    // 내부 24MHz 오실레이터 설정 및 오토튜닝 활성화
    _PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, CLKCTRL_FRQSEL_24M_gc | CLKCTRL_AUTOTUNE_bm);
    // 메인 클럭을 OSCHF로 설정
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSCHF_gc);
    // 클럭 분주 비활성화 (1:1)
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, 0x00);
}

void zcd_init(void) {
    // ZCD0(PA7) 설정
    PORTMUX.ZCDROUTEA = 0x00;  // ZCD0 출력 기본 핀 PA7 사용
    ZCD0.CTRLA = ZCD_ENABLE_bm | ZCD_OUTEN_bm | ZCD_RUNSTDBY_bm; // ZCD0 활성화, 출력 활성화, 스탠바이 모드 동작
    ZCD0.INTCTRL = ZCD_INTMODE_BOTH_gc; // 양 에지 인터럽트 설정
    PORTB.DIRSET = PIN3_bm;             // PB3(LED0)를 출력으로 설정
}

ISR(ZCD0_ZCD_vect) {
    if (ZCD0.STATUS & ZCD_CROSSIF_bm) {
        led_state ^= 1;                  // LED 상태 토글
        if (led_state) {
            PORTB.OUTSET = PIN3_bm;      // PB3 High (LED 켬)
        } else {
            PORTB.OUTCLR = PIN3_bm;      // PB3 Low (LED 끔)
        }
        ZCD0.STATUS = ZCD_CROSSIF_bm;    // 영점 교차 플래그 클리어
    }
}

int main(void) {
    set_system_clock(); // 시스템 클록 설정
    zcd_init();        // ZCD 초기화

    sei(); // 글로벌 인터럽트 활성화

    while (1) {
        // 무한 루프: 인터럽트로 LED 제어
    }

    return 0;
}

설명 :

  • 기능 : ZCD0(PA7)의 영점 교차 시 인터럽트로 PB3 LED 토글
  • 설정 : ZCD0 활성화, 인터럽트 및 필터 활성화, PB3 출력
  • 출력 : AC 신호의 영점 교차마다 LED 상태 토글

5.3 예제 3: 다중 ZCD 출력 (LED 패턴)

#define F_CPU 24000000UL  // 시스템 클록 주파수를 24 MHz로 정의
#include <avr/io.h>        // AVR 입출력 관련 헤더 파일
#include <util/delay.h>    // 지연 함수 관련 헤더 파일


void set_system_clock(void) {
    // 32kHz 외부 오실레이터 활성화 및 스탠바이 설정
    _PROTECTED_WRITE(CLKCTRL.XOSC32KCTRLA, CLKCTRL_ENABLE_bm | CLKCTRL_RUNSTDBY_bm);
    while (!(CLKCTRL.MCLKSTATUS & CLKCTRL_XOSC32KS_bm)) {
        ; // 오실레이터 안정화 대기
    }
    // 내부 24MHz 오실레이터 설정 및 오토튜닝 활성화
    _PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, CLKCTRL_FRQSEL_24M_gc | CLKCTRL_AUTOTUNE_bm);
    // 메인 클럭을 OSCHF로 설정
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSCHF_gc);
    // 클럭 분주 비활성화 (1:1)
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, 0x00);
}

void zcd_init(void) {
    // ZCD0(PA7) 및 ZCD1(PC7) 설정
    PORTMUX.ZCDROUTEA = (0 << ZCD0_bp) | (1 << ZCD1_bp); // ZCD0: PA7(기본), ZCD1: PC7(대체)
    ZCD0.CTRLA = ZCD_ENABLE_bm | ZCD_OUTEN_bm | ZCD_RUNSTDBY_bm; // ZCD0 활성화, 출력 활성화, 스탠바이 모드
    ZCD1.CTRLA = ZCD_ENABLE_bm | ZCD_OUTEN_bm | ZCD_RUNSTDBY_bm; // ZCD1 활성화, 출력 활성화, 스탠바이 모드
    PORTA.DIRSET = PIN0_bm | PIN1_bm; // PA0, PA1를 출력으로 설정 (LED 연결)
}

int main(void) {
    set_system_clock(); // 시스템 클록 설정
    zcd_init();        // ZCD 초기화

    while (1) {
        if (ZCD0.STATUS & ZCD_CROSSIF_bm) {  // ZCD0 영점 교차 감지
            PORTA.OUTSET = PIN0_bm;          // PA0 LED 켬
            PORTA.OUTCLR = PIN1_bm;          // PA1 LED 끔
            ZCD0.STATUS = ZCD_CROSSIF_bm;    // 영점 교차 플래그 클리어
        }
        if (ZCD1.STATUS & ZCD_CROSSIF_bm) {  // ZCD1 영점 교차 감지
            PORTA.OUTSET = PIN1_bm;          // PA1 LED 켬
            PORTA.OUTCLR = PIN0_bm;          // PA0 LED 끔
            ZCD1.STATUS = ZCD_CROSSIF_bm;    // 영점 교차 플래그 클리어
        }
        _delay_ms(10); // 안정적인 동작을 위한 대기
    }

    return 0;
}

설명 :

  • 기능 : ZCD0(PA7)와 ZCD1(PC7)의 영점 교차 감지에 따라 PA0, PA1 LED 패턴 제어
  • 설정 : ZCD0, ZCD1 활성화, 필터 활성화, PA0/PA1 출력
  • 출력 : ZCD0 감지 시 PA0 ON/PA1 OFF, ZCD1 감지 시 PA1 ON/PA0 OFF

6. 사용 방법

6.1 환경 설정

  • AVR-GCC 설치: Microchip Studio(구 Atmel Studio) 또는 MPLAB X IDE에 AVR-GCC 툴체인 설치. 최신 툴체인 다운로드: Microchip 웹사이트 또는 MPLAB X IDE.
  • 헤더 파일: <avr/io.h>(레지스터 정의), <avr/interrupt.h>(인터럽트 처리), <util/delay.h>(지연 함수) 포함.
  • 프로젝트 설정: Microchip Studio 또는 MPLAB X IDE에서 AVR128DB48을 타겟으로 프로젝트 생성. 디바이스 설정에서 AVR128DB48 선택 확인.
  • 클럭 정의: #define F_CPU 24000000UL로 시스템 클록을 24 MHz로 설정. 코드 내 set_system_clock() 함수와 일치시켜야 함.

6.2 코드 실행

  • 파일 저장: 각 예제(zcd_interrupt.c, zcd_basic_output.c, zcd_multi.c)를 별도의 .c 파일로 저장하거나, main.c에 복사.
  • 단일 예제 실행: 다른 예제 코드를 주석 처리해 중복 컴파일 방지.
  • 빌드 및 플래싱: Microchip Studio 또는 MPLAB X IDE에서 프로젝트 빌드. AVR128DB48 Curiosity Nano 보드 또는 프로그래머(예: Atmel-ICE)를 사용해 플래싱.

6.3 하드웨어 준비

  • ZCD 입력:
  • ZCD0: 기본 PA7, 대체 PC7 (PORTMUX.ZCDROUTEA bit 0 설정).
  • ZCD1: 기본 PA7, 대체 PC7 (PORTMUX.ZCDROUTEA bit 1 설정).
  • ZCD2: 48핀 이상 디바이스에서 지원, 기본 PA7, 대체 PC7 (PORTMUX.ZCDROUTEA bit 2 설정).
  • AC 신호 입력: 50Hz/60Hz AC 신호, 최대 전압 VDD(1.8V~5.5V) 준수. 데이터시트 Equation 36-1에 따라 직렬 저항(R_SERIES, 예: 1kΩ) 사용.
    • LED 출력: PB3, PA0, PA1에 LED 연결, 전류 제한 저항(예: 330Ω) 필수.
    • 전원: 1.8V~5.5V 전원 공급, 안정적인 전원 회로 사용.
    • 안전: AC 신호 입력 시 절연 회로 필수. 예: 옵토커플러(예: PC817) 또는 소형 변압기(1:1, 10mA 이하) 사용. 데이터시트 Section 36.3.2 참조.

6.4 디버깅

  • 디버깅 도구: Microchip Studio 또는 MPLAB X IDE의 내장 디버거 사용(Atmel-ICE 또는 MPLAB Snap 지원).
  • ZCDx.STATUS 확인:
    • CROSSIF (bit 0): 영점 교차 감지 플래그, 1일 때 쓰기로 클리어.
    • STATE (bit 4): 현재 ZCD 출력 상태(1: High, 0: Low, 3사이클 지연 포함).
  • 신호 점검: 오실로스코프 또는 로직 분석기로 ZCD 입력 핀(PA7, PC7) 및 출력 핀(PB3, PA0, PA1)의 신호 확인.
  • ZCD 출력 설정: ZCD_OUTEN_bm이 활성화된 경우, ZCD 출력 신호를 해당 핀에서 직접 확인 가능.
  • 외부 회로 점검: 직렬 저항(R_SERIES) 및 커패시터의 값이 적절한지 확인(데이터시트 Equation 36-1 참조).
  • 인터럽트 디버깅: 인터럽트 기반 코드의 경우, ISR 실행 여부를 디버거로 확인.

7. 결론

이 문서는 AVR128DB48 ZCD 모듈의 설정 방법과 Bitfield 구조를 활용한 예제 코드를 제공하여 AC 신호의 영점 교차 감지 애플리케이션에 적용 가능하도록 구성했습니다. 초보자는 기본 ZCD 출력 예제부터 시작하고, 숙련자는 인터럽트 및 다중 ZCD를 활용하여 복잡한 시스템을 구현할 수 있습니다.

키워드 : AVR128DB48, ZCD, Zero-Cross Detection, AVR, 마이크로컨트롤러, Atmel Studio, MPLAB X IDE, AC 신호, 인터럽트, 입력 필터, LED 제어