2025-10-29 9:27 PM
Hello everyone,
I'd first like to mention that this project is being developed with support from ST Brasil, which has provided important components to aid in this development.
I'm working on firmware for motor control and, being new to this area, I'm looking for guidance on the best way to implement a specific part of the logic.
Here is a summary of the hardware and MCU configuration:
Hardware: 3 low-side shunts. The signal from the Phase U shunt resistor is shared, acting as a common input for two of the MCU's integrated op-amps.
MCU Config:
1.1. Timer 1: Configured for Center-Aligned Mode 1. * CH1/CH1N, CH2/CH2N, CH3/CH3N are complementary PWM outputs. * CH4 is used to generate a capture-compare interrupt.
1.2. ARR Value: The ARR (Auto-Reload Register) value is 1000.
1.3. Interrupt Trigger: Timer 1 CH4 is set to generate a capture-compare interrupt when the CNT (counter) reaches 900.
1.4. Modulation Index: For modulation index purposes, the maximum value for CCR1, CCR2, and CCR3 should be 800.
1.5. Op-Amps: Configured for high-speed mode. The non-inverting input pin needs to be switched programmatically (in software).
1.6. ADCs: * Using DMA. * Regular conversions are triggered by software. * Scan Mode is On. * The "End of Sequence of conversions" (EOS) option is enabled.
(Thank you for reading this far.)
Given this configuration—specifically the need to read currents and switch the op-amp inputs—I'm trying to figure out the most robust and efficient way to handle the logic.
What is the best practice or recommended method for:
Reading the ADC values?
Saving the conversion data?
Programmatically toggling the non-inverting inputs for the op-amps in sync with the PWM cycle?
I'm looking for advice on the general approach .
Thank you for your time.
Best Regards,
Raul Undergraduate Student & Scientific Initiation
Universidade Federal de Santa Maria (UFSM)
Solved! Go to Solution.
2025-10-31 12:11 AM
> I'm still unsure about the best way to toggle the op-amp pin in a robust and efficient manner, ...
Having no experience with STM32G4 devices, I am not sure what you mean with "toggle an opamp pin".
I used to do quite a bit with F3 and F4 devices in this regard.
In your case, I suppose to either switch the range or between different MCUs.
If you need to incorporate ADC input data from before and after this switch event, things might get a bit trickier.
But perhaps you explain a few details here.
> I really liked your idea of storing the buffer data inside the ADC interrupt — it makes perfect sense — and the flag approach for running the observer also sounds like a very elegant solution that I definitely plan to implement.
This is basically the PLC concept applied - input, processing, and output done icyclically n sequence, and a cycle time the controlled system requires. You want a stable and known sampling/cycle time for any control algorithm, or it gets really messy.
My company uses ECUs for work machinery, and an RTOS for portability and certification reasons.
But the concept is easy to replicate ad hoc with bare metal code.
2025-10-29 11:38 PM
> 1. Reading the ADC values?
> 2. Saving the conversion data?
Both are closely related.
And assuming you want to implement a cycle-by-cycle control, you probably need one set of ADC input values (the configured channel sequence).
For that I would configure DMA for the number of bytes this sequence contains (two bytes per channel for 12-bit values) in single-burst mode, ADC-EOS as trigger (ADC configuration !), and enable the DMA-TC interrupt. This way, you get an interrupt whenever DMA has finished to transfer a sequence to your configured buffer.
When playing around with audio data, I used to configure DMA to a larger (integral) number of transfers.
But since you probably want to feed the ADC values into the control algorithm cycle, this is not appropriate here.
> 3. Programmatically toggling the non-inverting inputs for the op-amps in sync with the PWM cycle?
I'm not really familiar with motor control, but probably a timer interrupt associated with the PWM generation.
I'm sure others here have more experience in this regard.
> 4. After the currents and voltages are read and saved, I will implement a state observer. Where in the execution flow (e.g., in which interrupt context, or in the main loop) should I perform these observer calculations to avoid race conditions with the data that is being updated by the DMA/ADC?
I personally would avoid the interrupt context here.
Refreshing my old electrical engineering subject stuff, an observer is basically a controller working on another controller instead of the controlled system itself.
I would run both in the main loop, usually the observer after the controller.
The trigger is a flag set in an interrupt - whichever signifies in your case that all data are gathered. Which might be said DMA-TC interrupt.
2025-10-30 12:17 PM
Thank you very much for taking the time to reply to this post and for your helpful insights. I really liked your idea of storing the buffer data inside the ADC interrupt — it makes perfect sense — and the flag approach for running the observer also sounds like a very elegant solution that I definitely plan to implement.
I'm still unsure about the best way to toggle the op-amp pin in a robust and efficient manner, so if you happen to have a small code snippet or example, that would be incredibly helpful.
I won't mark the answer as accepted just yet, but please know that your contribution has been extremely valuable for the implementation of this code. Thanks again for your time and for sharing your knowledge.
2025-10-31 12:11 AM
> I'm still unsure about the best way to toggle the op-amp pin in a robust and efficient manner, ...
Having no experience with STM32G4 devices, I am not sure what you mean with "toggle an opamp pin".
I used to do quite a bit with F3 and F4 devices in this regard.
In your case, I suppose to either switch the range or between different MCUs.
If you need to incorporate ADC input data from before and after this switch event, things might get a bit trickier.
But perhaps you explain a few details here.
> I really liked your idea of storing the buffer data inside the ADC interrupt — it makes perfect sense — and the flag approach for running the observer also sounds like a very elegant solution that I definitely plan to implement.
This is basically the PLC concept applied - input, processing, and output done icyclically n sequence, and a cycle time the controlled system requires. You want a stable and known sampling/cycle time for any control algorithm, or it gets really messy.
My company uses ECUs for work machinery, and an RTOS for portability and certification reasons.
But the concept is easy to replicate ad hoc with bare metal code.