카테고리 없음

전압전류체커기 3자리 프로그래밍AI

arirangled 2025. 6. 29. 14:58

아래는 구글제미나이로 한 것이다. 역시 뤼튼 보다는 제미나이 👍

MPLAB 환경에서 Atmel MCU (AVR)를 사용하여 3자리 FND에 전압과 전류를 표시하는 C 언어 프로그램을 작성하는 방법을 설명해 드리겠습니다.

준비물:
* MPLAB X IDE: Atmel Studio 대신 MPLAB X IDE를 사용하신다고 하셨으므로, MPLAB X IDE와 필요한 컴파일러 (XC8 등)가 설치되어 있어야 합니다.

* Atmel AVR 마이크로컨트롤러: 예시에서는 ATmega328P를 가정하겠습니다. (다른 AVR MCU를 사용하신다면 데이터시트를 참조하여 핀 설정 등을 조정해야 합니다.)
* 3자리 공통 애노드 또는 공통 캐소드 FND: 어떤 방식인지에 따라 코드의 세그먼트 데이터와 자리수 제어 방식이 달라집니다. 여기서는 공통 애노드(Common Anode)를 기준으로 설명하겠습니다.
* ADC (Analog-to-Digital Converter) 기능: 전압/전류 측정을 위해 MCU의 ADC 기능을 사용합니다.
* 전압/전류 센서 모듈: 전압과 전류를 아날로그 신호로 출력하는 센서 모듈이 필요합니다. (예: ACS712 전류 센서, 전압 분배 회로 등)
* 저항 및 배선: FND 세그먼트 전류 제한 저항, 센서 연결 저항 등.
* 브레드보드 및 점퍼선: 회로 구성용.
프로그래밍 개요:
* MCU 초기화:
   * 클럭 설정
   * I/O 핀 설정 (FND 제어 핀, ADC 입력 핀)
   * ADC 초기화
   * 타이머/인터럽트 초기화 (FND Multiplexing용)
* FND 제어:
   * 세그먼트 데이터 정의 (0~9, 소수점 등)
   * 자리수 제어 (Common Anode/Cathode)
   * Multiplexing 기법을 사용하여 3자리 FND 표시
* ADC를 이용한 전압/전류 측정:
   * 지정된 ADC 채널에서 아날로그 값 읽기
   * 읽은 아날로그 값을 실제 전압/전류 값으로 변환 (스케일링)
* 표시 로직:
   * 측정된 전압과 전류 값을 정수로 분리 (백의 자리, 십의 자리, 일의 자리)
   * 분리된 값을 FND에 표시
하드웨어 연결 (예시: ATmega328P, 공통 애노드 FND)
| ATmega328P 핀 | FND 핀 (예시) | 설명 |
|---|---|---|
| PB0 (D8) | Segment A | FND 세그먼트 제어 |
| PB1 (D9) | Segment B |  |
| PB2 (D10) | Segment C |  |
| PB3 (D11) | Segment D |  |
| PB4 (D12) | Segment E |  |
| PB5 (D13) | Segment F |  |
| PC0 (A0) | Segment G |  |
| PD2 (D2) | Segment DP | 소수점 |
| PD3 (D3) | Digit 1 (COM) | FND 첫째 자리 공통 핀 (PNP TR을 통해 제어) |
| PD4 (D4) | Digit 2 (COM) | FND 둘째 자리 공통 핀 |
| PD5 (D5) | Digit 3 (COM) | FND 셋째 자리 공통 핀 |
| PC1 (A1) | Voltage Sensor Output | 전압 센서 아날로그 출력 연결 |
| PC2 (A2) | Current Sensor Output | 전류 센서 아날로그 출력 연결 |
주의: FND의 각 세그먼트에는 적절한 전류 제한 저항(보통 220옴 ~ 1K옴)을 직렬로 연결해야 합니다. 자리수 제어 핀(공통 핀)에는 트랜지스터(PNP for Common Anode, NPN for Common Cathode)를 사용하여 MCU의 전류 한계를 넘지 않도록 해야 합니다.
C 언어 코드 (예시 - ATmega328P, MPLAB X IDE, XC8 Compiler)
#include <xc.h> // MPLAB XC8 헤더 파일
#include <avr/io.h> // AVR I/O 헤더 파일
#include <util/delay.h> // 딜레이 함수
#include <avr/interrupt.h> // 인터럽트 헤더 파일

