질문게시판 > 모터제어 중 RPM 계산 질문입니다.

TODAY16,520 TOTAL5,246,018
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | 질문게시판 | 모터제어 중 RPM 계산 질문입니다.

페이지 정보

작성자 suuuuuuuh 작성일2024-10-24 22:43 조회55회 댓글3건

본문

	

BLDC 모터를 제어하고 있습니다.

윤덕용 박사님의 BLDC 모터제어 기술에 나오는 코드를 활용하여(회로를 다르게 구성하였습니다.)

모터드라이버 IC 없이 MCU가 직접 제어하는 방식으로, ATMEGA128A를 사용하고 있습니다.

 

모터는 BL4252-4262를 사용하고 있으며

 

정/역방향 회전, PWM 제어로 Duty UP/DOWN 에 따라 모터는 잘 회전하고 이 상태를 LCD로 잘 표현하고 있으나,

RPM 계산이 잘 되지 않는 상황입니다. (엔코더는 없습니다..) LCD에는 계속 RPM 0000 만 나타나는 상황입니다.

 

먼저 3개의 홀센서의 엣지변화(상승/하강모두)를 카운트하고, 해당 카운트가 6가 될때 걸린 시간을 타이머카운트2로 계산하여 RPM을 구하려고 하고..

  

타이머카운터2가 동작을 제대로 안하는 것 같은데 이유를 잘 모르겠습니다 ㅠㅠ 

머리를 싸매고 몇주 고민하다가 .. 질문 올려봅니다 

도움주시면 정말 감사합니다...

 

그리고 혹시, 간혹가다 START 버튼을 누른 이후에 모터가 바로 회전하지않고 모터 축을 살짝 손으로 돌려준 이후에서야 돌기시작하는 경우가 있는데, 이것도 혹시 원인이 무엇인지 알 수 있을까요 ??

 

코드는 다음과 같습니다

 

//*********************************************

#include <mega128.h>

#include <stdio.h>

#include <delay.h>

#include <interrupt.h>

#include "mydef_ver3.h"      

#include "lcd.h"

#include <stdlib.h> 

#include <string.h>

#define F_CPU 16000000UL

//*************************************************  

u08 sec;

u08 time_count;

u08 count;

bit motor_running = 0; 

 

void LCD_control(u08 a);

void motor_rotate(void);

 

volatile unsigned char m1 = 0;

volatile unsigned char pulse=0;

volatile unsigned char pulse0 =0; //pulse count

volatile u16 timer_count = 0;   // TIMER2 count

volatile u16 rpm = 0;       //motor speed

volatile u16 edge_count = 0;

volatile u08 timer_overflows = 0;

 

volatile unsigned char TCCR1A_temp, PORTB_temp, PORTD_temp;  // I/O register store data

volatile unsigned char Hall_data = 0;                         // Hall sensor signal data

volatile unsigned char Hall_previous = 0;                    // 이전 Hall 센서 값

volatile unsigned char direction = '+';                       // motor direction command 

volatile bit update_lcd_flag = 0;  // LCD 업데이트 플래그

volatile bit hall_event_flag = 0;  // Hall 센서 이벤트 플래그

u08 prev_count;

bit CW_pressed = 0;

 

// 모터의 상태를 주기적으로 확인하여 정지하였을때, C 충전하는 루틴   

interrupt [TIM3_COMPA] void timer3_compA_isr(void){     

      

      if(m1 == 0){                          // 모터가 정지상태라면

        rpm = 0;

        TCCR1A_temp = TCCR1A;

        PORTB_temp = PORTB;

        PORTD_temp = PORTD;

        

        TCCR1A = 0x02;                      // PWM 출력 X, 일반 I/O 포트로 사용하게끔

                                            // 부트스트랩 커패시터 충전

        PORTB &= ~(0b11100000);              // UB(PD1) = VB(PD2) = WB(PD3) = 1

        PORTD |= 0b00001110;                               

        delay_ms(10);                       // UT(PB5) = VT(PB6) = WT(PB7) = 0

        PORTD &= ~(0b00001110);

        

        TCCR1A = TCCR1A_temp;

        PORTB = PORTB_temp;

        PORTD = PORTD_temp;                

      }

         #asm("sei")

     

}

 

