STM32数模转换器频率调节

STM32数模转换器频率调节,stm32,frequency,dac,Stm32,Frequency,Dac,我使用STM32F407VG创建了一个30 khz的正弦波。定时器设置为:;预分频器=2-1,ARR=1,时钟也是84 mHz运行DAC的时钟 我编写了一个名为generate_sin的函数 #define SINE_ARY_SIZE (360) const int MAX_SINE_DEGERI = 4095; // max_sine_value const double BASLANGIC_NOKTASI = 2047.5; //starting point uint32_t sine_ar

我使用STM32F407VG创建了一个30 khz的正弦波。定时器设置为:;预分频器=2-1,ARR=1,时钟也是84 mHz运行DAC的时钟

我编写了一个名为generate_sin的函数

#define SINE_ARY_SIZE (360)
const int MAX_SINE_DEGERI = 4095; // max_sine_value
const double BASLANGIC_NOKTASI = 2047.5; //starting point
uint32_t sine_ary[SINE_ARY_SIZE];
void generate_sine(){
    for (int i = 0; i < SINE_ARY_SIZE; i++){
        double deger = (sin(i*M_PI*360/180/SINE_ARY_SIZE) * BASLANGIC_NOKTASI) + BASLANGIC_NOKTASI; //double value
        sine_ary[i] = (uint32_t)deger; // value
}
这些是我用来做我想做的事情的代码。但是我在不改变预分频器或ARR的情况下改变频率时遇到了麻烦


这是我的问题。我可以在不更改计时器设置的情况下更改频率吗?例如,我想使用按钮,每当我按下按钮时,我想改变频率。

生成正弦函数将为您提供一个正弦波周期,该周期具有正弦大小的样本

要增加频率,您需要将周期缩短为2x频率,每个周期的采样数将减少一半。因此,您应该计算较小正弦大小的数组,该数组将用较短的正弦波填充原始缓冲区的一部分,并将该较小值放入HAL_DAC_Start_DMA函数中

降低频率将需要延长阵列的长度

您应该声明正弦值,该正弦值具有最低频率所需的最大长度。确保它适合RAM

#define MAXIMUM_ARRAY_LENGTH 360

uint32_t usedArrayLength = 180;

const double amplitude = 2047.5;

uint32_t sine_ary[MAXIMUM_ARRAY_LENGTH];

void generate_sine(){
    for (int i = 0; i < usedArrayLength; i++){
        double value = (sin(i*M_PI*2/usedArrayLength) * amplitude) + amplitude;
        sine_ary[i] = (uint32_t)value; // value
}
要更改频率,请停止DAC,更改usedArrayLength的值越小表示频率越高,必须小于或等于最大数组长度。然后调用generate_sine函数,并使用现在使用新usedArrayLength的相同函数再次启动DAC

频率为:时钟/预分频器/ARR/UsedArray长度


此外,您应该使用uint16\t,因为数组值从0到4095,DAC是12位的,我想DMA应该设置为每个值2字节的半字。

除了更改频率外,工作正常吗?顺便说一句,我在你的代码中看不到频率设置。@Tagli是的,它工作得非常好。我通过改变正弦大小来改变频率,正弦大小是我的采样率。其他设置保持不变。为什么要避免更改TIM频率?更改TIM频率比重新计算正弦查找表要好得多。要更改频率,请停止DAC。。。。非常幼稚和糟糕的方式。在大多数情况下,您无法停止生成,您需要避免抖动或信号失真。@JiříMaier感谢您的努力。我可以用按钮来做吗?我的意思是我可以创建一个名为buttonState的变量,当buttonState变为1时,应该应用其他设置来更改频率。你认为有可能吗?@0\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。每当按下按钮时,应在不停止发电的情况下更改频率。Jiri谢谢你的时间。我会考虑一下,并尝试想出一个解决方案。@Kırambor,你为什么不想更改计时器设置,而不是通过重新计算样本来更改频率?计算一次样本,然后更改计时器的频率似乎比每次更改频率时重新计算数组要简单。因为我不知道如何应用新的计时器设置。我的意思是,计时器设置在一个名为void TimerSettings;的函数中;。当我按下按钮时,我会将预分频器从2变为4。但有可能用按钮状态来实现吗?
#define MAXIMUM_ARRAY_LENGTH 360

uint32_t usedArrayLength = 180;

const double amplitude = 2047.5;

uint32_t sine_ary[MAXIMUM_ARRAY_LENGTH];

void generate_sine(){
    for (int i = 0; i < usedArrayLength; i++){
        double value = (sin(i*M_PI*2/usedArrayLength) * amplitude) + amplitude;
        sine_ary[i] = (uint32_t)value; // value
}
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, sine_ary, usedArrayLength, DAC_ALIGN_12B_R);