모터 > 변속기 - Davide Gironi - sound

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

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


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

페이지 정보

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

본문

//
#include
#include
#include
#include
#include
//
#define U_C unsigned char
#define U_I unsigned int
#define U_L unsigned long
//
#define DIR_SW     PINC.5
//
#define FET_PORT   PORTD
#define FET_DDR    DDRD
//#define FET_WH   PORTD.7
//#define FET_WL   PORTD.6
//#define FET_VH   PORTD.5
//#define FET_VL   PORTD.4
//#define FET_UH   PORTD.3
//#define FET_UL   PORTD.2
//
#define STOP  FET_PORT=0x00; //AH=AL=BH=BL=CH=CL=0; //000000xx (CC-BB-AA) //running free(stop)
#define BREAK FET_PORT=0xA8; //A+    B+    C+       //101010xx (CC-BB-AA) //break
//
//                                        CCBBAA
//                                        +-+-+-
//#define RUN0  FET_PORT=0x18; // A+ B- //000110xx
//#define RUN1  FET_PORT=0x48; // A+ C- //010010xx
//#define RUN2  FET_PORT=0x60; // B+ C- //011000xx
//#define RUN3  FET_PORT=0x24; // B+ A- //001001xx
//#define RUN4  FET_PORT=0x84; // C+ A- //100001xx
//#define RUN5  FET_PORT=0x90; // C+ B- //100100xx
char commut_table[]={0x18,0x48,0x60,0x24,0x84,0x90};
U_C commut_step=0;        // current commut step
//
bit dir,dir_old;          // CW dir=1,CCW dir=0
bit enabled=0;            // current running status
//
//---------------------------------------------------------------------------------------------------------
char sound_table[]={0,3,2,5,4,1};
//
void sound_stop(){ BREAK; STOP; _delay_us(1200); }
//
void power_on_sound(){ /* power on sound */
    U_C d,i;
    for(d=0;d<20;d++){ // 20*(( 20+1200)*6)=146.4ms
        for(i=0;i<6;i++){ FET_PORT=commut_table[sound_table[i]]; _delay_us( 20); sound_stop(); } //820Hz
    } delay_ms(30);
    for(d=0;d<20;d++){ // 20*((120+1200)*6)=158.4ms
        for(i=0;i<6;i++){ FET_PORT=commut_table[sound_table[i]]; _delay_us(120); sound_stop(); } //758Hz
    } delay_ms(30);
    for(d=0;d<20;d++){ // 20*((240+1200)*6)=172.8ms
        for(i=0;i<6;i++){ FET_PORT=commut_table[sound_table[i]]; _delay_us(240); sound_stop(); } //694Hz
    } delay_ms(30);
}
//---------------------------------------------------------------------------------------------------------
#define STARTUP_commutS 29
//
U_I startup_delays[30]={                  //[30] //setup startup delays array 10ms-->1.5ms(1000rpm-->6666rpm)
    400,380,360,320,280,240,200,160,120,110,100,96,92,88,84,80,76,72,71,70,69,68,67,66,65,64,63,62,61,60
};
//
void dly_25us(U_I dly){ U_I i; for(i=0;i;i++)delay_us(25);>
//
void startup_motor(){ /* * startup motor cicle */
    U_C i=0,j=0;
    commut_step=0;                      // reset to first commut
    for(;;){                            // run commuts
        FET_PORT=commut_table[commut_step];
        if(commut_step==0){
            if(++i>1){ i=0; if(++j==STARTUP_commutS)break; }
        }
        dly_25us(startup_delays[j]);
        if(dir){ if(++commut_step>5)commut_step=0; } // do next commut
        else   { if(--commut_step<0)commut_step=5; } // do next commut
    }
}
//---------------------------------------------------------------------------------------------------------
U_I adc_read(){ U_I adc; ADCSRA|=0x40; while(!(ADCSRA&0x10)); adc=ADCW; ADCSRA|=0x10; return(adc); }
//---------------------------------------------------------------------------------------------------------
#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){>
                  case 2: if(current_bemf>ZC_THRESHOLD){ emissions=1; STOP; } break; // ZA↓ 
                  case 3: if(current_bemf){>
                  case 4: if(current_bemf>ZC_THRESHOLD){ emissions=1; STOP; } break; // ZB↓ 
                  case 5: if(current_bemf){>
                }
            }
            else{
                switch(commut_step){
                  case 0: if(current_bemf){>
                  case 1: if(current_bemf>ZC_THRESHOLD){ emissions=1; STOP; } break; //  ZB↓
                  case 2: if(current_bemf){>
                  case 3: if(current_bemf>ZC_THRESHOLD){ emissions=1; STOP; } break; //  ZC↓
                  case 4: if(current_bemf){>
                  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; }
        }
    }
}
//---------------------------------------------------------------------------------------------------------
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 */
//---------------------------------------------------------------------------------------------------------
//
void main(void){
    U_I pot_speed=0;
    //
    FET_DDR=0xFC; // #define FET_DDR  DDRD
    DDRE.2=1;     // COMP_INPUT output //COMP_INPUT=0; // COMP_INPUT off
    //
    ADCSRA=0x83;  // Prescaler 8
    //
    set_stop();   //set dir
    //
    BREAK; delay_ms(5); STOP; // precharge bootstrap_caps
    //
    TCCR1B=0x0A; TIMSK=0x10;  // 0.5us*200=10us
    //
    power_on_sound();         // sound start
    //
    dir_old=!DIR_SW;
    //
    OCR1A=100; set_start();
    //
    SREG|=0x80;
    while(1){
        if(DIR_SW!=dir_old){ dir=dir_old=DIR_SW; //dir changed
            set_stop();
            ADMUX=3; pot_speed=adc_read();          // 속도조절 가변저항 모터 정지 시에만 읽음
            OCR1A=(U_I)((float)pot_speed*100.0/1023.0); // 0~100으로 변환
            delay_ms(2000);                             // wait for the motor to stop
            startup_motor(); set_start();
        }
    }
}

이해하기 쉽게 소스를 재구성 했습니다.

//---------------------------------------------------------
char sound_table[]={0,3,2,5,4,1};
//
void sound_stop(){ BREAK; STOP; _delay_us(1200); }
//
void power_on_sound(){ /* power on sound */
    U_C d,i;
    for(d=0;d<20;d++){ // 20*(( 20+1200)*6)=146.4ms
        for(i=0;i<6;i++){ FET_PORT=commut_table[sound_table[i]]; _delay_us( 20); sound_stop(); } //820Hz
    } delay_ms(30);
    for(d=0;d<20;d++){ // 20*((120+1200)*6)=158.4ms
        for(i=0;i<6;i++){ FET_PORT=commut_table[sound_table[i]]; _delay_us(120); sound_stop(); } //758Hz
    } delay_ms(30);
    for(d=0;d<20;d++){ // 20*((240+1200)*6)=172.8ms
        for(i=0;i<6;i++){ FET_PORT=commut_table[sound_table[i]]; _delay_us(240); sound_stop(); } //694Hz
    } delay_ms(30);
}

//---------------------------------------------------------
모터로 소리를 발생 시키는 부분만 뽑았습니다.

void dly_us(U_I d){ int i; for(i=0;i;i++)delay_us(1);>
1us 딜레이를 변수를 사용해서 호출하고 있는데
c 루프 실행 시간이 좀 되서 실제 시간은 계산 값보다 길어집니다.
//
char sound_table[]={0,3,2,5,4,1};
commutation step 순서는 이 배열에서 하고 있습니다.
어떤 순서로 출력하든 회전하지 못하도록 순서를 엉망으로 출력하면 됩니다.

3660040649_o89Be4Ow_25C125A625B825F1_25BE25F825C025BD.PNG3Ftype3Dw740
전에 만들어둔 글도 참고하세요


void power_on_sound(){
    U_C d,i;
    for(d=0;d<123;d++){ FET_PORT=commut_table[0]; _delay_us( 20); BREAK; STOP; _delay_us(1200); } //820Hz
    delay_ms(30);
    for(d=0;d<114;d++){ FET_PORT=commut_table[0]; _delay_us(120); BREAK; STOP; _delay_us(1200); } //758Hz
    delay_ms(30);
    for(d=0;d<104;d++){ FET_PORT=commut_table[0]; _delay_us(240); BREAK; STOP; _delay_us(1200); } //694Hz
    delay_ms(30);
}
한 개의 commutation step만 사용한다면 더 간단해지겠죠

댓글 0

조회수 1,580

등록된 댓글이 없습니다.

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