2016-02-08 12:59 AM
Hello there,
I am using STM32F4. I am trying to make an application, where I could be able to modulate the frequency (not pwm) of one channel for example in range of 1k - 20k Hz. The problem i encountered is that for a channel frequency the equasion is applied:Freq = SysClk / ( (Prescaller + 1) * Period )
Because of this, I cannot change the frequency in a linear way by modifying prescaller and period. Also modifying them both in order to get the result needs a bit of computation which requires time. I was wondering either there is a simplier and more effective way of doing this. For example, lets say each timer tick I would like to change the channel frequency by 10 Hz (starting from 1k and finishing at 20k).
Are there any moethods for that?
I would apreciate all help!
2016-02-08 05:53 AM
When you say “not PWM� do you mean a sine wave?
If so, the approach that I would recommend is to use DMA and a timer to drive one (or both) of the F4’s DAC’s from a sine lookup table.
The technique is called Direct Digital Synthesis.
2016-02-08 06:03 AM
Thank you for answer,
I do not mean to create a DDS. I might have explained this in the wrong way, i will try on an example. Lets say I have TIM1 consigured to output a 50% PWM on channel 1 with frequency 1kHz. Next on, in a loop, lets say every 10 ms (interrupt routine of another timer) I would like to change the frequency of the TIM1 (not pulse width). If i change the TIM1 prescaller or period, I wont be able to change the frequency in a linear way. This is the question, is there any way to do it in a linear way? For example, to increate the frequency of TIM1 by 10 Hz each time.2016-02-08 06:16 AM
You should define your maximum allowed frequency step ( 10Hz ?)
If that is the case, 10Hz should works for such a low frequency, since timer is running on 80MHz or so ( maybe even 160, don't remember) In that case, i would use other timer or systick, to adjust your pwm compare and period registers, like this:uint32_t period = X;
uint32_t period_temp = 0xFFFF; (something big)
void IRQ(void) //at constant time intervals
{
if(period>period_temp)
period_temp++;
if(period<period_temp)
period_temp--;
Timer_register_update(period_temp);
}
}
this will change frequency in semi linear way, if you are running with large values for period and CCR registers.... ( CCR = period-1/2)
2016-02-08 06:17 AM
The integer methods used by the STM32 are rather limiting. More effective solutions use an NCO, with an accumulator and tuning register. The high order bit of the accumulator is the out, multiple high order bit can represent phase. The method allows for fractional frequency adjustments.
2016-02-08 06:50 AM
Thank you for the answers, I have an idea of how to do it now.