// CPU 클럭 주파수 정의 (MPLAB 프로젝트 설정과 일치해야 함)
#ifndef F_CPU
#define F_CPU 16000000UL // 16MHz
#endif

// FND 세그먼트 핀 정의 (PORTB와 PORTC의 일부 사용)
// 공통 애노드 (Common Anode) 기준
#define FND_SEGMENT_PORT_A PORTB
#define FND_SEGMENT_PORT_B PORTB
#define FND_SEGMENT_PORT_C PORTB
#define FND_SEGMENT_PORT_D PORTB
#define FND_SEGMENT_PORT_E PORTB
#define FND_SEGMENT_PORT_F PORTB
#define FND_SEGMENT_PORT_G PORTC // 예시: PC0를 G로 사용
#define FND_SEGMENT_PORT_DP PORTD // 예시: PD2를 DP로 사용

#define SEG_A (1 << PB0)
#define SEG_B (1 << PB1)
#define SEG_C (1 << PB2)
#define SEG_D (1 << PB3)
#define SEG_E (1 << PB4)
#define SEG_F (1 << PB5)
#define SEG_G (1 << PC0)
#define SEG_DP (1 << PD2)

// FND 자리수 제어 핀 정의 (PORTD 사용)
#define FND_DIGIT_PORT PORTD
#define DIGIT1 (1 << PD3) // 백의 자리 (TR 제어)
#define DIGIT2 (1 << PD4) // 십의 자리 (TR 제어)
#define DIGIT3 (1 << PD5) // 일의 자리 (TR 제어)

// ADC 채널 정의
#define VOLT_ADC_CHANNEL 1 // PC1 (ADC1)
#define CURR_ADC_CHANNEL 2 // PC2 (ADC2)

// FND 세그먼트 패턴 (공통 애노드: 핀 Low일 때 켜짐)
//          A  B  C  D  E  F  G  DP
const uint8_t FND_SEGMENTS[] = {
    ~(SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F),      // 0
    ~(SEG_B | SEG_C),                                      // 1
    ~(SEG_A | SEG_B | SEG_D | SEG_E | SEG_G),              // 2
    ~(SEG_A | SEG_B | SEG_C | SEG_D | SEG_G),              // 3
    ~(SEG_B | SEG_C | SEG_F | SEG_G),                      // 4
    ~(SEG_A | SEG_C | SEG_D | SEG_F | SEG_G),              // 5
    ~(SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G),      // 6
    ~(SEG_A | SEG_B | SEG_C),                              // 7
    ~(SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G), // 8
    ~(SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G),      // 9
    ~(SEG_G)                                               // - (마이너스 부호 등)
};

volatile uint16_t voltage_adc_value = 0;
volatile uint16_t current_adc_value = 0;

volatile int16_t display_value_int = 0; // FND에 표시할 정수 값 (예: 12.3V -> 123)
volatile uint8_t display_digit_index = 0; // 현재 표시할 FND 자리수 인덱스

// 함수 프로토타입
void system_init(void);
void fnd_init(void);
void adc_init(void);
uint16_t read_adc(uint8_t channel);
void display_fnd(uint16_t value, uint8_t decimal_pos); // value: 표시할 값 (예: 123), decimal_pos: 소수점 위치 (0: 없음, 1: 십의 자리 뒤, 2: 백의 자리 뒤)
void set_fnd_segments(uint8_t segment_pattern);
void select_fnd_digit(uint8_t digit_index);

// 타이머 인터럽트 서비스 루틴 (FND Multiplexing)
ISR(TIMER0_COMPA_vect) {
    // 이전 자리수 끄기
    FND_DIGIT_PORT |= (DIGIT1 | DIGIT2 | DIGIT3); // 모든 자리 OFF (공통 애노드이므로 HIGH)

    // 표시할 값의 각 자리수 분리
    uint8_t hundred = display_value_int / 100;
    uint8_t ten = (display_value_int % 100) / 10;
    uint8_t one = display_value_int % 10;

    // 현재 표시할 자리수에 따라 세그먼트 패턴 설정
    switch (display_digit_index) {
        case 0: // 백의 자리
            set_fnd_segments(FND_SEGMENTS[hundred]);
            select_fnd_digit(0); // 백의 자리 ON
            break;
        case 1: // 십의 자리 (소수점 포함 가능)
            set_fnd_segments(FND_SEGMENTS[ten] | SEG_DP); // 예시: 소수점 십의 자리 뒤
            select_fnd_digit(1); // 십의 자리 ON
            break;
        case 2: // 일의 자리
            set_fnd_segments(FND_SEGMENTS[one]);
            select_fnd_digit(2); // 일의 자리 ON
            break;
    }
    display_digit_index = (display_digit_index + 1) % 3; // 다음 자리수로 이동
}


