¿Cómo generar la señal PWM para el motor BLDC usando dsPIC33?

2

Soy un principiante con microcontroladores y estoy trabajando en un proyecto que utiliza el microcontrolador dsPIC33 para controlar un motor BLDC. Estoy teniendo problemas para generar la salida de señal PWM. Usaré la entrada del sensor de efecto Hall en el futuro, pero como no tengo esta disponible en este momento, me gustaría simular la salida PWM por ahora. Si tiene alguna pregunta adicional que lo ayude, no dude en preguntar. ¡Cualquier comentario es bienvenido y apreciado!

Aquíhayunacapturadepantallademiseñaldesalidaenestemomento.EnlugardecambiarlosestadosquedeseoenStateTableIndex's,mantieneesteestadoparatodaslasseñales.

//DSPIC33EP256MC506ConfigurationBitSettings//'C'sourcelineconfigstatements//FICD#pragmaconfigICS=PGD2//ICDCommunicationChannelSelectbits(CommunicateonPGEC1andPGED1)#pragmaconfigJTAGEN=OFF//JTAGEnablebit(JTAGisdisabled)//FPOR#pragmaconfigALTI2C1=ON//AlternateI2C1pins(I2C1mappedtoASDA1/ASCL1pins)#pragmaconfigALTI2C2=ON//AlternateI2C2pins(I2C2mappedtoASDA2/ASCL2pins)#pragmaconfigWDTWIN=WIN25//WatchdogWindowSelectbits(WDTWindowis25%ofWDTperiod)//FWDT#pragmaconfigWDTPOST=PS32768//WatchdogTimerPostscalerbits(1:32,768)#pragmaconfigWDTPRE=PR128//WatchdogTimerPrescalerbit(1:128)#pragmaconfigPLLKEN=ON//PLLLockEnablebit(ClockswitchtoPLLsourcewillwaituntilthePLLlocksignalisvalid.)#pragmaconfigWINDIS=OFF//WatchdogTimerWindowEnablebit(WatchdogTimerinNon-Windowmode)#pragmaconfigFWDTEN=OFF//WatchdogTimerEnablebit(Watchdogtimerenabled/disabledbyusersoftware)//FOSC#pragmaconfigPOSCMD=XT//PrimaryOscillatorModeSelectbits(XTCrystalOscillatorMode)#pragmaconfigOSCIOFNC=OFF//OSC2PinFunctionbit(OSC2isclockoutput)#pragmaconfigIOL1WAY=OFF//Peripheralpinselectconfiguration(Allowmultiplereconfigurations)#pragmaconfigFCKSM=CSECMD//ClockSwitchingModebits(Clockswitchingisenabled,Fail-safeClockMonitorisdisabled)//FOSCSEL#pragmaconfigFNOSC=FRC//OscillatorSourceSelection(InternalFastRC(FRC))#pragmaconfigPWMLOCK=ON//PWMLockEnablebit(CertainPWMregistersmayonlybewrittenafterkeysequence)#pragmaconfigIESO=ON//Two-speedOscillatorStart-upEnablebit(StartupdevicewithFRC,thenswitchtouser-selectedoscillatorsource)//FGS#pragmaconfigGWRP=OFF//GeneralSegmentWrite-Protectbit(GeneralSegmentmaybewritten)#pragmaconfigGCP=OFF//GeneralSegmentCode-Protectbit(GeneralSegmentCodeprotectisDisabled)//#pragmaconfigstatementsshouldprecedeprojectfileincludes.//Useprojectenumsinsteadof#defineforONandOFF.#include<xc.h>#include<p33Exxxx.h>#include<stdio.h>#defineSYS_FREQ50000000L#defineFCYSYS_FREQ/2/****************************CONFIGURATION****************************/unsignedintStateIndexTable1[]={0xC00C,0xC00C,0xC004,0xC00C,0xC00C,0xC00C,0xC004,0xC00C};unsignedintStateIndexTable2[]={0xC00C,0xC00C,0xC00C,0xC00C,0xC004,0xC004,0xC00C,0xC00C};unsignedintStateIndexTable3[]={0xC00C,0xC004,0xC00C,0xC004,0xC00C,0xC00C,0xC00C,0xC00C};longunsignedintpwmOutput=0;intindexx=0;voidinitAdc1(void);voidInit_Timers(void);voidDelay_us(unsignedint);voidDelay_ms(unsignedint);intADCValue,i;intmain(void){//ConfigurethedevicePLLtoobtain40MIPSoperation.Thecrystalfrequencyis8MHz.//Divide8MHzby2,multiplyby40anddivideby2.ThisresultsinFoscof80MHz.//TheCPUclockfrequencyisFcy=Fosc/2=40MHz.PLLFBD=0x0030;/*M=40*/CLKDIVbits.PLLPOST=1;/*N1=2*/CLKDIVbits.PLLPRE=0;/*N2=2*/OSCTUN=0;/*InitiateClockSwitchtoPrimaryOscillatorwithPLL(NOSC=0x3)*/__builtin_write_OSCCONH(0x03);__builtin_write_OSCCONL(0x01);while(OSCCONbits.COSC!=0x3);while(_LOCK==0);/*WaitforPLLlockat40MIPS*/initAdc1();Init_Timers();while(1){/*IOCON1=0xC004;IOCON2=0xC00C;IOCON3=0xC00C;*/Delay_us(100);pwmOutput=(indexx%6)+1;IOCON1=StateIndexTable1[pwmOutput];IOCON2=StateIndexTable2[pwmOutput];IOCON3=StateIndexTable3[pwmOutput];indexx++;Delay_ms(1000);/*AD1CON1bits.SAMP=1;//StartsamplingDelay_us(10);//Waitforsamplingtime(10us)AD1CON1bits.SAMP=0;//Starttheconversionwhile(!AD1CON1bits.DONE);//WaitfortheconversiontocompleteADCValue=ADC1BUF0;//ReadtheADCconversionresult*/}}voidinitAdc1(void){TRISB=0x01FF;//SetPWMasoutputs/*Setportconfiguration*/ANSELA=ANSELB=ANSELC=ANSELE=0x0000;ANSELEbits.ANSE13=1;//SetpottoanalogTRISEbits.TRISE13=1;//Setpottoinput/*InitializeandenableADCmodule*/AD1CON1=0x0000;AD1CON2=0x0000;AD1CON3=0x000F;AD1CON4=0x0000;AD1CHS0=0x000D;AD1CHS123=0x0000;AD1CSSH=0x0000;AD1CSSL=0x0000;AD1CON1bits.ADON=1;Delay_us(20);//selectmasterdutycycleMDCPWMCON1=0x0000;PWMCON2=0x0000;PWMCON3=0x0000;//initializePWMxH/LinoverridelowstateIOCON1=0xC300;IOCON2=0xC300;IOCON3=0xC300;//PWMfaultconfigurationFCLCON1=0x03;FCLCON2=0x03;FCLCON3=0x03;PTPER=4999;//(FOSC/FPWM-1)SEVTCMP=PTPER;//PWMperiodisspecialeventtriggerPDC1=PDC2=PDC3=499;//InitializeDutyCycles@50%PTCON=0x8000;}voidInit_Timers(void){//Timer4&5T4CON=0x0038;//32bittimer,pre-scalerof256T5CONbits.TSIDL=0;//TimertooperateduringidleTMR5HLD=0;//MSB(writetoMSWfirstthenLSW)TMR4=0;//LSBPR5=0xFFFF;//PeriodofMSBPR4=0xFFFF;//PeriodofLSB}//[TMR5][TMR4]holdsupto2147483648decimal//maxvalueforcompare=214783648/97//DELAYUPTO22139006msvoidDelay_ms(unsignedintdelay){TMR5HLD=0;//ResettimervaluesTMR4=0;T4CONbits.TON=1;//Start32bittimerunsignedlongtimer_4_ticks=97UL*delay;//Calculateclocktickstowaitunsignedlongtmp=0;while(tmp<timer_4_ticks){tmp=TMR4;tmp|=(unsignedlong)TMR5HLD<<16;}T4CONbits.TON=0;}voidDelay_us(unsignedintdelay){for(i=0;i<delay;i++){__asm__volatile("repeat #39");
        __asm__ volatile ("nop");
    }
}
    
