Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Seeking Efficient Method for Generating Sine Wave with H-Bridge Using TIM1 (STM32 Microcontroller) with Complimentory outputs .

gravity123

Junior Member level 1
Junior Member level 1
Joined
Mar 30, 2011
Messages
15
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,415
I am working with TIM1 on an STM32 microcontroller, which has two channels (Channel 1 and Channel 2) with complementary outputs. I’m configuring it to generate a sine wave for an H-bridge as follows:

  • Positive Half-Cycle: PWM signals drive MOSFETs Q1 and Q4, while MOSFETs Q2 and Q3 remain off.
  • Negative Half-Cycle: PWM signals drive MOSFETs Q2 and Q3, while MOSFETs Q1 and Q4 remain off.
I am using center-aligned mode. What is the most efficient programming approach to achieve this?

Specifically, I need to know:

  1. How to efficiently feed sine wave values to CCR1 and CCR2 using DMA.
  2. Can a single lookup table be used to handle the entire sine wave, or is it better to handle each half-cycle separately? Should I first feed values for the positive half-cycle and then invert the polarity for the negative half-cycle?
What is the most effective and straightforward method to implement this?
 
Hi,
  • Positive Half-Cycle: PWM signals drive MOSFETs Q1 and Q4, while MOSFETs Q2 and Q3 remain off.
  • Negative Half-Cycle: PWM signals drive MOSFETs Q2 and Q3, while MOSFETs Q1 and Q4 remain off.

What about Q5 and Q6?

What is the most efficient programming approach to achieve this?
to use already written software.

Can a single lookup table be used to handle the entire sine wave, or is it better to handle each half-cycle separately? Should I first feed values for the positive half-cycle and then invert the polarity for the negative half-cycle?
If you want have a fixed sine frequencyand fixed amplitude .. I recommend to use a full wave lookup table in a RAM array to be transferred repeatedly via DMA.
It surely is the least processing power consuming way.

Klaus
 
Another arm single chip approach :



Regards, Dana.
 
I am using center-aligned mode. What is the most efficient programming approach to achieve this?
What prompted you to use the center-aligned mode? Dig into your motivation for that and then proceed to ask what are the next steps in generating your output.

Specifically, I need to know:

  1. How to efficiently feed sine wave values to CCR1 and CCR2 using DMA.
  2. Can a single lookup table be used to handle the entire sine wave, or is it better to handle each half-cycle separately? Should I first feed values for the positive half-cycle and then invert the polarity for the negative half-cycle?
What is the most effective and straightforward method to implement this?
As Klaus mentioned, having the full table is least computationally demanding. In your alternate approaches, you would need to perform additional computation/logic in inverting the polarity. If you can avoid that, why not? The tradeoff is more storage/memory requirement. Without knowing your specific application/use case, I would guess that the additional memory requirement is unlikely to be a deal-breaker.

Have you used PWM and DMA on this chip before?
Broadly, your steps would be:
  1. Populate sine table into memory. You should be able to compute this as fractions of the PWM period corresponding to a sine wave. May consider looking at this: https://tahmidmc.blogspot.com/2011/01/generation-and-implementation-of-sine.html , https://tahmidmc.blogspot.com/2023/11/smartsinepy-and-example-of-gui.html
  2. Configure PWM at your carrier frequency.
  3. Configure DMA: source = sine table, destination = PWM duty cycle register, trigger = PWM, source length, etc.
  4. Set everything to run.
Register-level implementation details should be in the datasheet or technical reference manual for your microcontroller. Alternately, if you decide to use a hardware abstraction library, refer to that for peripheral details.
 
Last edited:
Thanks, @Tahamid. I already know your blog; it provides us with so much valuable information. This time, I want to express my appreciation and gratitude for sharing your knowledge with the world through the blog .
I am able to work with DMA to feed the PWM duty cycle, and it works well for the first half cycle. I am confused about how to feed data for the next half cycle. Do I need a 180-degree phase-shifted sine wave array value, or can I change the polarity of the main PWM channels? What is the generic logic for this?
I used center-aligned mode based on some sites that mention its advantages, by the way I don't have a specific reason for choosing it.

i just showing my code for the array to pwm by DMA as follows
const uint16_t sine_table[200]= {250, 250, 250, 249, 249, 248, 248, 247, 246, 245, 244, 243, 241, 240,
238, 236, 235, 233, 231, 228, 226, 224, 221, 219, 216, 213, 211, 208, 205, 202, 198, 195, 192,
189, 185, 182, 178, 175, 171, 167, 164, 160, 156, 152, 148, 145, 141, 137, 133, 129, 125, 121,
117, 113, 109, 105, 102, 98, 94, 90, 86, 83, 79, 75, 72, 68, 65, 61, 58, 55, 52, 48, 45, 42, 39,
37, 34, 31, 29, 26, 24, 22, 19, 17, 15, 14, 12, 10, 9, 7, 6, 5, 4, 3, 2, 2, 1, 1, 0, 0, 0, 1, 1,
2, 2, 2, 3, 3, 4, 5, 6, 7, 9, 10, 12, 14, 15, 17, 19, 22, 24, 26, 29, 31, 34, 37, 39, 42, 45, 48,
52, 55, 58, 61, 65, 68, 72, 75, 79, 83, 86, 90, 94, 98, 102, 105, 109, 113, 117, 121, 125, 129, 133,
137, 141, 145, 148, 152, 156, 160, 164, 167, 171, 175, 178, 182, 185, 189, 192, 195, 198, 202, 205,
208, 211, 213, 216, 219, 221, 224, 226, 228, 231, 233, 235, 236, 238, 240, 241, 243, 244, 245, 246,
247, 248, 248, 249, 249, 250, 250, 250};

HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t *)sine_table, 20);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_2, (uint32_t *)sine_table, 20);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);

Am trying to give same half wave array to get the next half cycle .
 
What type of load do you want to drive with the inverter, are you planning a LC output filter?

As far as I understand, the on/off switching pattern described in post #1 can't maintain the modulated sine waveform with reactive load as e.g. presented by an output filter.
 
Yes am using LC filter .
is there any other method to recover it ?
You're using the conventional filter method. For a load that is resistive and unchanging, it's not so much trouble as you calculate LC filter values. Make the inductor a value that permits adequate amplitude of your output waveform (while smoothing it to some extent). The capacitor value performs further smoothing, as well as correcting for power factor error.

What SPWM filtering shall we make for a load that is inductive or partially inductive? The waveform changes phase. So notice even on grid power a big motor may include a capacitor in the housing for the purpose of power factor correction.

* Picture your SPWM H-bridge acting like a buck converter sending current to the righthand direction through the load, during one-half of the cycle. Only one and only one transistor needs to switch thousands of times per second. Then during the second half of the cycle, our mimic of a buck converter performs in the left direction. One and only one transistor needs to switch thousands of times per second.

Your H-bridge must duplicate the above switching action. Through selecting N-devices or P-devices properly. Proper biasing at proper voltage. Current conducting through body diodes at proper times.
 

LaTeX Commands Quick-Menu:

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top