int main(void) {
    system_init();
    fnd_init();
    adc_init();

    sei(); // 전역 인터럽트 활성화

    uint32_t raw_voltage_sum = 0;
    uint32_t raw_current_sum = 0;
    const uint8_t num_samples = 16; // ADC 샘플링 횟수 (평균치 계산용)

    while (1) {
        // 전압 측정
        raw_voltage_sum = 0;
        for (uint8_t i = 0; i < num_samples; i++) {
            raw_voltage_sum += read_adc(VOLT_ADC_CHANNEL);
            _delay_us(100); // 샘플링 간 딜레이
        }
        voltage_adc_value = raw_voltage_sum / num_samples;

        // 전류 측정
        raw_current_sum = 0;
        for (uint8_t i = 0; i < num_samples; i++) {
            raw_current_sum += read_adc(CURR_ADC_CHANNEL);
            _delay_us(100);
        }
        current_adc_value = raw_current_sum / num_samples;

        // ADC 값을 실제 전압/전류 값으로 변환 (스케일링)
        // 예시: 10비트 ADC (0~1023), 5V 레퍼런스, 전압 분배 회로 또는 센서 특성에 맞게 조정
        // 전압: (ADC_VALUE / 1024.0) * V_REF * 스케일링_팩터
        // 전류: (ADC_VALUE / 1024.0) * V_REF * 전류_센서_민감도 (mV/A) 에 따른 역계산
        
        // 예시 스케일링 (가정치, 실제 센서와 회로에 맞게 조정 필요)
        // 5V 기준, 전압 분배 회로로 1/10으로 전압을 낮춘 경우:
        // ADC_Value (0~1023) -> 0~5V (MCU 입력) -> 0~50V (실제 측정 전압)
        // 1023 -> 500 (50.0V)
        float voltage_float = (float)voltage_adc_value / 1023.0 * 5.0 * 10.0; // 0.1V 단위로 표시하기 위해 10을 곱함
        // 1023이 50.0V라면, 123은 6.0V 정도 (123 / 1023 * 50 = 6.01)
        // FND에 12.3V를 표시하려면 123으로 만들어서 넘겨야 함 (소수점은 display_fnd에서 처리)
        // 예를 들어 12.3V를 표시하고 싶다면, voltage_float을 123으로 변환
        display_value_int = (int)(voltage_float * 10); // 12.3V -> 123
        //display_fnd(display_value_int, 1); // 십의 자리 뒤에 소수점

        // 전류 스케일링 (예시: ACS712 20A 모듈, 100mV/A, VCC/2 = 2.5V가 0A)
        // 전류는 양방향이므로 ADC 값 512 (2.5V)가 0A
        // 1023 -> 5V, 512 -> 2.5V, 0 -> 0V
        // 센서 출력 전압 - 2.5V = 델타 전압
        // 델타 전압 / 민감도(0.1V/A) = 전류 (A)
        float current_float = ((float)current_adc_value / 1023.0 * 5.0 - 2.5) / 0.1; // ACS712 100mV/A (0.1V/A)
        display_value_int = (int)(current_float * 10); // 1.23A -> 123

        // 여기서는 간단하게 전압과 전류를 번갈아 표시합니다.
        // 실제로는 사용자 입력에 따라 전환하거나, 버튼으로 선택하도록 할 수 있습니다.
        // 예시로 전압을 2초 표시하고, 전류를 2초 표시
        
        display_value_int = (int)(voltage_float * 10); // 12.3V -> 123
        //display_fnd(display_value_int, 1); // 십의 자리 뒤에 소수점 (TIMER0_COMPA_vect에서 이미 처리)
        _delay_ms(2000); // 2초간 전압 표시

        display_value_int = (int)(current_float * 10); // 1.23A -> 123
        //display_fnd(display_value_int, 1); // 십의 자리 뒤에 소수점
        _delay_ms(2000); // 2초간 전류 표시
    }

    return 0;
}

