Generate a fixed number of pulses on the STM32F4 PWM - c

I am trying to control a servo motor (link). It is a brushless DC motor with an interface similar to a stepper motor.
The motor rotates for a defined distance based on the number of pulses it receives from the PWM. The speed is determined by the pulse frequency of the PWM, like a stepper motor.
To control this motor I am using a microcontroller STM32F407ZET6. I can easily change the frequency and Duty Cycle of PWM, but my doubt is the following:
How do I generate a fixed number of pulses in the PWM? For example, I want the PWM to send 1000 pulses at a certain time with a frequency of 20KHz and a Duty Cycle of 50%. 20KHz and 50% Duty Cycle are easy to define, but I can't determine how to generate the 1000 fixed pulses.
One of the solutions I tried was to connect the PWM back to a timer in counter mode and stop the PWM when the required number of pulses has been generated. But the number of pulses is not always fixed, sometimes ranging from 998 to 1005 (for example).
Is it possible to do this without the need for feedback?

Simpest way:
UG interrupt = count cycles. After n cycles disable the timer.
In the memory create a buffer with the timer register values and use timer burst mode.
Configure DMA mem-mem with n cycles same source and destination address. After n cycles end of transaction interrupt will be generated - disable the timer.
Use slave timer counting when the PWM is updating (overflowing). Set the overflow interrupt and disable the PWM timer.
many other methods.

This can be easily achieved by combining the so called "One-pulse mode" (reference manual page 551) with the repetition counter (page 529). All you've got to do is enabling this mode (OPM bit in CR1), set the repetition counter (RCR) and start the timer. IIRC you also have to force an update event in order to get RCR loaded. The reference manual will have more information on that.

Related

STM32: How to configure timer to trigger interrupt in every increments in quadrature encoder mode?

I have a rotary encoder with STM32F4 and configured TIM4 in "Encoder Mode TI1 and TI2". I want to have an interrupt every time the value of timer is incremented or decremented.
The counting works but I only can configure an interrupt on every update event, not every changes in TIM4->cnt. How can I do this?
In other words: My MCU+Encoder in quadrature mode could count from 0 to 99 in one revolution. I want to have 100 interrupts in the revolution but if I set TIM4->PSC=0 and TIM4->ARR=1, results 50 UPDATE_EVENTs, so I should set ARR=0 but it does not work. How can I sole that?
To get 100 interrupts per revolution keep PSC=0, ARR=1, setup the two timer channels in output compare mode with compare values 0 and 1 and interrupts on both channels.
Or even use ARR=3 and setup all four channels, with compare values of 0,1,2 and 3. This will allow to detect the direction.
Normally, the whole point of using the quadrature encoder mode is counting the pulses while avoiding interrupts. You can simply poll the counter register periodically to determine speed and position.
Getting interrupts on every encoder pulse is extremely inefficient, especially with high resolution encoders. Yours seems to be a low resolution one. If you still think you need them for some reason, you can connect A & B into external interrupts and implement the counting logic manually. In this case, you don't need quadrature encoder mode.

How to control the rate of LED blinking

I am using STM32 board to control the color and blinking rate of the RGB LED. For varying the color of RGB LED I have configured a timer in PWM mode and by varying the duty cycle of three signals on three channels of this timer, the LED changes the color. How can I control the blinking rate of LED with another timer? Which mode of second timer and technique should be used to control the on and off time?
Thanks in advance.
There are many ways that you can do this.
The simplest is in the main loop of your application to read some clock or free running timer. If it is time for the next LED colour then update the PWM duty cycle.
A more complicated approach that does not require code in the main loop would use a DMA whose source is an array of PWM values and whose destination is the duty cycle register of the output timer. You can then use a different timer to periodically trigger the DMA.

stm32f446 When using dma to control PWM duty cycle, the PWM wave has abnormal waveform

MCU: f446rct6
System: freertos
Library: hal
Program logic:
Initialize the timer to output the PWM wave and initialize the DMA and connect to the Capture/Compare register
Start the timer
When data needs to be updated, start a dma transmission
Phenomenon: There is no problem with the frequency and duty cycle of the PWM wave, but a strange triangular waveform often appears in the first or second waveform of DMA transmission.
Ask everyone, do you encounter similar waveforms when using pwm? Please give me a hint to locate this problem, thank you
Potential causes include:
You're switching the pin to DAC mode (if your MCU has a DAC) and driving it with an increasing value.
The pin is disabled, and what you see is the drift of the voltage on the pin's and probe's combined capacitance.
You're inadvertently switching the PWM to a very high frequency and the scope is set to too low sample rate. Make sure you set the scope to highest possible sample rate / sample depth / sampling length, and decrease the horizontal scale (i.e. decrease the time per division by 2x or 5x).

ARMv7 stm32-L476G How to set a specific pitch of sound to play for a specific duration

I am new to ARMv7 assembly programming (using the stm32-L476G) and I am lost on how to produce a specific-pitched sound (e.g 110 hz) to play for 15 seconds. I have done my research and reached a dead end. Can anybody help me?
method A
Configure the timer to generate 110Hz PWM 50% signal.
Configure another timer to overflow after 15 seconds.
In the second timer interrupt deactivate the PWM signal generation by the first timer
method B
1 configure the timer to overflow every 1/220 sec.
In the timer interrupt toggle the pin
count the number the interrupts when the number reaches the 220*15 disable timer
method C
1 create the sine tabue table in the memory.
confiure the timer to trigger DMA transfer to DAC every
1/(110*nsamples_per_period)
configure DMA in the circular mode
in the DMA end transfer interrupt increase the counter
when the counter is >= 110*15 disable the triggering timer

STM32 - How to trigger interrupt after a certain PWM ON time?

I'm new to ARM MCUs (STM32F411), and I have been trying to find my way around the peripherals using STM's HAL library and STM32Cube.
I've already configured my board in order to use some peripherals:
Timer 2 for running an interrupt with a certain frequency
Timer 3 for running PWMs on 3 channels of it.
ADC with 4 channels, into DMA mode, for reading some analog input.
Let us suppose, now, that the PWM's whole period is 100 ms and its duty cycle is 50% (50 ms PWM on and 50 ms PWM off).
I would like to trigger an interrupt after a certain time of the PWM on level, let us say 50% of it.
Hence, I would like to run an interrupt at 25 ms in order to use the ADC for sampling it's analog inputs.
Do you have any suggestion on how could I implement such a kind of interrupt?
Thank you in advance for your help!
Since the ADC of the STM32F411 is used in Regular mode (not Injected mode) and only three channels out of four are used to generate PWM on Timer 3, the fourth channel can be used to trigger the ADC.
Hence Timer 3 is configured as follows:
CH1 used for Output Compare mode 0 (TIM3->CCMR1.OC1M = 0)
CH2, CH3, CH4 used for PWM outputs
Therefore TIM3->CCR1 is loaded to a value that gives 25% of duty, then it will generate TIM3_CH1 events that can be used to trigger ADC start-of-conversion at 25% of your TIM3 timebase.

Resources