// HA 신호 외부 인터럽트 처리 루틴

interrupt [EXT_INT4] void Ext_int4_isr(void){     

    edge_count++;

    motor_rotate();

}

 

// HB 신호 외부 인터럽트 처리 루틴 

interrupt [EXT_INT5] void Ext_int5_isr(void){

    edge_count++;   

    motor_rotate();

}    

 

// HC 신호 외부 인터럽트 처리 루틴 

interrupt [EXT_INT6] void Ext_int6_isr(void){   

    edge_count++;

    motor_rotate();

}

 

// 타이머카운터2, 분주비 1024, CTC mode, 주기 1msec

 

interrupt [TIM2_COMP] void timer2_comp_isr(void) {

    // 펄스 수를 바탕으로 RPM 계산

    // 한 바퀴 회전당 6개의 펄스 발생 (상승/하강 엣지 고려)

    rpm = (edge_count * 10) / 6;  // 초당 펄스 수 * 10 -> 분당 회전 수로 환산

 

   edge_count = 0;  // 카운트 초기화

    

}

 

// 부저음 루틴

void beep(void){

  PORTG = PORTG | 0x08;  

  delay_ms(100);

  PORTG = PORTG & 0x07;       

}

 

// 모터 회전 6STEP 루틴

void motor_rotate(void){

    Hall_data = PINE & 0x70;

    if(direction == '+')    

      { if((Hall_data & 0x70) == 0b01010000)   

        { PORTD &= ~(0b00001110);  // 1, 2, 3번 비트를 0으로 만듦

          PORTD |=  (0b00000100);  // 2번 비트(VB)만 1로 설정

          PORTB &= ~(0b11100000);  // 상위 스위치 클리어

          TCCR1A = 0x82;           // OC1A 핀에서 PWM 출력 (WT)

        }

        else if((Hall_data & 0x70) == 0b00010000)  

        { PORTD &= ~(0b00001110);  // 1, 2, 3번 비트를 0으로 만듦

          PORTD |=  (0b00001000);  // 3번 비트(WB)만 1로 설정

          PORTB &= ~(0b11100000);  // 상위 스위치 클리어

          TCCR1A = 0x82;           // OC1A 핀에서 PWM 출력 (UT)

        }

        else if((Hall_data & 0x70) == 0b00110000)          // position angle = 120~180

        { PORTD &= ~(0b00001110);  // 1, 2, 3번 비트를 0으로 만듦

          PORTD |=  (0b00001000);  // 3번 비트(WB)만 1로 설정

          PORTB &= ~(0b11100000);  // 상위 스위치 클리어    

          TCCR1A = 0x22;           // OC1B 핀에서 PWM 출력 (VT)

        }

        else if((Hall_data & 0x70) == 0b00100000)  // position angle = 180~240

        { PORTD &= ~(0b00001110);  // 1, 2, 3번 비트를 0으로 만듦

          PORTD |=  (0b00000010);  // 1번 비트(UB)만 1로 설정

          PORTB &= ~(0b11100000);  // 상위 스위치 클리어

          TCCR1A = 0x22;           // OC1B 핀에서 PWM 출력 (VT)

        }

        else if((Hall_data & 0x70) == 0b01100000)  // position angle = 240~300

        { PORTD &= ~(0b00001110);  // 1, 2, 3번 비트를 0으로 만듦

          PORTD |=  (0b00000010);  // 1번 비트(UB)만 1로 설정

          PORTB &= ~(0b11100000);  // 상위 스위치 클리어

          TCCR1A = 0x0A;           // OC1C 핀에서 PWM 출력 (WT)

        }

        else if((Hall_data & 0x70) == 0b01000000)     // position angle = 300~360

       { PORTD &= ~(0b00001110);  // 1, 2, 3번 비트를 0으로 만듦

         PORTD |=  (0b00000100);  // 2번 비트(VB)만 1로 설정

         PORTB &= ~(0b11100000);  // 상위 스위치 클리어

         TCCR1A = 0x0A;           // OC1C 핀에서 PWM 출력 (WT)

       }

      }

      else

        { if((Hall_data & 0x70) == 0b00110000)  // position angle = 0~60

          { PORTD &= ~(0b00001110);  // 1, 2, 3번 비트를 0으로 만듦

            PORTD |=  (0b00000100);  // 2번 비트(VB)만 1로 설정

            PORTB &= ~(0b11100000);  // 상위 스위치 클리어

            TCCR1A = 0x0A;           // OC1C 핀에서 PWM 출력 (WT)

          }

          else if((Hall_data & 0x70) == 0b00010000)          // position angle = 60~120

          { PORTD &= ~(0b00001110);  // 1, 2, 3번 비트를 0으로 만듦

           PORTD |=  (0b00000010);  // 1번 비트(UB)만 1로 설정

           PORTB &= ~(0b11100000);  // 상위 스위치 클리어    

           TCCR1A = 0x0A;           // OC1C 핀에서 PWM 출력 (WT)

          }

          else if((Hall_data & 0x70) == 0b01010000)          // position angle = 120~180

          { PORTD &= ~(0b00001110);  // 1, 2, 3번 비트를 0으로 만듦

           PORTD |=  (0b00000010);  // 1번 비트(UB)만 1로 설정

           PORTB &= ~(0b11100000);  // 상위 스위치 클리어    

           TCCR1A = 0x22;           // OC1B 핀에서 PWM 출력 (VT)

          }

          else if((Hall_data & 0x70) == 0b01000000)  // position angle = 180~240

          { PORTD &= ~(0b00001110);  // 1, 2, 3번 비트를 0으로 만듦

           PORTD |=  (0b00001000);  // 3번 비트(WB)만 1로 설정

           PORTB &= ~(0b11100000);  // 상위 스위치 클리어

           TCCR1A = 0x22;           // OC1B 핀에서 PWM 출력 (VT)

          }

          else if((Hall_data & 0x70) == 0b01100000)     // position angle = 240~300

          { PORTD &= ~(0b00001110);  // 1, 2, 3번 비트를 0으로 만듦

            PORTD |=  (0b00001000);  // 3번 비트(WB)만 1로 설정

            PORTB &= ~(0b11100000);  // 상위 스위치 클리어

            TCCR1A = 0x82;           // OC1A 핀에서 PWM 출력 (UT)

          }

          else if((Hall_data & 0x70) == 0b00100000)     // position angle = 300~360

         { PORTD &= ~(0b00001110);  // 1, 2, 3번 비트를 0으로 만듦

           PORTD |=  (0b00000100);  // 2번 비트(VB)만 1로 설정

           PORTB &= ~(0b11100000);  // 상위 스위치 클리어

           TCCR1A = 0x82;           // OC1A 핀에서 PWM 출력 (UT)

         }

        }

}

 