// 시스템 초기화 함수
void system_init(void) {
    // 핀 방향 설정
    // FND 세그먼트 핀 출력 설정 (PB0-PB5, PC0, PD2)
    DDRB |= (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F);
    DDRC |= SEG_G; // PC0
    DDRD |= SEG_DP; // PD2

    // FND 자리수 제어 핀 출력 설정 (PD3, PD4, PD5)
    DDRD |= (DIGIT1 | DIGIT2 | DIGIT3);

    // 모든 FND 핀을 일단 OFF 상태로 (공통 애노드: HIGH)
    FND_SEGMENT_PORT_A |= (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F);
    FND_SEGMENT_PORT_G |= SEG_G;
    FND_SEGMENT_PORT_DP |= SEG_DP;
    FND_DIGIT_PORT |= (DIGIT1 | DIGIT2 | DIGIT3);

    // 타이머/카운터 0 설정 (FND Multiplexing용)
    // CTC 모드, 분주비 64
    TCCR0A |= (1 << WGM01); // CTC 모드
    TCCR0B |= (1 << CS01) | (1 << CS00); // 분주비 64
    OCR0A = (F_CPU / 64 / 1000) * 5; // 5ms 주기로 인터럽트 발생 (1000Hz = 1ms)
                                     // F_CPU / 분주비 / (주기당 카운트) = 주파수
                                     // F_CPU / 64 / OCR0A = 200Hz (5ms)
                                     // OCR0A = F_CPU / 64 / 200 = 16000000 / 64 / 200 = 1250
    TIMSK0 |= (1 << OCIE0A); // Output Compare Match A 인터럽트 활성화
}

// FND 초기화 (핀 방향 설정은 system_init에서 함)
void fnd_init(void) {
    // 초기화 시 모든 FND 끄기
    FND_SEGMENT_PORT_A |= (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F);
    FND_SEGMENT_PORT_G |= SEG_G;
    FND_SEGMENT_PORT_DP |= SEG_DP;
    FND_DIGIT_PORT |= (DIGIT1 | DIGIT2 | DIGIT3);
}

// ADC 초기화 함수
void adc_init(void) {
    // ADMUX: ADC 레퍼런스 및 채널 선택
    // REFS0: AVCC를 ADC 레퍼런스로 사용 (AREF 핀에 외부 커패시터 연결 권장)
    // ADLAR: ADC 결과 왼쪽 정렬 (일반적으로 사용하지 않음, ADCL을 먼저 읽고 ADCH 읽기)
    ADMUX = (1 << REFS0); // AVCC with external capacitor at AREF pin

    // ADCSRA: ADC 활성화, 분주비 설정, 인터럽트 설정
    // ADEN: ADC 활성화
    // ADPS2, ADPS1, ADPS0: ADC 클럭 분주비 (16MHz / 128 = 125kHz, ADC 권장 주파수 50kHz~200kHz)
    ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // ADC 활성화, 분주비 128
}

// ADC 값 읽기 함수
uint16_t read_adc(uint8_t channel) {
    // 채널 선택
    ADMUX = (ADMUX & 0xF0) | (channel & 0x0F); // 상위 4비트 유지하고 하위 4비트에 채널 설정

    // ADC 변환 시작
    ADCSRA |= (1 << ADSC);

    // 변환 완료 대기
    while (ADCSRA & (1 << ADSC));

    // ADC 결과 반환 (10비트)
    return ADC; // ADCL과 ADCH를 합쳐서 반환
}

// FND 세그먼트 패턴 설정 함수 (공통 애노드 기준)
void set_fnd_segments(uint8_t segment_pattern) {
    // 모든 세그먼트 핀을 초기화 (모두 OFF)
    FND_SEGMENT_PORT_A |= (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F);
    FND_SEGMENT_PORT_G |= SEG_G;
    FND_SEGMENT_PORT_DP |= SEG_DP;

    // 전달받은 패턴에 따라 세그먼트 켜기 (공통 애노드: 해당 비트가 0이면 켜짐)
    FND_SEGMENT_PORT_A &= ~(segment_pattern & (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F));
    FND_SEGMENT_PORT_G &= ~(segment_pattern & SEG_G);
    FND_SEGMENT_PORT_DP &= ~(segment_pattern & SEG_DP);
}

// FND 자리수 선택 함수 (공통 애노드 기준)
void select_fnd_digit(uint8_t digit_index) {
    // 모든 자리수 OFF (공통 애노드: HIGH)
    FND_DIGIT_PORT |= (DIGIT1 | DIGIT2 | DIGIT3);

    // 선택된 자리수 ON (공통 애노드: LOW)
    switch (digit_index) {
        case 0: // 백의 자리
            FND_DIGIT_PORT &= ~DIGIT1;
            break;
        case 1: // 십의 자리
            FND_DIGIT_PORT &= ~DIGIT2;
            break;
        case 2: // 일의 자리
            FND_DIGIT_PORT &= ~DIGIT3;
            break;
    }
}

