MCU Code for FRDMKL25Z which works with Graphical User Interface available on Freescale website to control a brushed DC motor using FRDM-34931S-EVB / FRDM-34931-EVB / FRDM-33931-EVB. The code enables controlling the PWM frequency, duty cycle, enabling/disabling while monitoring status flag pin for undervoltge, short circuit and over-temperature events as well as real time load current for implementing advanced diagnostics.
Fork of Brushed_DC_Motor_Control_MC34931_MC33931 by
Import the program to your compiler window after logging in and complie to "main.cpp" file to generate the binary file "Brushed_DC_Motor_Control_MC34931_MC33931_KL25Z.bin" which can be flashed into the MBED drive on FRDM-KL25Z after upgrading the firmware.
main.cpp@0:f2f48fcea638, 2015-06-12 (annotated)
- Committer:
- pnandy
- Date:
- Fri Jun 12 17:51:20 2015 +0000
- Revision:
- 0:f2f48fcea638
Brushed DC Motor Control using MC34931/MC33931
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pnandy | 0:f2f48fcea638 | 1 | #include "mbed.h" |
pnandy | 0:f2f48fcea638 | 2 | #include "USBHID.h" |
pnandy | 0:f2f48fcea638 | 3 | |
pnandy | 0:f2f48fcea638 | 4 | // We declare a USBHID device. |
pnandy | 0:f2f48fcea638 | 5 | // HID In/Out Reports are 64 Bytes long |
pnandy | 0:f2f48fcea638 | 6 | // Vendor ID (VID): 0x15A2 |
pnandy | 0:f2f48fcea638 | 7 | // Product ID (PID): 0x0138 |
pnandy | 0:f2f48fcea638 | 8 | // Serial Number: 0x0001 |
pnandy | 0:f2f48fcea638 | 9 | USBHID hid(64, 64, 0x15A2, 0x0138, 0x0001, true); |
pnandy | 0:f2f48fcea638 | 10 | |
pnandy | 0:f2f48fcea638 | 11 | //Setup Digital Outputs for the LEDs on the FRDM |
pnandy | 0:f2f48fcea638 | 12 | //PwmOut red_led(LED1); |
pnandy | 0:f2f48fcea638 | 13 | //DigitalOut green_led(LED2); |
pnandy | 0:f2f48fcea638 | 14 | //DigitalOut blue_led(LED3); |
pnandy | 0:f2f48fcea638 | 15 | |
pnandy | 0:f2f48fcea638 | 16 | //Setup PWM and Digital Outputs from FRDM-KL25Z to FRDM-17510 |
pnandy | 0:f2f48fcea638 | 17 | PwmOut IN1(PTC8); // Pin IN1 input to MC34931 (FRDM PIN Name) |
pnandy | 0:f2f48fcea638 | 18 | PwmOut IN2 (PTA5); // Pin IN2 input to MC34931 (FRDM PIN Name) |
pnandy | 0:f2f48fcea638 | 19 | DigitalOut EN(PTE0); // Pin EN input to MC34931 (FRDM PIN Name) |
pnandy | 0:f2f48fcea638 | 20 | DigitalOut DIS(PTA2); // Pin D1 input to MC34931 (FRDM PIN Name) |
pnandy | 0:f2f48fcea638 | 21 | DigitalIn STATUS(PTB3); |
pnandy | 0:f2f48fcea638 | 22 | AnalogIn CFB(PTB0); |
pnandy | 0:f2f48fcea638 | 23 | //DigitalOut READY(PTC7); // Pin READY input to Motor Control Board (FRDM PIN Name) |
pnandy | 0:f2f48fcea638 | 24 | |
pnandy | 0:f2f48fcea638 | 25 | //Variables |
pnandy | 0:f2f48fcea638 | 26 | int pwm_freq_lo; |
pnandy | 0:f2f48fcea638 | 27 | int pwm_freq_hi; |
pnandy | 0:f2f48fcea638 | 28 | int frequencyHz = 500; |
pnandy | 0:f2f48fcea638 | 29 | int runstop = 0; |
pnandy | 0:f2f48fcea638 | 30 | int direction = 1; |
pnandy | 0:f2f48fcea638 | 31 | int braking; |
pnandy | 0:f2f48fcea638 | 32 | int dutycycle = 75; |
pnandy | 0:f2f48fcea638 | 33 | int newDataFlag = 0; |
pnandy | 0:f2f48fcea638 | 34 | int status = 0; |
pnandy | 0:f2f48fcea638 | 35 | uint16_t CurrFB; |
pnandy | 0:f2f48fcea638 | 36 | uint16_t CFBArray[101]; |
pnandy | 0:f2f48fcea638 | 37 | uint32_t CFBTotal; |
pnandy | 0:f2f48fcea638 | 38 | uint16_t CFBAvg; |
pnandy | 0:f2f48fcea638 | 39 | uint16_t CFBtemp; |
pnandy | 0:f2f48fcea638 | 40 | |
pnandy | 0:f2f48fcea638 | 41 | //storage for send and receive data |
pnandy | 0:f2f48fcea638 | 42 | HID_REPORT send_report; |
pnandy | 0:f2f48fcea638 | 43 | HID_REPORT recv_report; |
pnandy | 0:f2f48fcea638 | 44 | |
pnandy | 0:f2f48fcea638 | 45 | bool initflag = true; |
pnandy | 0:f2f48fcea638 | 46 | |
pnandy | 0:f2f48fcea638 | 47 | // USB COMMANDS |
pnandy | 0:f2f48fcea638 | 48 | // These are sent from the PC |
pnandy | 0:f2f48fcea638 | 49 | #define WRITE_LED 0x20 |
pnandy | 0:f2f48fcea638 | 50 | #define WRITE_GEN_EN 0x40 |
pnandy | 0:f2f48fcea638 | 51 | #define WRITE_DUTY_CYCLE 0x50 |
pnandy | 0:f2f48fcea638 | 52 | #define WRITE_PWM_FREQ 0x60 |
pnandy | 0:f2f48fcea638 | 53 | #define WRITE_RUN_STOP 0x70 |
pnandy | 0:f2f48fcea638 | 54 | #define WRITE_DIRECTION 0x71 |
pnandy | 0:f2f48fcea638 | 55 | #define WRITE_BRAKING 0x90 |
pnandy | 0:f2f48fcea638 | 56 | #define WRITE_RESET 0xA0 |
pnandy | 0:f2f48fcea638 | 57 | #define WRITE_D1 0xB1 |
pnandy | 0:f2f48fcea638 | 58 | #define WRITE_D2_B 0xC1 |
pnandy | 0:f2f48fcea638 | 59 | |
pnandy | 0:f2f48fcea638 | 60 | #define scaleFactor 0.11868 |
pnandy | 0:f2f48fcea638 | 61 | |
pnandy | 0:f2f48fcea638 | 62 | // LOGICAL CONSTANTS |
pnandy | 0:f2f48fcea638 | 63 | #define OFF 0x00 |
pnandy | 0:f2f48fcea638 | 64 | #define ON 0x01 |
pnandy | 0:f2f48fcea638 | 65 | |
pnandy | 0:f2f48fcea638 | 66 | |
pnandy | 0:f2f48fcea638 | 67 | int main() |
pnandy | 0:f2f48fcea638 | 68 | { |
pnandy | 0:f2f48fcea638 | 69 | send_report.length = 64; |
pnandy | 0:f2f48fcea638 | 70 | recv_report.length = 64; |
pnandy | 0:f2f48fcea638 | 71 | |
pnandy | 0:f2f48fcea638 | 72 | |
pnandy | 0:f2f48fcea638 | 73 | while(1) |
pnandy | 0:f2f48fcea638 | 74 | { |
pnandy | 0:f2f48fcea638 | 75 | //try to read a msg |
pnandy | 0:f2f48fcea638 | 76 | if(hid.readNB(&recv_report)) |
pnandy | 0:f2f48fcea638 | 77 | { |
pnandy | 0:f2f48fcea638 | 78 | switch(recv_report.data[0]) //byte 0 of recv_report.data is command |
pnandy | 0:f2f48fcea638 | 79 | { |
pnandy | 0:f2f48fcea638 | 80 | //----------------------------------------------------------------------------------------------------------------- |
pnandy | 0:f2f48fcea638 | 81 | // COMMAND PARSER |
pnandy | 0:f2f48fcea638 | 82 | //----------------------------------------------------------------------------------------------------------------- |
pnandy | 0:f2f48fcea638 | 83 | //////// |
pnandy | 0:f2f48fcea638 | 84 | case WRITE_LED: |
pnandy | 0:f2f48fcea638 | 85 | break; |
pnandy | 0:f2f48fcea638 | 86 | //////// |
pnandy | 0:f2f48fcea638 | 87 | |
pnandy | 0:f2f48fcea638 | 88 | //////// |
pnandy | 0:f2f48fcea638 | 89 | case WRITE_DUTY_CYCLE: |
pnandy | 0:f2f48fcea638 | 90 | dutycycle = recv_report.data[1]; |
pnandy | 0:f2f48fcea638 | 91 | newDataFlag = 1; |
pnandy | 0:f2f48fcea638 | 92 | break; |
pnandy | 0:f2f48fcea638 | 93 | //////// |
pnandy | 0:f2f48fcea638 | 94 | case WRITE_PWM_FREQ: //PWM frequency can be larger than 1 byte |
pnandy | 0:f2f48fcea638 | 95 | pwm_freq_lo = recv_report.data[1]; //so we have to re-assemble the number |
pnandy | 0:f2f48fcea638 | 96 | pwm_freq_hi = recv_report.data[2] * 100; |
pnandy | 0:f2f48fcea638 | 97 | frequencyHz = pwm_freq_lo + pwm_freq_hi; |
pnandy | 0:f2f48fcea638 | 98 | newDataFlag = 1; |
pnandy | 0:f2f48fcea638 | 99 | break; |
pnandy | 0:f2f48fcea638 | 100 | //////// |
pnandy | 0:f2f48fcea638 | 101 | case WRITE_RUN_STOP: |
pnandy | 0:f2f48fcea638 | 102 | newDataFlag = 1; |
pnandy | 0:f2f48fcea638 | 103 | if(recv_report.data[1] != 0) |
pnandy | 0:f2f48fcea638 | 104 | { |
pnandy | 0:f2f48fcea638 | 105 | runstop = 1; |
pnandy | 0:f2f48fcea638 | 106 | } |
pnandy | 0:f2f48fcea638 | 107 | else |
pnandy | 0:f2f48fcea638 | 108 | { |
pnandy | 0:f2f48fcea638 | 109 | runstop = 0; |
pnandy | 0:f2f48fcea638 | 110 | } |
pnandy | 0:f2f48fcea638 | 111 | break; |
pnandy | 0:f2f48fcea638 | 112 | |
pnandy | 0:f2f48fcea638 | 113 | //////// |
pnandy | 0:f2f48fcea638 | 114 | case WRITE_DIRECTION: |
pnandy | 0:f2f48fcea638 | 115 | newDataFlag = 1; |
pnandy | 0:f2f48fcea638 | 116 | |
pnandy | 0:f2f48fcea638 | 117 | if(recv_report.data[1] != 0) |
pnandy | 0:f2f48fcea638 | 118 | { |
pnandy | 0:f2f48fcea638 | 119 | direction = 1; |
pnandy | 0:f2f48fcea638 | 120 | } |
pnandy | 0:f2f48fcea638 | 121 | else |
pnandy | 0:f2f48fcea638 | 122 | { |
pnandy | 0:f2f48fcea638 | 123 | direction = 0; |
pnandy | 0:f2f48fcea638 | 124 | } |
pnandy | 0:f2f48fcea638 | 125 | break; |
pnandy | 0:f2f48fcea638 | 126 | //////// |
pnandy | 0:f2f48fcea638 | 127 | case WRITE_BRAKING: |
pnandy | 0:f2f48fcea638 | 128 | newDataFlag = 1; |
pnandy | 0:f2f48fcea638 | 129 | if(recv_report.data[1] == 1) |
pnandy | 0:f2f48fcea638 | 130 | { |
pnandy | 0:f2f48fcea638 | 131 | braking = 1; |
pnandy | 0:f2f48fcea638 | 132 | } |
pnandy | 0:f2f48fcea638 | 133 | else |
pnandy | 0:f2f48fcea638 | 134 | { |
pnandy | 0:f2f48fcea638 | 135 | braking = 0; |
pnandy | 0:f2f48fcea638 | 136 | } |
pnandy | 0:f2f48fcea638 | 137 | break; |
pnandy | 0:f2f48fcea638 | 138 | //////// |
pnandy | 0:f2f48fcea638 | 139 | case WRITE_D1: |
pnandy | 0:f2f48fcea638 | 140 | newDataFlag = 1; |
pnandy | 0:f2f48fcea638 | 141 | if(recv_report.data[1] == 1) |
pnandy | 0:f2f48fcea638 | 142 | { |
pnandy | 0:f2f48fcea638 | 143 | DIS = 1; |
pnandy | 0:f2f48fcea638 | 144 | } |
pnandy | 0:f2f48fcea638 | 145 | else |
pnandy | 0:f2f48fcea638 | 146 | { |
pnandy | 0:f2f48fcea638 | 147 | DIS = 0; |
pnandy | 0:f2f48fcea638 | 148 | } |
pnandy | 0:f2f48fcea638 | 149 | break; |
pnandy | 0:f2f48fcea638 | 150 | //////// |
pnandy | 0:f2f48fcea638 | 151 | case WRITE_D2_B: |
pnandy | 0:f2f48fcea638 | 152 | newDataFlag = 1; |
pnandy | 0:f2f48fcea638 | 153 | if(recv_report.data[1] == 1) |
pnandy | 0:f2f48fcea638 | 154 | { |
pnandy | 0:f2f48fcea638 | 155 | EN = 0; |
pnandy | 0:f2f48fcea638 | 156 | } |
pnandy | 0:f2f48fcea638 | 157 | else |
pnandy | 0:f2f48fcea638 | 158 | { |
pnandy | 0:f2f48fcea638 | 159 | EN = 1; |
pnandy | 0:f2f48fcea638 | 160 | } |
pnandy | 0:f2f48fcea638 | 161 | break; |
pnandy | 0:f2f48fcea638 | 162 | |
pnandy | 0:f2f48fcea638 | 163 | //////// |
pnandy | 0:f2f48fcea638 | 164 | default: |
pnandy | 0:f2f48fcea638 | 165 | break; |
pnandy | 0:f2f48fcea638 | 166 | }// End Switch recv report data[0] |
pnandy | 0:f2f48fcea638 | 167 | |
pnandy | 0:f2f48fcea638 | 168 | //----------------------------------------------------------------------------------------------------------------- |
pnandy | 0:f2f48fcea638 | 169 | // end command parser |
pnandy | 0:f2f48fcea638 | 170 | //----------------------------------------------------------------------------------------------------------------- |
pnandy | 0:f2f48fcea638 | 171 | |
pnandy | 0:f2f48fcea638 | 172 | status = STATUS; |
pnandy | 0:f2f48fcea638 | 173 | send_report.data[0] = status; // Echo Command |
pnandy | 0:f2f48fcea638 | 174 | send_report.data[1] = recv_report.data[1]; // Echo Subcommand 1 |
pnandy | 0:f2f48fcea638 | 175 | send_report.data[2] = recv_report.data[2]; // Echo Subcommand 2 |
pnandy | 0:f2f48fcea638 | 176 | send_report.data[3] = 0x00; |
pnandy | 0:f2f48fcea638 | 177 | send_report.data[4] = 0x00; |
pnandy | 0:f2f48fcea638 | 178 | send_report.data[5] = 0x00; |
pnandy | 0:f2f48fcea638 | 179 | send_report.data[6] = (CFBAvg << 8) >> 8; |
pnandy | 0:f2f48fcea638 | 180 | send_report.data[7] = CFBAvg >> 8; |
pnandy | 0:f2f48fcea638 | 181 | |
pnandy | 0:f2f48fcea638 | 182 | //Send the report |
pnandy | 0:f2f48fcea638 | 183 | hid.send(&send_report); |
pnandy | 0:f2f48fcea638 | 184 | }// End If(hid.readNB(&recv_report)) |
pnandy | 0:f2f48fcea638 | 185 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
pnandy | 0:f2f48fcea638 | 186 | //End of USB message handling |
pnandy | 0:f2f48fcea638 | 187 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
pnandy | 0:f2f48fcea638 | 188 | |
pnandy | 0:f2f48fcea638 | 189 | CurrFB = CFB.read_u16(); |
pnandy | 0:f2f48fcea638 | 190 | CFBArray[0] = CurrFB; |
pnandy | 0:f2f48fcea638 | 191 | CFBTotal = 0; |
pnandy | 0:f2f48fcea638 | 192 | int i = 0; |
pnandy | 0:f2f48fcea638 | 193 | for(i=0; i<100; i++) |
pnandy | 0:f2f48fcea638 | 194 | { |
pnandy | 0:f2f48fcea638 | 195 | CFBTotal = CFBTotal + CFBArray[i]; |
pnandy | 0:f2f48fcea638 | 196 | } |
pnandy | 0:f2f48fcea638 | 197 | CFBAvg = CFBTotal / 100; |
pnandy | 0:f2f48fcea638 | 198 | |
pnandy | 0:f2f48fcea638 | 199 | for(i=100; i>=0; i--) |
pnandy | 0:f2f48fcea638 | 200 | { |
pnandy | 0:f2f48fcea638 | 201 | |
pnandy | 0:f2f48fcea638 | 202 | CFBArray[i+1] = CFBArray[i]; |
pnandy | 0:f2f48fcea638 | 203 | } |
pnandy | 0:f2f48fcea638 | 204 | |
pnandy | 0:f2f48fcea638 | 205 | if(newDataFlag != 0) //GUI setting changed |
pnandy | 0:f2f48fcea638 | 206 | { |
pnandy | 0:f2f48fcea638 | 207 | newDataFlag = 0; |
pnandy | 0:f2f48fcea638 | 208 | if(runstop != 0) //Running |
pnandy | 0:f2f48fcea638 | 209 | { |
pnandy | 0:f2f48fcea638 | 210 | if(direction == 0) //reverse |
pnandy | 0:f2f48fcea638 | 211 | { |
pnandy | 0:f2f48fcea638 | 212 | if(braking == 1) //dynamic |
pnandy | 0:f2f48fcea638 | 213 | { |
pnandy | 0:f2f48fcea638 | 214 | IN1.period(1/(float)frequencyHz); |
pnandy | 0:f2f48fcea638 | 215 | IN1 = (float)dutycycle/100.0; |
pnandy | 0:f2f48fcea638 | 216 | IN2 = 1; |
pnandy | 0:f2f48fcea638 | 217 | } |
pnandy | 0:f2f48fcea638 | 218 | else //coast |
pnandy | 0:f2f48fcea638 | 219 | { |
pnandy | 0:f2f48fcea638 | 220 | IN1 = 0; |
pnandy | 0:f2f48fcea638 | 221 | IN2.period(1/(float)frequencyHz); |
pnandy | 0:f2f48fcea638 | 222 | IN2 = (float)dutycycle/100.0; |
pnandy | 0:f2f48fcea638 | 223 | } |
pnandy | 0:f2f48fcea638 | 224 | } |
pnandy | 0:f2f48fcea638 | 225 | else //forward |
pnandy | 0:f2f48fcea638 | 226 | { |
pnandy | 0:f2f48fcea638 | 227 | if(braking == 1) //dynamic |
pnandy | 0:f2f48fcea638 | 228 | { |
pnandy | 0:f2f48fcea638 | 229 | IN1 = 1; |
pnandy | 0:f2f48fcea638 | 230 | IN2.period(1/(float)frequencyHz); |
pnandy | 0:f2f48fcea638 | 231 | IN2 = (float)dutycycle/100.0; |
pnandy | 0:f2f48fcea638 | 232 | } |
pnandy | 0:f2f48fcea638 | 233 | else //coast |
pnandy | 0:f2f48fcea638 | 234 | { |
pnandy | 0:f2f48fcea638 | 235 | IN1.period(1/(float)frequencyHz); |
pnandy | 0:f2f48fcea638 | 236 | IN1 = (float)dutycycle/100.0; |
pnandy | 0:f2f48fcea638 | 237 | IN2 = 0; |
pnandy | 0:f2f48fcea638 | 238 | } |
pnandy | 0:f2f48fcea638 | 239 | } |
pnandy | 0:f2f48fcea638 | 240 | } |
pnandy | 0:f2f48fcea638 | 241 | else //Stopped |
pnandy | 0:f2f48fcea638 | 242 | { |
pnandy | 0:f2f48fcea638 | 243 | if(braking == 1) //braking |
pnandy | 0:f2f48fcea638 | 244 | { |
pnandy | 0:f2f48fcea638 | 245 | IN1.period(1); |
pnandy | 0:f2f48fcea638 | 246 | IN2.period(1); |
pnandy | 0:f2f48fcea638 | 247 | IN1.write(1); |
pnandy | 0:f2f48fcea638 | 248 | IN2.write(1); |
pnandy | 0:f2f48fcea638 | 249 | } |
pnandy | 0:f2f48fcea638 | 250 | else //coasting |
pnandy | 0:f2f48fcea638 | 251 | { |
pnandy | 0:f2f48fcea638 | 252 | IN1.period(1); |
pnandy | 0:f2f48fcea638 | 253 | IN2.period(1); |
pnandy | 0:f2f48fcea638 | 254 | IN1.write(0); |
pnandy | 0:f2f48fcea638 | 255 | IN2.write(0); |
pnandy | 0:f2f48fcea638 | 256 | |
pnandy | 0:f2f48fcea638 | 257 | } |
pnandy | 0:f2f48fcea638 | 258 | } |
pnandy | 0:f2f48fcea638 | 259 | } |
pnandy | 0:f2f48fcea638 | 260 | } |
pnandy | 0:f2f48fcea638 | 261 | } |