stm32方波三角波正弦波HAL
时间: 2025-02-24 18:34:39 浏览: 24
使用 STM32 和 HAL 库生成方波、三角波和正弦波
方波生成方法
为了使用STM32和HAL库生成方波,需要配置DAC模块并利用DMA传输预定义的数据序列来形成特定形状的波形。对于方波而言,只需要两个不同的电平值交替变化即可。
// 定义方波数据表
uint16_t square_wave_data[] = {
0x0FFF, // 高电平
0x0000 // 低电平
};
void generate_square_wave(void){
// 初始化 DMA 描述符结构体
hdma_memtomem_dma1_channel1.Init.Direction = DMA_MEMORY_TO_MEMORY;
hdma_memtomem_dma1_channel1.Instance = DMA1_Channel1;
// 启动 DMA 流程向 DAC 发送数据
HAL_DMA_Start_IT(&hdma_memtomem_dma1_channel1,
(uint32_t)square_wave_data,
(uint32_t)&(DAC->DHR12R1),
sizeof(square_wave_data)/sizeof(uint16_t));
// 开启 DAC 输出通道
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
}
此段代码展示了如何初始化DMA并将预先设定好的高低电平值发送给DAC寄存器以产生周期性的方波输出[^1]。
三角波生成方式
当涉及到更复杂的波形比如三角波时,则需创建一系列逐渐增加或减少幅度直到反转方向为止的数据点集合作为输入源供DMA调用。
#define TRIANGLE_WAVE_POINTS 512
uint16_t triangle_wave_data[TRIANGLE_WAVE_POINTS];
void init_triangle_wave(){
int i;
uint16_t max_value = 0xFFF;
for(i=0;i<TRIANGLE_WAVE_POINTS/2;i++){
triangle_wave_data[i]=i*(max_value/(TRIANGLE_WAVE_POINTS/2));
}
for(;i<TRIANGLE_WAVE_POINTS;i++){
triangle_wave_data[i]=(TRIANGLE_WAVE_POINTS-i)*(max_value/(TRIANGLE_WAVE_POINTS/2));
}
}
void generate_triangle_wave(void){
init_triangle_wave();
// 设置 DMA 参数...
HAL_DMA_Init(&hdma_memtomem_dma1_channel1);
// 将三角波数组传递给 DMA 进行循环传送至 DAC 寄存器
HAL_DMA_Start_IT(&hdma_memtomem_dma1_channel1,
(uint32_t)triangle_wave_data,
(uint32_t)&(DAC->DHR12R1),
TRIANGLE_WAVE_POINTS );
// 开始 DAC 转换过程
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
}
上述程序片段说明了怎样构建一个线性上升再下降的三角波表格,并通过DMA持续不断地重复这个模式从而得到连续不断的三角波输出。
正弦波生成方案
最后来看一下正弦波的例子。由于正弦曲线具有固定的数学表达形式sin(x),因此可以通过计算获得一组近似于理想正弦分布的数据样本用于驱动DAC硬件完成最终目标。
#include <math.h>
#define SINUSOIDAL_WAVE_POINTS 1024
float pi = 3.14159f;
uint16_t sinusoidal_wave_data[SINUSOIDAL_WAVE_POINTS];
void init_sinusoidal_wave(){
float amplitude = 2047; // 半量程范围内的最大振幅
int i;
for(i=0;i<SINUSOIDAL_WAVE_POINTS;i++){
sinusoidal_wave_data[i]=(int)(amplitude*sin((pi*i)/(SINUSOIDAL_WAVE_POINTS/2))+amplitude);
}
}
void generate_sinusoidal_wave(void){
init_sinusoidal_wave();
// ...省略部分相同操作...
// 利用之前准备好的正弦波数据集启动 DMA 数据流
HAL_DMA_Start_IT(&hdma_memtomem_dma1_channel1,
(uint32_t)sinusoidal_wave_data,
(uint32_t)&(DAC->DHR12R1),
SINUSOIDAL_WAVE_POINTS );
// 执行 DAC 的开始命令
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
}
这段示例解释了如何依据正弦函数特性建立合适的离散时间域内表示法,并借助DMA机制高效地将其转化为实际物理层面上的变化电压信号输出。
相关推荐



