코드 설명:
* #include <xc.h>, #include <avr/io.h>, #include <util/delay.h>, #include <avr/interrupt.h>: MPLAB XC8 컴파일러와 AVR 특유의 레지스터 정의, 딜레이 함수, 인터럽트 관련 기능을 사용하기 위한 헤더 파일입니다.
* F_CPU 정의: MCU의 클럭 주파수를 정의합니다. 프로젝트 설정과 일치해야 합니다.
* 핀 정의: FND 세그먼트와 자리수 제어 핀을 명확하게 정의했습니다. SEG_A, SEG_B 등은 비트마스크를 사용하여 해당 핀의 비트를 나타냅니다.
* FND_SEGMENTS 배열: 0부터 9까지의 숫자를 FND에 표시하기 위한 세그먼트 패턴을 정의합니다. 공통 애노드 방식이므로, 해당 세그먼트를 켜려면 해당 비트가 0이 되어야 합니다. (~ 연산자를 사용한 이유)
* voltage_adc_value, current_adc_value, display_value_int, display_digit_index: volatile 변수로 선언하여 인터럽트와 메인 루프 간의 데이터 공유 시 컴파일러 최적화 문제를 방지합니다.
* system_init():
   * FND 세그먼트 및 자리수 제어 핀을 출력으로 설정합니다.
   * 타이머/카운터 0을 CTC(Clear Timer on Compare Match) 모드로 설정하고, 분주비를 64로 설정합니다.
   * OCR0A 레지스터는 타이머가 도달할 값으로, 이 값을 통해 인터럽트 주기를 조절합니다. 여기서는 약 5ms 주기로 인터럽트가 발생하도록 설정했습니다.
   * TIMSK0 레지스터를 통해 OCIE0A 비트를 활성화하여 타이머 비교 매치 인터럽트를 활성화합니다.
* fnd_init(): FND 초기 상태를 설정합니다 (모든 FND를 끔).
* adc_init():
   * ADMUX 레지스터를 설정하여 ADC 레퍼런스 전압을 AVCC(MCU의 VCC)로 설정합니다.
   * ADCSRA 레지스터를 설정하여 ADC를 활성화하고, ADC 클럭 분주비를 128로 설정합니다. 이는 ADC가 안정적으로 작동하는 50kHz ~ 200kHz 범위 내에 있도록 합니다. (16MHz / 128 = 125kHz)
* read_adc(uint8_t channel):
   * ADMUX 레지스터의 하위 4비트를 조작하여 원하는 ADC 채널을 선택합니다.
   * ADCSRA의 ADSC 비트를 1로 설정하여 ADC 변환을 시작합니다.
   * ADSC 비트가 0이 될 때까지 while 루프를 통해 변환이 완료되기를 기다립니다.
   * 변환이 완료되면 ADC 레지스터(ADCL과 ADCH의 결합된 값)를 반환합니다.
* ISR(TIMER0_COMPA_vect):
   * 타이머 0의 비교 매치 A 인터럽트 서비스 루틴입니다. FND 멀티플렉싱을 담당합니다.
   * 매 인터럽트 발생 시마다 현재 표시되고 있는 FND 자리를 끄고, 다음 자리의 숫자를 계산하여 세그먼트 패턴을 설정한 뒤, 해당 자리를 켭니다.
   * display_digit_index를 0, 1, 2 순환하도록 하여 3자리 FND를 빠르게 번갈아 켜고 끄면서 동시에 켜져 있는 것처럼 보이게 합니다.
