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- //100100xxchar 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=0bit 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.4msfor(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.4msfor(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.8msfor(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 commutfor(;;){ // run commutsFET_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 commutelse { 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 emissionbit startup=0; // startup selectorU_C zc_errors=0; // count zc errorsU_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 DDRDDDRE.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 changedset_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 stopstartup_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.4msfor(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.4msfor(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.8msfor(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 순서는 이 배열에서 하고 있습니다.어떤 순서로 출력하든 회전하지 못하도록 순서를 엉망으로 출력하면 됩니다.전에 만들어둔 글도 참고하세요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); } //820Hzdelay_ms(30);for(d=0;d<114;d++){ FET_PORT=commut_table[0]; _delay_us(120); BREAK; STOP; _delay_us(1200); } //758Hzdelay_ms(30);for(d=0;d<104;d++){ FET_PORT=commut_table[0]; _delay_us(240); BREAK; STOP; _delay_us(1200); } //694Hzdelay_ms(30);}한 개의 commutation step만 사용한다면 더 간단해지겠죠
댓글 0
조회수 1,580등록된 댓글이 없습니다.