// 모터 방향 변경 시 회전속도 서서히 줄어드는 루틴

void gradual_stop(void){

    while (count > 100){

        if (count > 90){

            count -= 20;  // count를 10씩 감소

        } else{

            count = 100;    //  이하로 내려가면 모터 정지

        }

        OCR1A = count;

        OCR1B = count;

        OCR1CL = count;

        LCD_control(count);

        delay_ms(900);  // 서서히 감소시키는 효과

    }

}

 

// 모터 방향 변경 시 회전속도 서서히 증가하는 루틴 

void gradual_start(u08 target_duty){

    while (count < target_duty){

        if (count + 20 <= target_duty){

            count += 20;  // count를 10씩 증가

        } else {

            count = target_duty;  // 목표 듀티 비율에 도달하면 멈춤

        }

        OCR1A = count;

        OCR1B = count;

        OCR1CL = count;

        LCD_control(count);

        delay_ms(900);  // 서서히 증가시키는 효과

    }

}

 

// 전류제어를 위해 ADC 루틴

#define ADC_VREF_TYPE 0x20              //AD0 INPUT

unsigned char read_adc(unsigned char adc_input)

{

    ADMUX = adc_input | (ADC_VREF_TYPE & 0xff);

    delay_us(10);

    ADCSRA |= 0x40;                      // START THE AD CONVERSION

    while((ADCSRA & 0x10)==0);          // Wait for the AD CONVERSION TO COMPLETE

    ADCSRA |= 0x10;

    return ADCH;

    }

 