pregunta KP123

1 respuesta

1

Francamente, no estoy seguro de que alguien verifique tu código, no lo haría. Pero me gustaría explicar qué necesitas. Hay muchas opciones, así que vamos a limitar sus opciones.

Primero, para mover BLDC debe decidir el método de conmutación. Verás, en BLDC los imanes se mueven sobre las bobinas, por lo que tienes que conmutar cada bobina de manera diferente para ajustar la fuerza aplicada al imán. Para mantener la fuerza al máximo, debe mantener el "ángulo de conmutación" a 90 grados. Y para eso necesitas saber la posición exacta. Así que necesitas retroalimentación de posición. Utilice sensores de efecto Hall: proporcionarán seis posiciones por par de polos (los pares de polos se dan en la hoja de datos del motor). Otra opción es el codificador, pero es un poco más complicado.

Entonces, teniendo los pares de polos, puedes conducir dos fases específicas. Correcto, tiene tres cables, por lo que para cada combinación de sensores de efecto de hall tendrá que elegir dos cables y una dirección.

Ahora necesitas ver lo que tienes en hardware. Debes tener tres medios puentes, cada uno es de hecho dos mosfets. Tendrá que conducir cada mosfet con su propio PWM. Cada par obtendrá un PWM opuesto con un pequeño tiempo de pausa. El ciclo de trabajo será proporcional al voltaje. Entonces, si quieres conducir las fases A y B, usa 0V en C, + V en A y -V en B. Luego cambia según los sensores de efecto de hall.

Bueno, si todo eso es útil, puedo continuar y alcanzar los bucles de posición y velocidad, control de corriente, etc ...

    
respondido por el Gregory Kornblum

Lea otras preguntas en las etiquetas