Motor Evaluation Kit NEVC-MCTRL-100-t01-1.0.0
Firmware for NEVB-MCTRL-100-01 for trapezoidal control of BLDC motors using Hall-effect sensors
|
Motor control implementation. More...
#include <Arduino.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdint.h>
#include "main.h"
#include "tables.h"
#include "fault.h"
#include "scpi.h"
#include "filter.h"
Go to the source code of this file.
Macros | |
#define | __AVR_ATmega32U4__ 1 |
Define macro for ATmega32U4 micro controller. | |
Functions | |
void | setup (void) |
Main initialization function. | |
void | loop () |
Main Loop Function. | |
static void | FlagsInit (void) |
Initializes motorFlags and faultFlags. | |
static void | ConfigsInit (void) |
Initializes motorConfigs. | |
static void | PLLInit (void) |
Initialize PLL (Phase-Locked Loop) | |
static void | PortsInit (void) |
Initialize I/O port directions and pull-up resistors. | |
void | TimersInit (void) |
Initializes and synchronizes Timers. | |
static void | PinChangeIntInit (void) |
Initialize pin change interrupts. | |
static void | ADCInit (void) |
Initializes the ADC. | |
static uint16_t | ADCSingleConversion (void) |
Perform a single ADC conversion. | |
static void | EnableUpdate (void) |
Check whether the enable pin is set and update flags accordingly. | |
static void | RemoteUpdate (void) |
Check whether the remote pin is set and update flags accordingly. | |
static void | SpeedController (void) |
Speed regulator loop. | |
static void | FatalError (uint8_t code) |
Handle a fatal error and enter a fault state. | |
static void | SetDuty (const uint16_t duty) |
Set duty cycle for TIM4. | |
static void | TimersSetModeBlockCommutation (void) |
Configures timers for block commutation. | |
static void | TimersWaitForNextPWMCycle (void) |
Wait for the start of the next PWM cycle. | |
static uint8_t | GetDesiredDirection (void) |
Retrieve the intended motor direction. | |
static uint8_t | GetActualDirection (void) |
Retrieve the current motor direction. | |
static void | BlockCommutate (const uint8_t direction, uint8_t hall) |
Perform block commutation based on direction and hall sensor input. | |
static uint8_t | GetHall (void) |
Read the hall sensor inputs and decode the hall state. | |
static void | DesiredDirectionUpdate (void) |
Updates global desired direction flag. | |
static void | ActualDirectionUpdate (uint8_t lastHall, const uint8_t newHall) |
Update the global actual direction flag based on the two latest hall values. | |
static void | ReverseRotationSignalUpdate (void) |
Update the reverse rotation flag. | |
static void | EnablePWMOutputs (void) |
Enable PWM output pins. | |
static void | DisablePWMOutputs (void) |
Disable PWM output pins. | |
static void | ClearPWMPorts (void) |
Clear PWM output ports. | |
static void | CommutationTicksUpdate (void) |
Update the 'tick' counter and check for a stopped motor. | |
ISR (INT0_vect) | |
Enable interrupt service routine. | |
ISR (PCINT0_vect) | |
Hall sensor change interrupt service routine. | |
ISR (INT2_vect) | |
Direction input change interrupt service routine. | |
ISR (TIMER4_OVF_vect) | |
Timer4 Overflow Event Interrupt Service Routine. | |
ISR (TIMER1_OVF_vect) | |
Timer1 Overflow Interrupt Service Routine. | |
ISR (ADC_vect) | |
ADC Conversion Complete Interrupt Service Routine. | |
Variables | |
volatile motorflags_t | motorFlags |
Motor control flags placed in I/O space for fast access. | |
volatile faultflags_t | faultFlags |
Fault flags placed in I/O space for fast access. | |
volatile motorconfigs_t | motorConfigs |
Motor Configs. | |
volatile uint16_t | commutationTicks = 0 |
The number of 'ticks' between two hall sensor changes (counter). | |
volatile uint16_t | lastCommutationTicks = 0xffff |
The number of 'ticks' between two hall sensor changes (store). | |
volatile uint8_t | speedInput = 0 |
The most recent "speed" input measurement. | |
volatile uint8_t | speedOutput = 0 |
The most recent "speed" output from the speed controller. | |
volatile uint16_t | current = 0 |
Current measurement (Register Value). | |
volatile uint16_t | gateVref = 0 |
Gate voltage measurement (Register Value) | |
char | incoming_byte = 0 |
Buffer for incoming serial data. | |
Motor control implementation.
This file contains the full implementation of the motor control, except the PID-controller, filter, fault, SCPI and table implementations and definitions.
Definition in file main.ino.
#define __AVR_ATmega32U4__ 1 |
|
static |
Update the global actual direction flag based on the two latest hall values.
Calling this function with the last two hall sensor values as parameters triggers an update of the global actualDirection flag.
lastHall | The previous hall sensor value. |
newHall | The current hall sensor value. |
Definition at line 982 of file main.ino.
|
static |
Initializes the ADC.
This function initializes the ADC for speed reference, current and gate voltage measurements.
The function performs self-tests to ensure the ADC's accuracy:
If any of the self-tests fail, a fatal error is indicated.
After self-testing, the ADC is configured for speed reference measurements and set to trigger on ADC_TRIGGER.
Definition at line 481 of file main.ino.
|
static |
Perform a single ADC conversion.
This function initiates a single ADC conversion to measure a voltage. It waits for the conversion to complete and then reads the ADC result.
Definition at line 561 of file main.ino.
|
static |
Perform block commutation based on direction and hall sensor input.
This function performs block commutation according to the specified direction of rotation and the hall sensor input. Block commutation is used to control motor phases during operation.
direction | Direction of rotation (DIRECTION_FORWARD or DIRECTION_REVERSE). |
hall | Hall sensor input value corresponding to the rotor position. |
Definition at line 908 of file main.ino.
|
static |
Clear PWM output ports.
This function clears the PWM output ports by setting the corresponding bits of the port registers to low. It effectively turns off the PWM signals on the specified ports while leaving the port directions unchanged.
Definition at line 1054 of file main.ino.
|
static |
Update the 'tick' counter and check for a stopped motor.
This function should be called at every PWM timer overflow to update the 'tick' counter. It increments the 'tick' counter until it reaches the maximum tick limit, indicating a potentially stopped or stalled motor. If the limit is reached, the global motor stopped flag is set.
Definition at line 1076 of file main.ino.
|
static |
Initializes motorConfigs.
This function initializes motorConfigs to their default values.
Definition at line 320 of file main.ino.
|
static |
Updates global desired direction flag.
Running this function triggers a reading of the direction input pin. The desiredDirection flag is set accordingly.
Definition at line 961 of file main.ino.
|
static |
Disable PWM output pins.
This function disables PWM outputs by setting the port direction for all PWM pins as inputs. This action overrides the PWM signals, effectively stopping the generation of PWM. The PWM configuration itself remains unchanged.
Definition at line 1041 of file main.ino.
|
static |
Enable PWM output pins.
This function sets the port direction for all PWM pins as output, allowing PWM signals to be generated on these pins. It does not modify the PWM configuration itself.
Definition at line 1028 of file main.ino.
|
static |
Check whether the enable pin is set and update flags accordingly.
This function checks the state of the enable pin and updates the motorFlags and faultFlags accordingly. If the enable pin is not set, it can perform specific actions based on the TURN_OFF_MODE configuration:
Definition at line 594 of file main.ino.
|
static |
Handle a fatal error and enter a fault state.
This function is called in response to a fatal error condition. It performs the following actions:
code | The error code indicating the nature of the fatal error. Each bit of the code corresponds to a specific fault condition: - Bit 0: User Flag 3 - Bit 1: User Flag 2 - Bit 2: User Flag 1 - Bit 3: Reverse Direction - Bit 4: Motor Stopped - Bit 5: Over Current - Bit 6: No Hall Connections |
Definition at line 728 of file main.ino.
|
static |
Initializes motorFlags and faultFlags.
This function initializes both motorFlags and faultFlags to their default values.
Definition at line 294 of file main.ino.
|
static |
Retrieve the current motor direction.
This function returns the current operating direction of the motor.
DIRECTION_FORWARD | Motor is currently running forward. |
DIRECTION_REVERSE | Motor is currently running in reverse. |
DIRECTION_UNKNOWN | The current motor direction cannot be determined, which may indicate the motor is stopped, changing direction, or that the hall sensors are providing incorrect information. |
Definition at line 893 of file main.ino.
|
static |
Retrieve the intended motor direction.
This function provides the current intended direction for the motor.
DIRECTION_FORWARD | Forward direction is the intended direction. |
DIRECTION_REVERSE | Reverse direction is the intended direction. |
Definition at line 873 of file main.ino.
|
static |
Read the hall sensor inputs and decode the hall state.
This function reads the hall sensor inputs and converts them into a number ranging from 1 to 6, where the hall sensors' states are represented as bits: H3|H2|H1.
0 | Illegal hall state. Possible hardware error. |
1-6 | Valid hall sensor values. |
7 | Illegal hall state. Possible hardware error. |
Definition at line 946 of file main.ino.
ISR | ( | ADC_vect | ) |
ADC Conversion Complete Interrupt Service Routine.
This interrupt service routine is automatically executed every time an AD conversion is finished, and the converted result is available in the ADC data register.
The switch/case construct ensures that the converted value is stored in the variable corresponding to the selected channel and changes the channel for the next ADC measurement.
Additional ADC measurements can be added to the cycle by extending the switch/case construct.
Definition at line 1292 of file main.ino.
ISR | ( | INT0_vect | ) |
Enable interrupt service routine.
This interrupt service routine is called if the enable pin changes state.
Definition at line 1115 of file main.ino.
ISR | ( | INT2_vect | ) |
Direction input change interrupt service routine.
This interrupt service routine is called every time the direction input pin changes state. The desired direction flag is updated accordingly. The motor control then goes into a state where it needs a stopped motor before any driving of the motor is performed.
Definition at line 1168 of file main.ino.
ISR | ( | PCINT0_vect | ) |
Hall sensor change interrupt service routine.
This interrupt service routine is called every time any of the hall sensors change. The actual direction, the reverse rotation and no hall connections flags are updated.
The motor stopped flag is also set to FALSE, since the motor is obviously not stopped when there is a hall change.
Definition at line 1129 of file main.ino.
ISR | ( | TIMER1_OVF_vect | ) |
Timer1 Overflow Interrupt Service Routine.
This interrupt service routine (ISR) is triggered on Timer1 overflow. It calls the faultSequentialStateMachine() function to handle motor fault reporting.
Definition at line 1273 of file main.ino.
ISR | ( | TIMER4_OVF_vect | ) |
Timer4 Overflow Event Interrupt Service Routine.
This interrupt service routine is trigger on Timer4 overflow. It manages the commutation ticks, which determines motor status. It also controls the execution of the speed regulation loop at constant intervals.
Definition at line 1202 of file main.ino.
void loop | ( | ) |
Main Loop Function.
The main loop function is executed continuously in normal operation after the program has configured everything. It continually checks if the speed controller needs to be run.
Definition at line 271 of file main.ino.
|
static |
Initialize pin change interrupts.
This function initializes pin change interrupt on hall sensor input pins input, shutdown input and motor direction control input.
Definition at line 450 of file main.ino.
|
static |
Initialize PLL (Phase-Locked Loop)
This function configures and initializes the PLL for clock generation. It sets the PLL frequency control register and waits until the PLL is locked and stable before returning.
Definition at line 335 of file main.ino.
|
static |
Initialize I/O port directions and pull-up resistors.
This function initializes all I/O ports with the correct directions and enables pull-up resistors, if needed, for various pins and signals used in the motor control.
Definition at line 361 of file main.ino.
|
static |
Check whether the remote pin is set and update flags accordingly.
This function checks the state of the remote pin and updates the motorFlags.
Definition at line 627 of file main.ino.
|
static |
Update the reverse rotation flag.
This function compares the actual and desired direction flags to determine if the motor is running in the opposite direction of what is requested.
Definition at line 1010 of file main.ino.
|
static |
Set duty cycle for TIM4.
This function sets the duty cycle for block commutation, where the duty range is 0-1023 (not in percentage). To convert to percentage, use: duty * 100 / 1023.
duty | New duty cycle, range 0-1023. |
Definition at line 761 of file main.ino.
void setup | ( | void | ) |
Main initialization function.
The main initialization function initializes all subsystems needed for motor control.
Definition at line 211 of file main.ino.
|
static |
Speed regulator loop.
This function is called periodically every SPEED_CONTROLLER_TIME_BASE ticks. In this implementation, a simple PID controller loop is called, but this function could be replaced by any speed or other regulator.
If the SPEED_CONTROL_METHOD is set to SPEED_CONTROL_CLOSED_LOOP, a PID controller is used to regulate the speed. The speed input is converted into an increment set point, and a PID controller computes the output value. The output is limited to a maximum value of 255.
If the SPEED_CONTROL_METHOD is not set to SPEED_CONTROL_CLOSED_LOOP, a simple speed control mechanism is applied. If the motor is enabled, the function calculates the delta between the speed input and the current speed output. If the delta exceeds the maximum allowed change, it limits the change to SPEED_CONTROLLER_MAX_DELTA. If the motor is disabled, the speed output is set to 0.
Definition at line 664 of file main.ino.
void TimersInit | ( | void | ) |
Initializes and synchronizes Timers.
This function sets the correct pre-scaler and starts all required timers.
Timer 1 is used to trigger the fault multiplexing on overflow. Timer 3 is used, if EMULATE_HALL is set, to trigger the change in hall output on overflow. Timer 4 is used to generate PWM outputs for the gates and trigger the commutation tick counter and check if the motor is spinning on overflow. The overflow event interrupt for Timer 4 is set outside this function at the end of the main initialization function.
Definition at line 405 of file main.ino.
|
static |
Configures timers for block commutation.
This function is called every time the drive waveform is changed and block commutation is needed. PWM outputs are safely disabled while configuration registers are changed to avoid unintended driving or shoot-through.
The function sets the PWM pins to input (High-Z) while changing modes and configures the timers. The output duty cycle is set to zero initially. It waits for the next PWM cycle to ensure that all outputs are updated, and then the motor drive waveform is set to block commutation. Finally, the PWM pins are changed back to output mode to allow PWM control.
Definition at line 779 of file main.ino.
|
static |
Wait for the start of the next PWM cycle.
This function waits for the beginning of the next PWM cycle to ensure smooth transitions between different PWM modes and avoid shoot-through conditions.
Definition at line 852 of file main.ino.
volatile uint16_t commutationTicks = 0 |
The number of 'ticks' between two hall sensor changes (counter).
This variable is used to count the number of 'ticks' between each hall sensor change. It is cleared when the hall sensor change occurs. One 'tick' is one PWM period.
volatile uint16_t current = 0 |
Current measurement (Register Value).
The most recent current measurement is stored in this variable.
The range is 0-1023.
This value is not scaled and represents the raw ADC register value. To obtain the scaled current value in amperes, you can use the formula:
\[ \text{Current (A)} = \frac{\text{REGISTER_VALUE} \times 0.004887586 \times 1000000}{\text{CURRENT_GAIN} \times \text{CURRENT_SENSE_RESISTOR}} \]
Where:
The NEVB-3INV-001-01 comes with a current op-amp with a gain factor of 50 and a current sense resistor of value 2 mΩ. This corresponds to approximately 0.049 amperes (A) per register value.
volatile faultflags_t faultFlags |
volatile uint16_t gateVref = 0 |
Gate voltage measurement (Register Value)
The most recent gate voltage measurement is stored in this variable.
The range is 0-1023.
This value is not scaled and represents the raw ADC register value. To obtain the scaled gate voltage in volts, you can use the formula:
\[ \text{Voltage (V)} = \frac{\text{REGISTER_VALUE} \times 0.004887586 \times (\text{GATE_RTOP} + \text{GATE_RBOTTOM})}{\text{GATE_RBOTTOM}} \]
Where:
NEVB-3INV-001-01 has a resistor divider with RTOP of 1 MΩ and RBOTTOM of 71.5 kΩ, so it corresponds to approximately 0.0732 volts (V) per register value.
char incoming_byte = 0 |
volatile uint16_t lastCommutationTicks = 0xffff |
The number of 'ticks' between two hall sensor changes (store).
This variable is used to store the number of 'ticks' between each hall sensor change. It is set to the value in commutationTicks before it is cleared when the hall sensor change occurs.
One 'tick' is one PWM period. The speed of the motor is inversely proportional to this value.
volatile motorconfigs_t motorConfigs |
volatile motorflags_t motorFlags |
volatile uint8_t speedInput = 0 |