STM32CubeMX | STM32使用DAC+DMA+TIM生成10KHz正弦波
工程环境:
- STM32F103RC
- KEIL MDK 5.20
- STM32CubeMX 6.0
前言
-
正弦波曲线的函数公式是:y=sin(x)
-
y的范围区间是[-1:1]
-
x的取值范围是任意实数
-
周期为2π
如下图所示的蓝色函数曲线:
使用DAC生成正弦波比较方便的方法是预先生成一个正弦波的数据点表,为了能够快速设置到DAC上所有会使用到DMA,然后通过定时器控制DAC的出样频率就达到了生成正弦波的效果。
那么这个正弦波数据点表是怎么生成的呢?下面就来讲解一下。
将这个y=sin(x)函数映射成我们现在的这个正弦波,那么y就是代表的电压,x代表的周期。
由于y=sin(x)的值范围在[-1:1]之间,DAC设置的时候不存在负数,所以就需要加1让公式生成的值都在正数范围内,公式就变成了y=six(x) + 1,现在值范围就成了[0:2],但是这样最高能表示到2V,而DAC是能输出到3.3V的,也就是说y=six(x) + 1输出2V的时候代表3.3V,所以就需要对y=six(x) + 1进行扩大,比值关系就是3.3V:2V,所以公式又变成了y=(sin(x) + 1)*(3.3/2),这样值范围就变为了[0:3.3],然后再将电压转为DAC数值就可以了。
因为正弦波每周期的波形都是一样的,所以我们生成一个周期的数据表即可。
经试验所得,一个周期内满足32个点就能近似逼近正弦波的效果,这里为了波形更好看,我选择了100个点。
周期为2π,一共100个点,那么每两个点的间距就是2π/100。
/**
* 生成正弦波数据点函数
* @param NPoints 一个周期内的点数
* @param VMaxRange 输出的电压最大值,取值范围0~3.3V
* @param SineWaveTable 存放生成的数据点
*/
void SineWaveGen(uint32_t NPoints, float VMaxRange, uint16_t* SineWaveTable)
{
#ifndef PI
#define PI 3.14159265358979323846
#endif
int i = 0;
double radian = 0; // 弧度
double setup = 0; // 弧度和弧度之间的大小
double voltage = 0; // 输出电压
setup = (2 * PI) / NPoints; // 两点之间的间距
while (i < NPoints)
{
voltage = VMaxRange / 2.0 * (sin(radian) + 1.0); // 计算电压
SineWaveTable[i] = (uint16_t)(voltage * 4096 / 3.3); // 电压转为DAC数值
radian += setup; // 下一个点的弧度
i++;
}
}
工程配置
时钟配置到72M主频:
配置DAC
说明:
Output Buffer:输出缓存
DAC 集成了 2 个输出缓存,可以用来减少输出阻抗,无需外部运放即可直接驱动外部负载。每个 DAC 通道输出缓存可以通过设置 DAC_CR 寄存器的 BOFFx 位来使能或者关闭。如果带载能力还不行,后面就接一个电压跟随器,选择运放一定要选择电流大的型号。
使能输出缓冲后,DAC 输出的最小电压为 0.2V,最大电压为 VREF±0.2,而未使能输出缓冲则输出可达到0V。
Tigger:触发方式
选择DAC的触发方式,可以选择为定时器触发、外部中断触发和软件触发。这里我选择了定时器6来触发DAC,因为通过设置定时器的频率就可以很方便的控制DAC输出的正弦波频率。
Wave generation mode:波形发生器
我这里没有使用。
配置DMA
配置定时器
定时器6的时钟主频为72MHz,我这里没有分频,那么把重载值设置为72,这样就得到了72M/72=1MHz的触发频率。
上面说到过我的设置是一个周期内100个点,定时器触发频率为1MHz,触发一百次才能完成一个周期的波形,所以生成的波形频率就是1MHz/100个点=10KHz。
最后启动定时器和DMA传输即可:
HAL_TIM_Base_Start(&htim6);
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_2, (uint32_t *)SineWaveTable, POINTS, DAC_ALIGN_12B_R);
生成的波形用示波器查看如下:
版权声明:本文为CSDN博主「雍正不秃头」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq153471503/article/details/122341769
STM32CubeMX | STM32使用DAC+DMA+TIM生成10KHz正弦波
工程环境:
- STM32F103RC
- KEIL MDK 5.20
- STM32CubeMX 6.0
前言
-
正弦波曲线的函数公式是:y=sin(x)
-
y的范围区间是[-1:1]
-
x的取值范围是任意实数
-
周期为2π
如下图所示的蓝色函数曲线:
使用DAC生成正弦波比较方便的方法是预先生成一个正弦波的数据点表,为了能够快速设置到DAC上所有会使用到DMA,然后通过定时器控制DAC的出样频率就达到了生成正弦波的效果。
那么这个正弦波数据点表是怎么生成的呢?下面就来讲解一下。
将这个y=sin(x)函数映射成我们现在的这个正弦波,那么y就是代表的电压,x代表的周期。
由于y=sin(x)的值范围在[-1:1]之间,DAC设置的时候不存在负数,所以就需要加1让公式生成的值都在正数范围内,公式就变成了y=six(x) + 1,现在值范围就成了[0:2],但是这样最高能表示到2V,而DAC是能输出到3.3V的,也就是说y=six(x) + 1输出2V的时候代表3.3V,所以就需要对y=six(x) + 1进行扩大,比值关系就是3.3V:2V,所以公式又变成了y=(sin(x) + 1)*(3.3/2),这样值范围就变为了[0:3.3],然后再将电压转为DAC数值就可以了。
因为正弦波每周期的波形都是一样的,所以我们生成一个周期的数据表即可。
经试验所得,一个周期内满足32个点就能近似逼近正弦波的效果,这里为了波形更好看,我选择了100个点。
周期为2π,一共100个点,那么每两个点的间距就是2π/100。
/**
* 生成正弦波数据点函数
* @param NPoints 一个周期内的点数
* @param VMaxRange 输出的电压最大值,取值范围0~3.3V
* @param SineWaveTable 存放生成的数据点
*/
void SineWaveGen(uint32_t NPoints, float VMaxRange, uint16_t* SineWaveTable)
{
#ifndef PI
#define PI 3.14159265358979323846
#endif
int i = 0;
double radian = 0; // 弧度
double setup = 0; // 弧度和弧度之间的大小
double voltage = 0; // 输出电压
setup = (2 * PI) / NPoints; // 两点之间的间距
while (i < NPoints)
{
voltage = VMaxRange / 2.0 * (sin(radian) + 1.0); // 计算电压
SineWaveTable[i] = (uint16_t)(voltage * 4096 / 3.3); // 电压转为DAC数值
radian += setup; // 下一个点的弧度
i++;
}
}
工程配置
时钟配置到72M主频:
配置DAC
说明:
Output Buffer:输出缓存
DAC 集成了 2 个输出缓存,可以用来减少输出阻抗,无需外部运放即可直接驱动外部负载。每个 DAC 通道输出缓存可以通过设置 DAC_CR 寄存器的 BOFFx 位来使能或者关闭。如果带载能力还不行,后面就接一个电压跟随器,选择运放一定要选择电流大的型号。
使能输出缓冲后,DAC 输出的最小电压为 0.2V,最大电压为 VREF±0.2,而未使能输出缓冲则输出可达到0V。
Tigger:触发方式
选择DAC的触发方式,可以选择为定时器触发、外部中断触发和软件触发。这里我选择了定时器6来触发DAC,因为通过设置定时器的频率就可以很方便的控制DAC输出的正弦波频率。
Wave generation mode:波形发生器
我这里没有使用。
配置DMA
配置定时器
定时器6的时钟主频为72MHz,我这里没有分频,那么把重载值设置为72,这样就得到了72M/72=1MHz的触发频率。
上面说到过我的设置是一个周期内100个点,定时器触发频率为1MHz,触发一百次才能完成一个周期的波形,所以生成的波形频率就是1MHz/100个点=10KHz。
最后启动定时器和DMA传输即可:
HAL_TIM_Base_Start(&htim6);
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_2, (uint32_t *)SineWaveTable, POINTS, DAC_ALIGN_12B_R);
生成的波形用示波器查看如下:
版权声明:本文为CSDN博主「雍正不秃头」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq153471503/article/details/122341769
暂无评论