// LCD에 모터 회전방향, PWM duty, RPM 표시하는 루틴

void LCD_control(u08 x){

    u08 o,p,q,r,s,t;

    s16 duty_ratio;

    char direction_str[4];

                         

    if (direction == '+') {

        strcpy(direction_str, "CW ");

    } else {

        strcpy(direction_str, "CCW");

    }

        

     duty_ratio = x*0.39;           //100/255 , 듀티비율 변환 후 lcd에 표시

     o = 0x30 + duty_ratio / 10;  // 십의 자리

     p = 0x30 + duty_ratio % 10;  // 일의 자리

     

     

    lcd_control_write(0x80);  // 첫 번째 라인으로 이동

    lcd_print_data(direction_str, 3);  // CW 또는 CCW 출력

   

    lcd_data_write(o);  // 듀티 비율 십의 자리

    lcd_data_write(p);  // 듀티 비율 일의 자리

    lcd_data_write('%');  // 퍼센트 기호 출력

    lcd_print_data(" R",2);

    

    lcd_control_write(0xC0);

    

    lcd_print_data("PM",2);    

    q = 0x30 + (rpm / 1000);  // 천의 자리

    r = 0x30 + ((rpm % 1000) / 100);  // 백의 자리

    s = 0x30 + ((rpm % 100) / 10);  // 십의 자리

    t = 0x30 + rpm % 10;  // 일의 자리

    

    lcd_data_write(q);  // rpm 천의 자리

    lcd_data_write(r);  // rpm 백의 자리

    lcd_data_write(s);  // rpm 십의 자리

    lcd_data_write(t);  // rpm 일의 자리

 

}    

 

 