* set_fnd_segments(uint8_t segment_pattern): FND의 각 세그먼트 핀을 제어하여 원하는 숫자의 모양을 만듭니다. 공통 애노드이므로 비트가 0일 때 켜집니다.
* select_fnd_digit(uint8_t digit_index): FND의 특정 자리를 활성화합니다. 공통 애노드이므로 해당 자리의 공통 핀을 LOW로 만듭니다.
* main():
   * system_init(), fnd_init(), adc_init()를 호출하여 MCU 및 주변 장치를 초기화합니다.
   * sei()를 호출하여 전역 인터럽트를 활성화합니다.
   * while(1) 무한 루프 내에서 전압과 전류를 주기적으로 측정합니다.
   * read_adc() 함수를 호출하여 ADC 값을 읽습니다.
   * ADC 값 스케일링: 읽은 ADC 값을 실제 전압 또는 전류 값으로 변환하는 수식이 중요합니다.
     * voltage_float = (float)voltage_adc_value / 1023.0 * 5.0 * 10.0;
       * (float)voltage_adc_value / 1023.0은 0~1 사이의 정규화된 ADC 값입니다.
       * * 5.0은 ADC 레퍼런스 전압이 5V라고 가정했을 때 실제 MCU 입력 전압으로 변환합니다.
       * * 10.0은 외부 전압 분배 회로 등으로 실제 측정 대상의 전압을 MCU의 ADC 입력 범위로 낮추는 경우의 역 스케일링 팩터입니다. (예: 1/10로 낮췄다면 10을 곱함)
       * display_value_int = (int)(voltage_float * 10);은 FND에 소수점 한 자리까지 표시하기 위해 실제 전압 값에 10을 곱한 정수 값을 만듭니다. (예: 12.3V -> 123)
     * 전류 스케일링은 사용하는 전류 센서(예: ACS712)의 특성(민감도, 0A일 때 출력 전압)에 따라 수식을 조정해야 합니다.
   * 여기서는 간단하게 전압과 전류 값을 번갈아 가며 표시하도록 했습니다. 실제 애플리케이션에서는 버튼 입력 등을 통해 표시할 값을 선택하게 할 수 있습니다.
MPLAB X IDE 프로젝트 설정:
* 새 프로젝트 생성: File -> New Project...
* 프로젝트 타입 선택: Stand-alone Project
* 디바이스 선택: ATmega328P (또는 사용하는 Atmel AVR MCU)
* 툴 선택: 연결된 디버거/프로그래머 (예: PICkit 4, Atmel-ICE 등) 또는 시뮬레이터.
* 컴파일러 선택: XC8 (vX.XX)
* 프로젝트 이름 및 위치 지정
* 클럭 설정 (Configuration Bits):
   * Project Properties -> Conf: [default] -> Configuration bits
   * Fuses 섹션에서 클럭 소스를 설정합니다.
     * CKSEL Fuses를 Ext. Crystal Osc.; frequency 8.0- MHz; Start-up time: 16K CK + 64 ms 와 같이 외부 크리스탈 오실레이터에 맞게 설정해야 합니다. (16MHz 크리스탈 사용 시)
     * CKDIV8 퓨즈가 활성화되어 있으면 내부적으로 클럭이 8분주되므로, 이를 비활성화(체크 해제)해야 합니다.
   * 설정 후 Generate Source Code to Output 버튼을 눌러 생성된 코드를 복사하여 프로젝트 소스 파일(main.c 등)에 붙여넣습니다. (또는 IDE가 자동으로 처리하도록 할 수 있습니다.)
회로 구성 시 유의사항:
* FND 저항: 각 세그먼트에는 반드시 적절한 전류 제한 저항을 직렬로 연결해야 합니다. (LED 개별 사용과 동일)
* 자리수 제어 트랜지스터: MCU의 출력 전류는 제한적이므로, FND의 공통 핀을 직접 제어하기보다는 트랜지스터(PNP 또는 NPN)를 사용하여 FND에 충분한 전류를 공급해야 합니다.
   * 공통 애노드 FND: PNP 트랜지스터를 사용하고, MCU 핀을 LOW로 만들면 트랜지스터가 ON되어 FND가 켜집니다.
   * 공통 캐소드 FND: NPN 트랜지스터를 사용하고, MCU 핀을 HIGH로 만들면 트랜지스터가 ON되어 FND가 켜집니다.
* ADC 입력 보호: ADC 입력 핀에는 과전압이 인가되지 않도록 주의해야 합니다. 필요한 경우 전압 분배 회로를 사용하여 입력 전압을 MCU의 ADC 허용 범위(보통 VCC 이하)로 낮춰야 합니다.
* 센서 선택: 사용하려는 전압 및 전류 측정 범위에 맞는 센서 모듈을 선택해야 합니다.
   * 전압: 저항 분배 회로 또는 전압 센서 모듈 (예: LM358 기반)
   * 전류: 홀 효과 전류 센서 (예: ACS712, ACS724 등)
이 코드는 기본적인 틀을 제공하며, 실제 하드웨어 구성과 사용하는 센서의 특성에 맞게 ADC 스케일링 부분과 핀 정의 등을 반드시 수정해야 합니다. 질문이 더 있으시면 언제든지 물어보세요.

반응형