Firmware for MC33926 evaluation on KL25Z-based EVB. This works with a Graphical User Interface (GUI) available on NXP.com to control a brushed DC motor using FRDM-33926ESEVM or FRDM-33926PNBEVM. The code enables control of the PWM frequency, duty cycle, enable/disable controls, invert, slew rate control, real-time current monitoring, and includes status flag pin monitoring for undervoltage, short circuit and over-temperature events.
Fork of Brushed_DC_Motor_Control_MC33926 by
main_copy.cpp
- Committer:
- nxf42866
- Date:
- 2018-07-09
- Revision:
- 2:d98eb31a4b69
File content as of revision 2:d98eb31a4b69:
#include "mbed.h" #include "USBHID.h" // We declare a USBHID device. // HID In/Out Reports are 64 Bytes long // Vendor ID (VID): 0x15A2 // Product ID (PID): 0x0138 // Serial Number: 0x0001 USBHID hid(64, 64, 0x15A2, 0x0138, 0x0001, true); //Setup Digital Outputs for the LEDs on the FRDM //PwmOut red_led(LED1); //DigitalOut green_led(LED2); //DigitalOut blue_led(LED3); //Setup PWM and Digital Outputs from FRDM-KL25Z to FRDM-17510 PwmOut IN1(PTA5); // Pin IN1 input to MC33926 (FRDM PIN Name) PwmOut IN2(PTC8); // Pin IN2 input to MC33926 (FRDM PIN Name) DigitalOut EN(PTE0); // Pin EN input to MC33926 (FRDM PIN Name) DigitalOut DIS1(PTA2); // Pin D1 input to MC33926 (FRDM PIN Name) DigitalOut D2B(PTD5); // Pin D2B input to MC33926 (FRDM PIN Name) DigitalOut SLEW(PTA13); // Pin Slew input to MC33926 (FRDM PIN Name) DigitalOut INV(PTD0); // Pin INV input to MC33926 (FRDM PIN Name) DigitalIn SFB(PTB3); // Pin SF_B output from MC33926 to FRDM-KL25Z AnalogIn CFB(PTB0); // Pin FB output from MC33926 to FRDM-KL25Z //DigitalOut READY(PTC7); // Pin READY input to Motor Control Board (FRDM PIN Name) //Variables int pwm_freq_lo; int pwm_freq_hi; int frequencyHz = 500; int runstop = 0; int direction = 1; int braking; // needs to be initialized? int dutycycle = 75; int newDataFlag = 0; int status = 0; uint16_t CurrFB; uint16_t CFBArray[101]; uint32_t CFBTotal; uint16_t CFBAvg; uint16_t CFBtemp; //storage for send and receive data HID_REPORT send_report; HID_REPORT recv_report; bool initflag = true; // USB COMMANDS // These are sent from the PC #define WRITE_LED 0x20 #define WRITE_GEN_EN 0x40 // what is this? What should the GUI kickoff here? #define WRITE_DUTY_CYCLE 0x50 #define WRITE_PWM_FREQ 0x60 #define WRITE_RUN_STOP 0x70 #define WRITE_DIRECTION 0x71 #define WRITE_BRAKING 0x90 #define WRITE_RESET 0xA0 // what is this? What should the GUI kickoff here? #define WRITE_D1 0xB1 #define WRITE_EN 0xC1 #define WRITE_D2B 0xD5 #define WRITE_SLEW 0xE5 #define WRITE_INV 0xF5 #define scaleFactor 0.11868 // LOGICAL CONSTANTS #define OFF 0x00 #define ON 0x01 int main() { send_report.length = 64; recv_report.length = 64; while(1) { //try to read a msg if(hid.readNB(&recv_report)) { switch(recv_report.data[0]) //byte 0 of recv_report.data is command { //----------------------------------------------------------------------------------------------------------------- // COMMAND PARSER //----------------------------------------------------------------------------------------------------------------- //////// case WRITE_LED: break; //////// //////// case WRITE_DUTY_CYCLE: dutycycle = recv_report.data[1]; newDataFlag = 1; break; //////// case WRITE_PWM_FREQ: //PWM frequency can be larger than 1 byte pwm_freq_lo = recv_report.data[1]; //so we have to re-assemble the number pwm_freq_hi = recv_report.data[2] * 100; frequencyHz = pwm_freq_lo + pwm_freq_hi; newDataFlag = 1; break; //////// case WRITE_RUN_STOP: newDataFlag = 1; if(recv_report.data[1] != 0) { runstop = 1; } else { runstop = 0; } break; //////// case WRITE_DIRECTION: newDataFlag = 1; if(recv_report.data[1] == 1) // used to be != 0 { direction = 1; // corrected allocation for FWD //direction = 0; // corrected allocation for REV } else { direction = 0; // corrected allocation for REV //direction = 1; // corrected allocation for FWD } break; //////// case WRITE_BRAKING: newDataFlag = 1; if(recv_report.data[1] != 0) // used to be == 1 { braking = 1; // this is HS recirc } else { braking = 0; // this is LS recirc } break; //////// case WRITE_D1: newDataFlag = 1; if(recv_report.data[1] == 1) { DIS1 = 1; // logic hi will disable the part } else { DIS1 = 0; // logic lo will enable the part } break; //////// case WRITE_EN: newDataFlag = 1; if(recv_report.data[1] == 1) { //EN = 0; // this is enable case EN = 1; // align with the signal being sent from GUI } else { //EN = 1; // this is disable case EN = 0; // align with signal being sent from GUI } break; //////// case WRITE_D2B: newDataFlag = 1; if(recv_report.data[1] == 1) { D2B = 1; } else { D2B = 0; } break; //////// case WRITE_SLEW: newDataFlag = 1; if(recv_report.data[1] == 1) { SLEW = 1; } else { SLEW = 0; } break; //////// case WRITE_INV: newDataFlag = 1; if(recv_report.data[1] == 1) { INV = 1; //INV = 0; } else { INV = 0; //INV = 1; } break; //////// default: break; }// End Switch recv report data[0] //----------------------------------------------------------------------------------------------------------------- // end command parser //----------------------------------------------------------------------------------------------------------------- status = SFB; send_report.data[0] = status; // Echo Command send_report.data[1] = recv_report.data[1]; // Echo Subcommand 1 send_report.data[2] = recv_report.data[2]; // Echo Subcommand 2 send_report.data[3] = 0x00; send_report.data[4] = 0x00; send_report.data[5] = 0x00; send_report.data[6] = (CFBAvg << 8) >> 8; send_report.data[7] = CFBAvg >> 8; //Send the report hid.send(&send_report); }// End If(hid.readNB(&recv_report)) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //End of USB message handling ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// CurrFB = CFB.read_u16(); CFBArray[0] = CurrFB; CFBTotal = 0; int i = 0; for(i=0; i<100; i++) { CFBTotal = CFBTotal + CFBArray[i]; } CFBAvg = CFBTotal / 100; for(i=100; i>=0; i--) { CFBArray[i+1] = CFBArray[i]; } if(newDataFlag != 0) //GUI setting changed { newDataFlag = 0; if(runstop != 0) //Running { if(direction == 0) //reverse { if(braking == 1) //dynamic { IN1.period(1/(float)frequencyHz); //IN1 = (float)dutycycle/100.0; // this is REV + HS, inverted d IN1 = 1.0-((float)dutycycle/100.0); // this is REV + HS IN2 = 1; } else //coast { IN1 = 0; // this is REV + LS IN2.period(1/(float)frequencyHz); IN2 = (float)dutycycle/100.0; } } else //forward { if(braking == 1) //dynamic { IN1 = 1; IN2.period(1/(float)frequencyHz); //IN2 = (float)dutycycle/100.0; // this is FWD + HS, inverted d IN2 = 1.0-((float)dutycycle/100.0); // this is FWD + HS } else //coast { IN1.period(1/(float)frequencyHz); IN1 = (float)dutycycle/100.0; IN2 = 0; // FWD + LS } } } else //Stopped { if(braking == 1) //braking { IN1.period(1); IN2.period(1); IN1.write(1); IN2.write(1); } else //coasting { IN1.period(1); IN2.period(1); IN1.write(0); IN2.write(0); } } } } }