void main(void){

    u08 old_key,new_key;

 

    DDRA = 0x00;

    PORTA = 0x00;      //LCD DATA PORT

 

    DDRB = 0b11100000;

    PORTB = 0b00001111;       // UT = VT = WT = 0

    

    DDRD = 0b00001110;

    PORTD = 0b00000000;      // UB = VB = WB = 0

 

    DDRC = 0xff;

    PORTC =0x00;       //BCD KEY INPUT AND LCD CONTROL PORT

        

    DDRE = 0x00;

    

    DDRF = 0x00;

        

    DDRG = 0xFF;

    PORTG = 0x00;      //BUZZER AND RELAY CONTROL PORT            

 

//************타이머 및 인터럽트 초기화 ***********************

 

    TCCR1A = 0x02;      //Timer1 = fast PWM mode(14)

    TCCR1B = 0x19;      //dont output OC1A, OC1B, OC1C    

    TCCR1C = 0x00;      // 16MHz/1/(1+532) = 30kHz

    ICR1 = 532;

    OCR1A = 0;

    OCR1B = 0;

    OCR1CH = 0;

    OCR1CL = 0;

    

    TCCR2 = (1 << WGM21) |(0 << WGM20) | (1 << CS22)| (1 << CS21) | (1 << CS20);  // CTC 모드, 프리스케일러 1024

    OCR2 = 156;  // 100ms 주기로 인터럽트 발생 (16MHz 클럭 기준)

    TIMSK |= (1 << OCIE2);  // 비교 일치 인터럽트 활성화

    TCNT2 = 0x00;    

    

    TCCR3A = 0x00;      // Timer3 = CTC mode(4), dont output OC3A

    TCCR3B = 0x0C;      // 16MHz/256/(1+2499) = 25Hz

    TCCR3C = 0x00;    

    OCR3AH = 9;

    OCR3AL = 195;        // OCR3A = 2499;

 

    TCNT3H = 0x00;     // clear timer/counter3

    TCNT3L = 0x00;

    

    ETIFR = 0x10;       // clear OC3A interrupt flag

    ETIMSK = 0x10;      // enable OC3A interrupt

    

    DDRE = 0x00;         // initialize PORTE

    EICRB = 0x55;       // INT4/5/6 = rising and falling edge

    EIFR = 0x70;

    EIMSK = 0x70;  

  

    ACSR = 0x80;        //아날로그 비교기 비활성화

    SFIOR = 0x00;       // ADC 수동변환, 자동트리거 비활성화

    ADMUX = ADC_VREF_TYPE & 0xff;

    ADCSRA = 0x87;      // enable ADC, 수동 변환 모드, 분주비 128(125kHz)     

 

//********************************************** 

    

    lcd_init();

    lcd_clear();

    lcd_home();

 

    lcd_control_write(0x80);

    lcd_print_data("SUHYEON ",8);

    

    delay_ms(500);

    

    lcd_control_write(0xC0);        

    lcd_print_data("BLDC CON",8);    

    delay_ms(3000);    

 

    lcd_home();    

    lcd_clear();    

          

    #asm("sei")

                          

    count = 100;

    BUZ_RLY = 0x00;

    old_key = 0;

 

       

//****************게이트 드라이브 신호 초기화 *****************

 

    DDRB = 0xE0;

    PORTB &= ~0xE0;       // UT = VT = WT = 0    

    DDRD = 0x0E;

    PORTD = 0x00;      // UB = VB = WB = 0

                         // 부트스트랩 커패시터 충전  UB = VB = WB = 1, UT = VT = WT = 0

    PORTD |= 0x0E;                

    delay_ms(10);

    PORTD = 0x00;

    

    motor_rotate();

 

//*********************** 주 제어루틴 ********************    

     

      

    while(1){     

      new_key = PINB & 0x0F;        

        

        if(new_key!=old_key){              

            switch(new_key){

                case START:

                    motor_running = !motor_running;

                    if(motor_running){

                     #asm("sei")

                     motor_rotate();

                     OCR1A = count;

                     OCR1B = count;

                     OCR1CL = count;

                    }else{

                     #asm("cli")

                     TCCR1A = 0x02;

                     PORTB &= ~0xE0;

                     PORTD = 0x00;

                    }

                    LCD_control(count);                    

                    break;

          case DIRECTION:

                        if (!CW_pressed) {

                         CW_pressed = 1;  // 스위치 눌림 상태 처리

                         prev_count = count;   // 현재 듀티 비율을 저장

                         gradual_stop();       // 듀티 비를 서서히 감소시키며 정지

                        // 방향 변경

                        #asm("cli")

                        direction = (direction == '+') ? '-' : '+';  // 방향을 토글

                       // 방향에 따라 모터 재설정 

                        #asm("sei")

                        motor_rotate();

                        }

                        gradual_start(prev_count);  // 저장된 듀티 비율로 서서히 시작

                        CW_pressed = 0;

                        LCD_control(count);                        

                    break;

          case UP:

                    if(count>=250) count = 250;

                    else count = count + 10;

                    OCR1A = count;

                    OCR1B = count;

                    OCR1CL = count; 

                    LCD_control(count);     

                    break;             

          case DOWN:

                    if(count<=100) count =100;

                    else count = count -10;

                    OCR1A = count;

                    OCR1B = count;

                    OCR1CL = count;

                    LCD_control(count);                     

                    break;                      

         }            

         delay_ms(200);                  

                                      

        }

            LCD_control(count);

            old_key = new_key;

        

    }                                                                        

}   

 

  • BASIC4MCU 작성글 SNS에 공유하기
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기

댓글 3

조회수 55

master님의 댓글

master 작성일

OCR2 = 156;  // 100ms 주기로 인터럽트 발생 (16MHz 클럭 기준)
8비트 타이머로 100ms 주기가 가능한가요?
16.384ms가 한계 아닌가요?

master님의 댓글

master 작성일

질문이 여러가지라서 답변이 어려우니 원론적인 설명만 해드리겠습니다.
//
스텝모터와 BLDC모터는 원리상 동일합니다.
스텝모터는 2상, BLDC모터는 3상으로 조금 복잡할 뿐입니다.
여기에 속도 가감속하는 방법이 조금다릅니다.
스텝모터는 스텝딜레이를 변경해서 속도를 가감속하지만 BLDC는 PWM 듀티로 가감속을 하며, 모터 위치를 파악해서 다음스텝의 시작위치를 잡습니다.(홀 센서가 있다면 홀센서를 활용하겠죠)

