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
Revision 2:d98eb31a4b69, committed 2018-07-09
- Comitter:
- nxf42866
- Date:
- Mon Jul 09 17:53:48 2018 +0000
- Parent:
- 1:52d7baa4af71
- Child:
- 3:d7fd752817e1
- Commit message:
- New firmware for evaluation of MC33926 on KL25Z-based EVB
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
main_copy.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Fri Jun 12 17:52:57 2015 +0000 +++ b/main.cpp Mon Jul 09 17:53:48 2018 +0000 @@ -14,12 +14,15 @@ //DigitalOut blue_led(LED3); //Setup PWM and Digital Outputs from FRDM-KL25Z to FRDM-17510 -PwmOut IN1(PTC8); // Pin IN1 input to MC34931 (FRDM PIN Name) -PwmOut IN2 (PTA5); // Pin IN2 input to MC34931 (FRDM PIN Name) -DigitalOut EN(PTE0); // Pin EN input to MC34931 (FRDM PIN Name) -DigitalOut DIS(PTA2); // Pin D1 input to MC34931 (FRDM PIN Name) -DigitalIn STATUS(PTB3); -AnalogIn CFB(PTB0); +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 @@ -28,7 +31,7 @@ int frequencyHz = 500; int runstop = 0; int direction = 1; -int braking; +int braking; // needs to be initialized? int dutycycle = 75; int newDataFlag = 0; int status = 0; @@ -46,16 +49,19 @@ // USB COMMANDS // These are sent from the PC -#define WRITE_LED 0x20 -#define WRITE_GEN_EN 0x40 +#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 +#define WRITE_RESET 0xA0 // what is this? What should the GUI kickoff here? #define WRITE_D1 0xB1 -#define WRITE_D2_B 0xC1 +#define WRITE_EN 0xC1 +#define WRITE_D2B 0xD5 +#define WRITE_SLEW 0xE5 +#define WRITE_INV 0xF5 #define scaleFactor 0.11868 @@ -113,26 +119,27 @@ //////// case WRITE_DIRECTION: newDataFlag = 1; - - if(recv_report.data[1] != 0) + if(recv_report.data[1] == 1) // used to be != 0 { - direction = 1; + direction = 1; // corrected allocation for FWD + //direction = 0; // corrected allocation for REV } else { - direction = 0; + direction = 0; // corrected allocation for REV + //direction = 1; // corrected allocation for FWD } break; //////// case WRITE_BRAKING: newDataFlag = 1; - if(recv_report.data[1] == 1) + if(recv_report.data[1] != 0) // used to be == 1 { - braking = 1; + braking = 1; // this is HS recirc } else { - braking = 0; + braking = 0; // this is LS recirc } break; //////// @@ -140,25 +147,68 @@ newDataFlag = 1; if(recv_report.data[1] == 1) { - DIS = 1; + DIS1 = 1; // logic hi will disable the part } else { - DIS = 0; + 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_D2_B: - newDataFlag = 1; + case WRITE_D2B: + newDataFlag = 1; if(recv_report.data[1] == 1) { - EN = 0; + D2B = 1; } else { - EN = 1; + D2B = 0; + } + break; + +//////// + case WRITE_SLEW: + newDataFlag = 1; + if(recv_report.data[1] == 1) + { + SLEW = 1; + } + else + { + SLEW = 0; } - break; + break; + +//////// + case WRITE_INV: + newDataFlag = 1; + if(recv_report.data[1] == 1) + { + INV = 1; + //INV = 0; + } + else + { + INV = 0; + //INV = 1; + } + break; + //////// default: @@ -169,7 +219,7 @@ // end command parser //----------------------------------------------------------------------------------------------------------------- - status = STATUS; + 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 @@ -212,12 +262,13 @@ if(braking == 1) //dynamic { IN1.period(1/(float)frequencyHz); - IN1 = (float)dutycycle/100.0; + //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; + IN1 = 0; // this is REV + LS IN2.period(1/(float)frequencyHz); IN2 = (float)dutycycle/100.0; } @@ -226,15 +277,16 @@ { if(braking == 1) //dynamic { - IN1 = 1; + IN1 = 1; IN2.period(1/(float)frequencyHz); - IN2 = (float)dutycycle/100.0; + //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; + IN2 = 0; // FWD + LS } } } @@ -259,3 +311,4 @@ } } } +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_copy.cpp Mon Jul 09 17:53:48 2018 +0000 @@ -0,0 +1,314 @@ +#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); + + } + } + } + } +} +