这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【转载】STM32的DAC生成正弦波、三角波、方波--from森

共1条 1/1 1 跳转至

【转载】STM32的DAC生成正弦波、三角波、方波--from森

工程师
2024-12-19 19:22:50     打赏

一、获取波函数数据表

这一步是让ai写的,下面是sin函数的matlab的程序,其他波函数也可参考。

我是成txt文件后复制,直接输出再复制也一样。

可以在一些在线网站跑这类代码,推荐一个免费的代码在线运行 - 锤子在线工具 (toolhelper.cn),让ai改一下代码就行。

% DAC输出范围(12位DAC)

DAC_range = 2^12; % 4096个离散级别

% 生成正弦波形数组

num_samples = 256;

t = linspace(0, 2*pi, num_samples); % 时间从0到2*pi,等分成512份

sin_wave = sin(t);

% 将正弦波形归一化到DAC输出范围(0到4095)

normalized_sin_wave = (sin_wave + 1) * (DAC_range - 1) / 2;

% 将归一化的数组四舍五入为整数

dac_output_values = round(normalized_sin_wave);

% 绘制DAC输出波形

figure;

plot(dac_output_values);

title('DAC输出正弦波形');

xlabel('样本');

ylabel('DAC输出值');

grid on;

% 将数组保存到文件中

writematrix(dac_output_values, 'dac_output_values.txt');

disp('DAC输出值已保存到文件:dac_output_values.txt');

 核心代码是将sin从[-1,1]的值域转换到DAC输出范围[0,4095]。

% 将正弦波形归一化到DAC输出范围(0到4095)

normalized_sin_wave = (sin_wave + 1) * (DAC_range - 1) / 2;

% 将归一化的数组四舍五入为整数

dac_output_values = round(normalized_sin_wave);

放一组等分成64个点的sin函数数据表

2048,2251,2453,2651,2843,3027,3201,3364,3513,3648,3767,3870,3953,4018,4064,4089,4094,4079,4044,3988,3914,3821,3710,3583,3440,3284,

3115,2936,2748,2553,2353,2150,1945,1742,1542,1347,1159,980,811,655,512,385,274,181,107,51,16,1,6,31,77,142,225,328,447,582,731,894,1068,1252,1444,1642,1844,2047

二、stm32代码

1.DAC配置

我这里把dac相关的配置放一起了

1.dac

 在参考手册可以看到,A4会自动作为输出引脚,需要设置成AIN模式

屏幕截图 2024-12-19 191715.png

/*GPIO初始化*/

GPIO_InitTypeDef GPIO_InitStructure; //定义结构体

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入模式

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //GPIO引脚A4

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO速度50MHz

GPIO_Init(GPIOA, &GPIO_InitStructure);

dac参数配置

DAC_Trigger:触发方式

DAC_WaveGeneration:是否生成波。stm32的DAC可以生成噪声和三角形波两种波

DAC_LFSRUnmask_TriangleAmplitude:生成波的幅值

DAC_OutputBuffer:输出缓冲。

/*DAC_InitStruct 参数初始化*/

DAC_InitTypeDef DAC_InitStruct;

 

DAC_InitStruct.DAC_Trigger = DAC_Trigger_T2_TRGO;      //触发方式:定时器2触发

DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None;  //不生成波形

DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;

DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Enable;   //输出缓冲使能

DAC_Init(DAC_Channel_1,&DAC_InitStruct);  //

2.定时器

可以通过定时器触发周期和等份点数,计算最后波的频率。

1.png

TIM_PrescalerConfig(TIM2,36-1,TIM_PSCReloadMode_Update);

TIM_SetAutoreload(TIM2,1000-1);

TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update);

3.dma

 dma即直接内存访问,我们这里使用DMA,将自己设置的数组,搬运到DAC发送数据的地址,也就是从存储器到外设。自己使用需要更改地址,

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)sin_wave ,把sin_wave换成自己设置的数组

 

/*DMA初始化*/

DMA_InitTypeDef DMA_InitStructure; //定义结构体变量

 

DMA_InitStructure.DMA_PeripheralBaseAddr =  (uint32_t)&DAC -> DHR12R1;   //外设基地址

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据宽度,选择半字

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址自增,选择失能

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)sin_wave ;           //存储器基地址

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //存储器数据宽度,选择半字,与源数据宽度对应

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /存储器地址自增,选择使能,每次转运后,数组移到下一个位置

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,选择由存储到外设

DMA_InitStructure.DMA_BufferSize = 512; //转运的数据大小

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //模式,选择循环模式

DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先级,选择中等

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存

DMA_Init(DMA2_Channel3, &DMA_InitStructure); //将结构体变量交给DMA_Init,配置DMA2的通道3

三、示波器效果

频率和理论值差不多

1734607301298708.jpeg

1734607311791304.jpeg

总结

全文讲解了stm32使用dac生成波的全流程,对其中一些参数进行解释说明。

来源: 整理文章为传播相关技术,网络版权归原作者所有,如有侵权,请联系删除。              





共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]