BLDC모터도 스텝모터처럼 센서위치 무시하고 딜레이로 구동이 가능합니다.
물론 스타트 매끄럽지 못해서 손으로 돌려주기도 합니다만
예제를 만들 당시에는 매끄러운 스타트가 중요하지 않아서 신경쓰지 않았습니다.
https://cafe.naver.com/circuitsmanual/121156
https://cafe.naver.com/circuitsmanual/133992
상기 2개의 강좌글도 참고하세요

master님의 댓글

master 작성일

rpm을 계산하기 위한 방법에서
펄스 개수는 코드에서 제어하니 정확히 알 수 있습니다.
문제는 시간인데요
여유가 있다면 8비트 타이머보다는 16비트 타이머를 고려해보세요
8비트 밖에 없다면 타이머인터럽트 안에서 변수를 사용해서 카운트하면 됩니다.
//
인터럽트 안에서는 가급적 딜레이를 사용하지 않는 것이 좋으며
시간이 많이 걸리는 연산도 하지 않는 것이 좋습니다.

질문게시판HOME > 질문게시판 목록

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은 질문게시판에서만 작성 가능합니다. 스태프 19-01-15 24133
공지 사이트 이용 안내댓글[31] master 17-10-29 38436
질문 초음파 센서로 장애물 인식댓글[1] 나난ㄴ 24-10-31 41
질문 이런 투명 LCD는 뭐라고 부르나요?댓글[2] 이미지 펌린이 24-10-29 92
현재글 모터제어 중 RPM 계산 질문입니다.댓글[3] suuuuuuuh 24-10-24 56
질문 아트메가 128과 블루투스 모듈(HC-06) 연결 질문댓글[1] 메가아트 24-10-24 49
질문 ATmega128 질문 DFplayer mini댓글[1] Miin 24-10-18 112
질문 스탭모터 3개 회로도 질문.. 삉삉이 24-10-11 93
답변 답변글 답변 : 스탭모터 3개 회로도 질문.. 이미지 master 24-10-12 157
질문 수분수위센서와 멀티플렉서댓글[3] 김고래쓰 24-10-10 283
질문 ATmegq128 PI 제어기 추가댓글[1] 바밤 24-10-08 95
답변 답변글 답변 : ATmegq128 PI 제어기 추가댓글[1] master 24-10-08 196
질문 아두이노 ide 네오픽셀 각 셀 각자 코드 현수 24-09-29 106
질문 아두이노 IDE 프로마이크로 네오픽셀 현수 24-09-29 89
답변 답변글 답변 : 아두이노 IDE 프로마이크로 네오픽셀 master 24-09-29 109
질문 아두이노 프로마이크로 ide 현수 24-09-28 100
답변 답변글 답변 : 아두이노 프로마이크로 ide master 24-09-28 242
질문 ATmega128로 압력센서댓글[1] 이미지첨부파일 바밤 24-09-27 217
질문 아두이노 회로 배선 질문드립니다댓글[3] 이미지 아브 24-09-23 287
질문 아두이노 및 전기배선 작동이 안되어 해결 부탁드립니다 첨부파일 호떡아 24-09-14 231
답변 답변글 답변 : 아두이노 및 전기배선 작동이 안되어 해결 부탁드립니다 master 24-09-14 220
질문 USB host하고 Stop모드를 같이 쓰려는데댓글[1] 이미지 라칸 24-09-12 339
질문 아두이노 압력 센서로 LED 불빛 들어오게 할려고 하는데... 이미지첨부파일 윤시기 24-09-12 517
답변 답변글 답변 : 아두이노 압력 센서로 LED 불빛 들어오게 할려고 하는데... 이미지 master 24-09-12 402
질문 esp32 배터리 잔량 공부중입니다..댓글[6] 펌린이 24-09-06 1761
답변 답변글 답변 : esp32 배터리 잔량 공부중입니다.. 이미지 master 24-09-07 174
질문 ads로 adc값을 읽는데댓글[1] 라칸 24-09-05 233
질문 stm32 절전모드에 대해서댓글[2] 라칸 24-08-29 288
질문 아두이노 우노보드로 스마트팜 만들려고 하는데 문제가 있어요댓글[4] 부러진명검 24-08-28 774
질문 아두이노 블루투스 통신댓글[3] 이미지첨부파일 찌릿공돌이 24-08-27 493
게시물 검색

2022년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2021년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2020년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2020
모바일버전으로보기