모터 > 변속기 - Davide Gironi - timer

TODAY368 TOTAL3,068,168
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

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


BASIC4MCU | 모터 | BLDC모터 | 변속기 - Davide Gironi - timer

페이지 정보

작성자 키트 작성일2017-09-05 15:18 조회1,693회 댓글0건

본문

이제 타이머만 남았습니다.^^

//---------------------------------------------------------------------------------------------------------
#define ZC_THRESHOLD  150 // zc bemf threshold value
#define ZC_ERRORS     100 // number of zc threshold reading error befor emissions a motor startup
//
//
bit emissions=1;    // emissions or skip emission
bit startup=0;      // startup selector
U_C zc_errors=0;    // count zc errors
U_I current_bemf=0; // bemf value used in zc detection
//
interrupt [TIM1_COMPA] void timer1_compa_isr(void){ /* * main bldc timer */
    if(enabled){
        if(emissions){ emissions=0;
            STOP; delay_us(10); FET_PORT=commut_table[commut_step];
            if(dir){
                switch(commut_step){
                  case 0: ADMUX=1; commut_step=1; break;
                  case 1: ADMUX=0; commut_step=2; break;
                  case 2: ADMUX=2; commut_step=3; break;
                  case 3: ADMUX=1; commut_step=4; break;
                  case 4: ADMUX=0; commut_step=5; break;
                  case 5: ADMUX=2; commut_step=0; break;
                }
            }
            else{
                switch(commut_step){
                  case 0: ADMUX=0; commut_step=5; break;
                  case 1: ADMUX=1; commut_step=4; break;
                  case 2: ADMUX=2; commut_step=3; break;
                  case 3: ADMUX=0; commut_step=2; break;
                  case 4: ADMUX=1; commut_step=1; break;
                  case 5: ADMUX=2; commut_step=0; break;
                }
            }
            zc_errors=0;
        }
        //
        if(!emissions){
            current_bemf=adc_read();
            if(dir){
                switch(commut_step){
                  case 0: if(current_bemf>ZC_THRESHOLD){ emissions=1; STOP; } break; // ZC↓ 
                  case 1: if(current_bemf<ZC_THRESHOLD){ emissions=1; STOP; } break; //  ZB↑
                  case 2: if(current_bemf>ZC_THRESHOLD){ emissions=1; STOP; } break; // ZA↓ 
                  case 3: if(current_bemf<ZC_THRESHOLD){ emissions=1; STOP; } break; //  ZC↑
                  case 4: if(current_bemf>ZC_THRESHOLD){ emissions=1; STOP; } break; // ZB↓ 
                  case 5: if(current_bemf<ZC_THRESHOLD){ emissions=1; STOP; } break; //  ZA↑
                }
            }
            else{
                switch(commut_step){
                  case 0: if(current_bemf<ZC_THRESHOLD){ emissions=1; STOP; } break; // ZC↑
                  case 1: if(current_bemf>ZC_THRESHOLD){ emissions=1; STOP; } break; //  ZB↓
                  case 2: if(current_bemf<ZC_THRESHOLD){ emissions=1; STOP; } break; // ZA↑ 
                  case 3: if(current_bemf>ZC_THRESHOLD){ emissions=1; STOP; } break; //  ZC↓
                  case 4: if(current_bemf<ZC_THRESHOLD){ emissions=1; STOP; } break; // ZB↑
                  case 5: if(current_bemf>ZC_THRESHOLD){ emissions=1; STOP; } break; //  ZA↓ 
                }
            }
            //
            if(++zc_errors>ZC_ERRORS){ zc_errors=0; startup_motor(); commut_step=0; emissions=1; }
        }
    }
}
//---------------------------------------------------------------------------------------------------------
이해하기 쉽도록 나열식으로 작성하다보니 원본 소스보다 많이 길어졌습니다.^^


interrupt [TIM1_COMPA] void timer1_compa_isr(void){ /* * main bldc timer */
    if(enabled){
        // code
    }
}

회전방향 변경 및 속도 변경등으로 모터를 정지시키고 다시 구동 할 때에는 
타이머를 금지 시키기 위해서 enabled 변수를 사용하고 있습니다.

void set_stop() { if( enabled){ SREG&=0x7F; enabled=0; STOP; SREG|=0x80; } } /* * set stop */
void set_start(){ if(!enabled){ SREG&=0x7F; enabled=1;       SREG|=0x80; } } /* * set start */
기억나시죠?

//

bit emissions=1;    // emissions or skip emission
//
interrupt [TIM1_COMPA] void timer1_compa_isr(void){ /* * main bldc timer */
    if(emissions){ // commutation step 마다 1회만 실행
        STOP; delay_us(10); // 10us동안 출력을 OFF 시킨 후
        FET_PORT=commut_table[commut_step]; // FET 출력을 하고
        emissions=0;
    }
    //
    if(!emissions){ // 제로크로싱 디텍트 될 때까지 계속 실행
        current_bemf=adc_read();
        if(current_bemf>ZC_THRESHOLD){ emissions=1; STOP; }
    }
}
인터럽트 함수의 큰 틀은 이 것입니다.
FET 출력을 하고나서 제로크로싱 디텍트 할 때까지 반복적으로 체크합니다.
제로크로싱 디텍트 되면 FET 출력을 OFF 시키고 emissions을 1로 set 시켜서 다음 인터럽트 주기에서 FET 출력 하도록 준비합니다.

//
제로크로싱 디텍트 부터 시간을 보면
제로크로싱 검출 ok - FET OFF 후 인터럽트 빠져나감
TIMER 주기 딜레이
10us 딜레이
FET ON 
제로크로싱 검출? no 
TIMER 주기 딜레이
제로크로싱 검출? no 
TIMER 주기 딜레이
제로크로싱 검출 ok - FET OFF 후 인터럽트 빠져나감

FET 출력 후 제로크로싱 디텍트 될 때까지 몇차례의 인터럽트 주기동안 기다린 후에
다음 commutation step 출력을 합니다.

댓글 0

조회수 1,693

등록된 댓글이 없습니다.

모터HOME > 모터 > BLDC모터 목록

게시물 검색

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
모바일버전으로보기