Quantcast
Channel: Microcontrollers
Viewing all articles
Browse latest Browse all 218521

Forum Post: RE: TMS320F28027F: TMS320F28027with DRV8301 to run bldc motor

$
0
0
Hi Jason Osborn // system includes #include #include "main.h" #include "sw/drivers/sci/src/32b/f28x/f2802x/sci.h" #include "hal.h" #include "hal_obj.h" //Added // Define motor control and UART variables bool isMotorOn = false; bool isWaitingTxFifoEmpty = false; bool isTxOffDelayActive = false; int txOffDelayCounter = 0; int txOffDelayCount = 1000; // Example delay count int counter = 0; char buf[8]; char returnBuf[8]; // Added uint16_t boardId = '5'; volatile bool isVoltageTooLow = true; _iq lowVoltageThreshold = _IQ(0.01); bool isCommandReceived = false; bool isCommandStart = false; bool isOpenLoop = false; bool shouldSendSpeed = false; // Constants for command processing #define BUF_SIZE 8 #define CMD_RX_ON "RX_ON" #define CMD_RX_OFF "RX_OFF" // Globals for UART and motor control static char buf[BUF_SIZE]; //static int counter = 0; //static bool isMotorOn = false; #ifdef FLASH #pragma CODE_SECTION(mainISR,"ramfuncs"); #endif // Include header files used in the main function // ************************************************************************** // the defines // ************************************************************************** // the globals CLARKE_Handle clarkeHandle_I; //! estHandle = estHandle; // initialize the estimator through the controller. These three // function calls are needed for the F2806xF/M implementation of // InstaSPIN. CTRL_setParams(ctrlHandle,&gUserParams); CTRL_setUserMotorParams(ctrlHandle); CTRL_setupEstIdleState(ctrlHandle); } #else { // initialize the estimator. These two function calls are needed for // the F2802xF implementation of InstaSPIN using the estimator handle // initialized by EST_init(), these two function calls configure the // estimator, and they set the estimator in a proper state prior to // spinning a motor. EST_setEstParams(estHandle,&gUserParams); EST_setupEstIdleState(estHandle); } #endif // disable Rs recalculation // **NOTE: changing the input parameter from 'false' to 'true' will cause // ** run time issues. Lab11 does not support Rs Online function // EST_setFlag_enableRsRecalc(estHandle,false); // set the number of current sensors setupClarke_I(clarkeHandle_I,USER_NUM_CURRENT_SENSORS); // set the number of voltage sensors setupClarke_V(clarkeHandle_V,USER_NUM_VOLTAGE_SENSORS); // set the pre-determined current and voltage feeback offset values gOffsets_I_pu.value[0] = _IQ(I_A_offset); gOffsets_I_pu.value[1] = _IQ(I_B_offset); gOffsets_I_pu.value[2] = _IQ(I_C_offset); gOffsets_V_pu.value[0] = _IQ(V_A_offset); gOffsets_V_pu.value[1] = _IQ(V_B_offset); gOffsets_V_pu.value[2] = _IQ(V_C_offset); // initialize the PID controllers { // This equation defines the relationship between per unit current and // real-world current. The resulting value in per units (pu) is then // used to configure the controllers _iq maxCurrent_pu = _IQ(USER_MOTOR_MAX_CURRENT / USER_IQ_FULL_SCALE_CURRENT_A); // This equation uses the scaled maximum voltage vector, which is // already in per units, hence there is no need to include the #define // for USER_IQ_FULL_SCALE_VOLTAGE_V _iq maxVoltage_pu = _IQ(USER_MAX_VS_MAG_PU * USER_VD_SF); float_t fullScaleCurrent = USER_IQ_FULL_SCALE_CURRENT_A; float_t fullScaleVoltage = USER_IQ_FULL_SCALE_VOLTAGE_V; float_t IsrPeriod_sec = 1.0 / USER_ISR_FREQ_Hz; float_t Ls_d = USER_MOTOR_Ls_d; float_t Ls_q = USER_MOTOR_Ls_q; float_t Rs = USER_MOTOR_Rs; // This lab assumes that motor parameters are known, and it does not // perform motor ID, so the R/L parameters are known and defined in // user.h float_t RoverLs_d = Rs / Ls_d; float_t RoverLs_q = Rs / Ls_q; // For the current controller, Kp = Ls*bandwidth(rad/sec) But in order // to be used, it must be converted to per unit values by multiplying // by fullScaleCurrent and then dividing by fullScaleVoltage. From the // statement below, we see that the bandwidth in rad/sec is equal to // 0.25/IsrPeriod_sec, which is equal to USER_ISR_FREQ_HZ/4. This means // that by setting Kp as described below, the bandwidth in Hz is // USER_ISR_FREQ_HZ/(8*pi). _iq Kp_Id = _IQ((0.25 * Ls_d * fullScaleCurrent) / (IsrPeriod_sec * fullScaleVoltage)); // In order to achieve pole/zero cancellation (which reduces the // closed-loop transfer function from a second-order system to a // first-order system), Ki must equal Rs/Ls. Since the output of the // Ki gain stage is integrated by a DIGITAL integrator, the integrator // input must be scaled by 1/IsrPeriod_sec. That's just the way // digital integrators work. But, since IsrPeriod_sec is a constant, // we can save an additional multiplication operation by lumping this // term with the Ki value. _iq Ki_Id = _IQ(RoverLs_d * IsrPeriod_sec); // Now do the same thing for Kp for the q-axis current controller. // If the motor is not an IPM motor, Ld and Lq are the same, which // means that Kp_Iq = Kp_Id _iq Kp_Iq = _IQ((0.25 * Ls_q * fullScaleCurrent) / (IsrPeriod_sec * fullScaleVoltage)); // Do the same thing for Ki for the q-axis current controller. If the // motor is not an IPM motor, Ld and Lq are the same, which means that // Ki_Iq = Ki_Id. _iq Ki_Iq = _IQ(RoverLs_q * IsrPeriod_sec); // There are three PI controllers; one speed controller and two current // controllers. Each PI controller has two coefficients; Kp and Ki. // So you have a total of six coefficients that must be defined. // This is for the speed controller pidHandle[0] = PID_init(&pid[0],sizeof(pid[0])); // This is for the Id current controller pidHandle[1] = PID_init(&pid[1],sizeof(pid[1])); // This is for the Iq current controller pidHandle[2] = PID_init(&pid[2],sizeof(pid[2])); // The following instructions load the parameters for the speed PI // controller. PID_setGains(pidHandle[0],_IQ(1.0),_IQ(0.01),_IQ(0.0)); // The current limit is performed by the limits placed on the speed PI // controller output. In the following statement, the speed // controller's largest negative current is set to -maxCurrent_pu, and // the largest positive current is set to maxCurrent_pu. PID_setMinMax(pidHandle[0],-maxCurrent_pu,maxCurrent_pu); PID_setUi(pidHandle[0],_IQ(0.0)); // Set the initial condition value // for the integrator output to 0 pidCntSpeed = 0; // Set the counter for decimating the speed // controller to 0 // The following instructions load the parameters for the d-axis // current controller. // P term = Kp_Id, I term = Ki_Id, D term = 0 PID_setGains(pidHandle[1],Kp_Id,Ki_Id,_IQ(0.0)); // Largest negative voltage = -maxVoltage_pu, largest positive // voltage = maxVoltage_pu PID_setMinMax(pidHandle[1],-maxVoltage_pu,maxVoltage_pu); // Set the initial condition value for the integrator output to 0 PID_setUi(pidHandle[1],_IQ(0.0)); // The following instructions load the parameters for the q-axis // current controller. // P term = Kp_Iq, I term = Ki_Iq, D term = 0 PID_setGains(pidHandle[2],Kp_Iq,Ki_Iq,_IQ(0.0)); // The largest negative voltage = 0 and the largest positive // voltage = 0. But these limits are updated every single ISR before // actually executing the Iq controller. The limits depend on how much // voltage is left over after the Id controller executes. So having an // initial value of 0 does not affect Iq current controller execution. PID_setMinMax(pidHandle[2],_IQ(0.0),_IQ(0.0)); // Set the initial condition value for the integrator output to 0 PID_setUi(pidHandle[2],_IQ(0.0)); } // initialize the speed reference in kilo RPM where base speed is // USER_IQ_FULL_SCALE_FREQ_Hz. // Set 10 Hz electrical frequency as initial value, so the kRPM value would // be: 10 * 60 / motor pole pairs / 1000. gMotorVars.SpeedRef_krpm = _IQmpy(_IQ(10.0),gSpeed_hz_to_krpm_sf); // initialize the inverse Park module iparkHandle = IPARK_init(&ipark,sizeof(ipark)); // initialize the space vector generator module svgenHandle = SVGEN_init(&svgen,sizeof(svgen)); // setup faults HAL_setupFaults(halHandle); // initialize the interrupt vector table HAL_initIntVectorTable(halHandle); // enable the ADC interrupts HAL_enableAdcInts(halHandle); // enable global interrupts HAL_enableGlobalInts(halHandle); // enable debug interrupts HAL_enableDebugInt(halHandle); // disable the PWM HAL_disablePwm(halHandle); // compute scaling factors for flux and torque calculations gFlux_pu_to_Wb_sf = USER_computeFlux_pu_to_Wb_sf(); gFlux_pu_to_VpHz_sf = USER_computeFlux_pu_to_VpHz_sf(); gTorque_Ls_Id_Iq_pu_to_Nm_sf = USER_computeTorque_Ls_Id_Iq_pu_to_Nm_sf(); gTorque_Flux_Iq_pu_to_Nm_sf = USER_computeTorque_Flux_Iq_pu_to_Nm_sf(); // enable the system by default gMotorVars.Flag_enableSys = true; #ifdef DRV8301_SPI // turn on the DRV8301 if present HAL_enableDrv(halHandle); // initialize the DRV8301 interface HAL_setupDrvSpi(halHandle,&gDrvSpi8301Vars); #endif #ifdef DRV8305_SPI // turn on the DRV8305 if present HAL_enableDrv(halHandle); // initialize the DRV8305 interface HAL_setupDrvSpi(halHandle,&gDrvSpi8305Vars); #endif // Begin the background loop for(;;) { // Waiting for enable system flag to be set while(!(gMotorVars.Flag_enableSys)); // loop while the enable system flag is true while(gMotorVars.Flag_enableSys) { // If Flag_enableSys is set AND Flag_Run_Identify is set THEN // enable PWMs and set the speed reference if(gMotorVars.Flag_Run_Identify) { // update estimator state EST_updateState(estHandle,0); #ifdef FAST_ROM_V1p6 // call this function to fix 1p6. This is only used for // F2806xF/M implementation of InstaSPIN (version 1.6 of // ROM), since the inductance calculation is not done // correctly in ROM, so this function fixes that ROM bug. softwareUpdate1p6(estHandle); #endif // enable the PWM HAL_enablePwm(halHandle); } else // Flag_enableSys is set AND Flag_Run_Identify is not set { // set estimator to Idle EST_setIdle(estHandle); // disable the PWM HAL_disablePwm(halHandle); // clear integrator outputs PID_setUi(pidHandle[0],_IQ(0.0)); PID_setUi(pidHandle[1],_IQ(0.0)); PID_setUi(pidHandle[2],_IQ(0.0)); // clear Id and Iq references gIdq_ref_pu.value[0] = _IQ(0.0); gIdq_ref_pu.value[1] = _IQ(0.0); } // update the global variables updateGlobalVariables(estHandle); // enable/disable the forced angle EST_setFlag_enableForceAngle(estHandle, gMotorVars.Flag_enableForceAngle); // set target speed gMotorVars.SpeedRef_pu = _IQmpy(gMotorVars.SpeedRef_krpm, gSpeed_krpm_to_pu_sf); #ifdef DRV8301_SPI HAL_writeDrvData(halHandle,&gDrvSpi8301Vars); HAL_readDrvData(halHandle,&gDrvSpi8301Vars); #endif #ifdef DRV8305_SPI HAL_writeDrvData(halHandle,&gDrvSpi8305Vars); HAL_readDrvData(halHandle,&gDrvSpi8305Vars); #endif } // end of while(gFlag_enableSys) loop // disable the PWM HAL_disablePwm(halHandle); gMotorVars.Flag_Run_Identify = false; } // end of for(;;) loop } // end of main() function //! \brief The main ISR that implements the motor control. interrupt void mainISR(void) { // Declaration of local variables _iq angle_pu = _IQ(0.0); _iq speed_pu = _IQ(0.0); _iq oneOverDcBus; MATH_vec2 Iab_pu; MATH_vec2 Vab_pu; MATH_vec2 phasor; // acknowledge the ADC interrupt HAL_acqAdcInt(halHandle,ADC_IntNumber_1); // convert the ADC data HAL_readAdcDataWithOffsets(halHandle,&gAdcData); // remove offsets gAdcData.I.value[0] = gAdcData.I.value[0] - gOffsets_I_pu.value[0]; gAdcData.I.value[1] = gAdcData.I.value[1] - gOffsets_I_pu.value[1]; gAdcData.I.value[2] = gAdcData.I.value[2] - gOffsets_I_pu.value[2]; gAdcData.V.value[0] = gAdcData.V.value[0] - gOffsets_V_pu.value[0]; gAdcData.V.value[1] = gAdcData.V.value[1] - gOffsets_V_pu.value[1]; gAdcData.V.value[2] = gAdcData.V.value[2] - gOffsets_V_pu.value[2]; // run Clarke transform on current. Three values are passed, two values // are returned. CLARKE_run(clarkeHandle_I,&gAdcData.I,&Iab_pu); // run Clarke transform on voltage. Three values are passed, two values // are returned. CLARKE_run(clarkeHandle_V,&gAdcData.V,&Vab_pu); // run the estimator // The speed reference is needed so that the proper sign of the forced // angle is calculated. When the estimator does not do motor ID as in this // lab, only the sign of the speed reference is used EST_run(estHandle,&Iab_pu,&Vab_pu,gAdcData.dcBus,gMotorVars.SpeedRef_pu); // generate the motor electrical angle angle_pu = EST_getAngle_pu(estHandle); speed_pu = EST_getFm_pu(estHandle); // get Idq from estimator to avoid sin and cos, and a Park transform, // which saves CPU cycles EST_getIdq_pu(estHandle,&gIdq_pu); // run the appropriate controller if(gMotorVars.Flag_Run_Identify) { // Declaration of local variables. _iq refValue; _iq fbackValue; _iq outMax_pu; // when appropriate, run the PID speed controller // This mechanism provides the decimation for the speed loop. if(pidCntSpeed >= USER_NUM_CTRL_TICKS_PER_SPEED_TICK) { // Reset the Speed PID execution counter. pidCntSpeed = 0; // The next instruction executes the PI speed controller and places // its output in Idq_ref_pu.value[1], which is the input reference // value for the q-axis current controller. PID_run_spd(pidHandle[0],gMotorVars.SpeedRef_pu,speed_pu, &(gIdq_ref_pu.value[1])); } else { // increment counter pidCntSpeed++; } // Get the reference value for the d-axis current controller. refValue = gIdq_ref_pu.value[0]; // Get the actual value of Id fbackValue = gIdq_pu.value[0]; // The next instruction executes the PI current controller for the // d axis and places its output in Vdq_pu.value[0], which is the // control voltage along the d-axis (Vd) PID_run(pidHandle[1],refValue,fbackValue,&(gVdq_out_pu.value[0])); // get the Iq reference value refValue = gIdq_ref_pu.value[1]; // get the actual value of Iq fbackValue = gIdq_pu.value[1]; // The voltage limits on the output of the q-axis current controller // are dynamic, and are dependent on the output voltage from the d-axis // current controller. In other words, the d-axis current controller // gets first dibs on the available voltage, and the q-axis current // controller gets what's left over. That is why the d-axis current // controller executes first. The next instruction calculates the // maximum limits for this voltage as: // Vq_min_max = +/- sqrt(Vbus^2 - Vd^2) outMax_pu = _IQsqrt(_IQ(USER_MAX_VS_MAG_PU * USER_MAX_VS_MAG_PU) - _IQmpy(gVdq_out_pu.value[0],gVdq_out_pu.value[0])); // Set the limits to +/- outMax_pu PID_setMinMax(pidHandle[2],-outMax_pu,outMax_pu); // The next instruction executes the PI current controller for the // q axis and places its output in Vdq_pu.value[1], which is the // control voltage vector along the q-axis (Vq) PID_run(pidHandle[2],refValue,fbackValue,&(gVdq_out_pu.value[1])); // The voltage vector is now calculated and ready to be applied to the // motor in the form of three PWM signals. However, even though the // voltages may be supplied to the PWM module now, they won't be // applied to the motor until the next PWM cycle. By this point, the // motor will have moved away from the angle that the voltage vector // was calculated for, by an amount which is proportional to the // sampling frequency and the speed of the motor. For steady-state // speeds, we can calculate this angle delay and compensate for it. angle_pu = angleDelayComp(speed_pu,angle_pu); // compute the sine and cosine phasor values which are part of the inverse // Park transform calculations. Once these values are computed, // they are copied into the IPARK module, which then uses them to // transform the voltages from DQ to Alpha/Beta reference frames. phasor.value[0] = _IQcosPU(angle_pu); phasor.value[1] = _IQsinPU(angle_pu); // set the phasor in the inverse Park transform IPARK_setPhasor(iparkHandle,&phasor); // Run the inverse Park module. This converts the voltage vector from // synchronous frame values to stationary frame values. IPARK_run(iparkHandle,&gVdq_out_pu,&Vab_pu); // These 3 statements compensate for variations in the DC bus by adjusting the // PWM duty cycle. The goal is to achieve the same volt-second product // regardless of the DC bus value. To do this, we must divide the desired voltage // values by the DC bus value. Or...it is easier to multiply by 1/(DC bus value). oneOverDcBus = EST_getOneOverDcBus_pu(estHandle); Vab_pu.value[0] = _IQmpy(Vab_pu.value[0],oneOverDcBus); Vab_pu.value[1] = _IQmpy(Vab_pu.value[1],oneOverDcBus); // Now run the space vector generator (SVGEN) module. // There is no need to do an inverse CLARKE transform, as this is // handled in the SVGEN_run function. SVGEN_run(svgenHandle,&Vab_pu,&(gPwmData.Tabc)); } else // gMotorVars.Flag_Run_Identify = 0 { // disable the PWM HAL_disablePwm(halHandle); // Set the PWMs to 50% duty cycle gPwmData.Tabc.value[0] = _IQ(0.0); gPwmData.Tabc.value[1] = _IQ(0.0); gPwmData.Tabc.value[2] = _IQ(0.0); } // write to the PWM compare registers, and then we are done! HAL_writePwmData(halHandle,&gPwmData); return; } // end of mainISR() function //! \brief The angleDelayComp function compensates for the delay introduced //! \brief from the time when the system inputs are sampled to when the PWM //! \brief voltages are applied to the motor windings. _iq angleDelayComp(const _iq fm_pu,const _iq angleUncomp_pu) { _iq angleDelta_pu = _IQmpy(fm_pu,_IQ(USER_IQ_FULL_SCALE_FREQ_Hz / (USER_PWM_FREQ_kHz*1000.0))); _iq angleCompFactor = _IQ(1.0 + (float_t)USER_NUM_PWM_TICKS_PER_ISR_TICK * 0.5); _iq angleDeltaComp_pu = _IQmpy(angleDelta_pu,angleCompFactor); uint32_t angleMask = ((uint32_t)0xFFFFFFFF >> (32 - GLOBAL_Q)); _iq angleComp_pu; _iq angleTmp_pu; // increment the angle angleTmp_pu = angleUncomp_pu + angleDeltaComp_pu; // mask the angle for wrap around // note: must account for the sign of the angle angleComp_pu = _IQabs(angleTmp_pu) & angleMask; // account for sign if(angleTmp_pu sciAHandle)) { char c = SCI_read(obj->sciAHandle); if (counter ') // End of command { buf[counter] = '\0'; // Null-terminate the command string processCommand(buf); counter = 0; // Reset buffer index } } else { // Buffer overflow, reset counter counter = 0; } } // Clear SCI interrupt flag PIE_clearInt(obj->pieHandle, PIE_GroupNumber_9); } // Process received command void processCommand(char *command) { if (strcmp(command, CMD_RX_ON) == 0) { isMotorOn = true; sendResponse("Motor ON"); } else if (strcmp(command, CMD_RX_OFF) == 0) { isMotorOn = false; sendResponse("Motor OFF"); } else { sendResponse("Unknown Command"); } } // Send response to UART void sendResponse(const char *message) { int length = strlen(message); returnBuf[0] = ' '; serialWrite(returnBuf, length + 2); } // Write data to UART void serialWrite(const char *sendData, int length) { int i = 0; while (i sciAHandle)) { SCI_write(halHandle->sciAHandle, sendData[i]); i++; } } isWaitingTxFifoEmpty = true; } //! \brief Update the global variables (gMotorVars). //! \param[in] handle The estimator (EST) handle void updateGlobalVariables(EST_Handle handle) { // get the speed estimate gMotorVars.Speed_krpm = EST_getSpeed_krpm(handle); // get the torque estimate { _iq Flux_pu = EST_getFlux_pu(handle); _iq Id_pu = PID_getFbackValue(pidHandle[1]); _iq Iq_pu = PID_getFbackValue(pidHandle[2]); _iq Ld_minus_Lq_pu = _IQ30toIQ(EST_getLs_d_pu(handle) - EST_getLs_q_pu(handle)); // Reactance Torque _iq Torque_Flux_Iq_Nm = _IQmpy(_IQmpy(Flux_pu,Iq_pu), gTorque_Flux_Iq_pu_to_Nm_sf); // Reluctance Torque _iq Torque_Ls_Id_Iq_Nm = _IQmpy(_IQmpy(_IQmpy(Ld_minus_Lq_pu,Id_pu), Iq_pu),gTorque_Ls_Id_Iq_pu_to_Nm_sf); // Total torque is sum of reactance torque and reluctance torque _iq Torque_Nm = Torque_Flux_Iq_Nm + Torque_Ls_Id_Iq_Nm; gMotorVars.Torque_Nm = Torque_Nm; } // get the magnetizing current gMotorVars.MagnCurr_A = EST_getIdRated(handle); // get the rotor resistance gMotorVars.Rr_Ohm = EST_getRr_Ohm(handle); // get the stator resistance gMotorVars.Rs_Ohm = EST_getRs_Ohm(handle); // get the stator inductance in the direct coordinate direction gMotorVars.Lsd_H = EST_getLs_d_H(handle); // get the stator inductance in the quadrature coordinate direction gMotorVars.Lsq_H = EST_getLs_q_H(handle); // get the flux in V/Hz in floating point gMotorVars.Flux_VpHz = EST_getFlux_VpHz(handle); // get the flux in Wb in fixed point gMotorVars.Flux_Wb = _IQmpy(EST_getFlux_pu(handle),gFlux_pu_to_Wb_sf); // get the estimator state gMotorVars.EstState = EST_getState(handle); // Get the DC buss voltage gMotorVars.VdcBus_kV = _IQmpy(gAdcData.dcBus, _IQ(USER_IQ_FULL_SCALE_VOLTAGE_V / 1000.0)); // read Vd and Vq vectors per units gMotorVars.Vd = gVdq_out_pu.value[0]; gMotorVars.Vq = gVdq_out_pu.value[1]; // calculate vector Vs in per units: (Vs = sqrt(Vd^2 + Vq^2)) gMotorVars.Vs = _IQsqrt(_IQmpy(gMotorVars.Vd,gMotorVars.Vd) + _IQmpy(gMotorVars.Vq,gMotorVars.Vq)); // read Id and Iq vectors in amps gMotorVars.Id_A = _IQmpy(gIdq_pu.value[0], _IQ(USER_IQ_FULL_SCALE_CURRENT_A)); gMotorVars.Iq_A = _IQmpy(gIdq_pu.value[1], _IQ(USER_IQ_FULL_SCALE_CURRENT_A)); // calculate vector Is in amps: (Is_A = sqrt(Id_A^2 + Iq_A^2)) gMotorVars.Is_A = _IQsqrt(_IQmpy(gMotorVars.Id_A,gMotorVars.Id_A) + _IQmpy(gMotorVars.Iq_A,gMotorVars.Iq_A)); return; } // end of updateGlobalVariables() function //@} //defgroup // end of file 1. In hal.h, I am added //Added extern interrupt void sciARxISR(void); static inline void HAL_initIntVectorTable(HAL_Handle handle) { .... //Added pie->SCIRXINTA = &sciARxISR; } //Added extern void HAL_setupSciA(HAL_Handle handle). //! \param[in] handle - the hardware abstraction (HAL) handle extern void HAL_enableSciInts(HAL_Handle handle); 2. In hal.c , i am added HAL_Handle HAL_init(void *pMemory,const size_t numBytes) { .... // Added obj->sciAHandle = SCI_init((void *)SCIA_BASE_ADDR,sizeof(SCI_Obj)); } void HAL_setParams(HAL_Handle handle,const USER_Params *pUserParams) { //Added // setup the sciA HAL_setupSciA(handle); } void HAL_setupGpios(HAL_Handle handle) { //Added // RX GPIO_setPullUp(obj->gpioHandle, GPIO_Number_28, GPIO_PullUp_Enable); GPIO_setQualification(obj->gpioHandle, GPIO_Number_28, GPIO_Qual_ASync); GPIO_setMode(obj->gpioHandle,GPIO_Number_28,GPIO_28_Mode_SCIRXDA); // TX GPIO_setPullUp(obj->gpioHandle, GPIO_Number_29, GPIO_PullUp_Enable); GPIO_setMode(obj->gpioHandle,GPIO_Number_29,GPIO_29_Mode_SCITXDA); } //Addedd void HAL_setupSciA(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *)handle; SCI_reset(obj->sciAHandle); SCI_enableTx(obj->sciAHandle); SCI_enableRx(obj->sciAHandle); SCI_disableParity(obj->sciAHandle); SCI_setNumStopBits(obj->sciAHandle,SCI_NumStopBits_One); SCI_setCharLength(obj->sciAHandle,SCI_CharLength_8_Bits); // set baud rate to 150000 SCI_setBaudRate(obj->sciAHandle,(SCI_BaudRate_e)(49)); SCI_setPriority(obj->sciAHandle,SCI_Priority_FreeRun); SCI_enable(obj->sciAHandle); return; // end of HAL_setupSciA() function } void HAL_enableSciInts(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; // enable the PIE interrupts associated with the SCI interrupts // enable SCIA RX interrupt in PIE PIE_enableInt(obj->pieHandle, PIE_GroupNumber_9, PIE_InterruptSource_SCIARX); // enable SCI RX interrupts // enable SCIA RX interrupt SCI_enableRxInt(obj->sciAHandle); // enable the cpu interrupt for SCI interrupts CPU_enableInt(obj->cpuHandle, CPU_IntNumber_9); } // end of HAL_enableSciInts() function 3. In hal.obj.h, I am added typedef struct _HAL_Obj_ { //Added SCI_Handle sciAHandle; } 4. In main.c, I am added /Added // enable the SCI interrupts HAL_enableSciInts(halHandle); I am working on Project 11, which utilizes SCI/UART functionality. However, I'm unable to run the motor using the commands provided. Could you please help me with this?.

Viewing all articles
Browse latest Browse all 218521

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>