STM32CubeMX教程18 DAC - DMA输出自定义波形

这篇具有很好参考价值的文章主要介绍了STM32CubeMX教程18 DAC - DMA输出自定义波形。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、准备材料

开发板(正点原子stm32f407探索者开发板V2.4)

STM32CubeMX软件(Version 6.10.0)

野火DAP仿真器

keil µVision5 IDE(MDK-Arm)

ST-LINK/V2驱动

一台示波器

逻辑分析仪nanoDLA

2、实验目标

使用STM32CubeMX软件配置STM32F407开发板的DAC OUT1实现输出0-3.3V 周期为12.8ms的正弦波形

3、实验流程

3.0、前提知识

由于STM32F407的两个DAC输出通道只能自动生成三角波和噪声波,因此如果想要输出其他的波形可以自己手动定义一个周期内DAC要输出的值,并选择定时器的更新事件作为DAC输出的触发源按顺序输出

这样按照波形采样值的顺序,在每一个触发源到来的时候,手动指定DAC将要输出的值,理论上就可以输出任何我们想要输出的波形,比如正弦波,本实验将以正弦波为例,讲解如何通过DAC的DMA输出正弦波型

当DAC参考电源引脚VREF+接VDDA(3.3V)时,可设置的DAC输出寄存器值范围为0~4095,而DAC的输出范围为0-3.3V,要输出的正弦波sin(x)波形幅值范围为-1~1,因此可以对该波形做一些平移伸缩,将其幅值范围缩放到DAC设置范围0~4095内,变换后的正弦波公式为:y=2047*(sin(x)+1)

在该正弦波形的一个周期0-2pi内平均取128个采样点,然后按照时间先后顺序定义在数组中,每当0.1ms触发源到来的时候,我们就递归的从数组中取出一个值将其设置为DAC的输出值,直到128个采样点全部设置完毕,然后再反复从第一个重新设置,这样就可以大致实现正弦波型

因为需要频繁的从内存取出数据然后写入DAC外设,因此这里比较合适的做法是使用DMA的方式进行,通过上述设置的DAC输出的正弦波形的周期应该为0.1ms*128=12.8ms,正弦波的幅值范围应该为0-3.3V

3.1、CubeMX相关配置

3.1.0、工程基本配置

打开STM32CubeMX软件,单击ACCESS TO MCU SELECTOR选择开发板MCU(选择你使用开发板的主控MCU型号),选中MCU型号后单击页面右上角Start Project开始工程,具体如下图所示

开始工程之后在配置主页面System Core/RCC中配置HSE/LSE晶振,在System Core/SYS中配置Debug模式,具体如下图所示

详细工程建立内容读者可以阅读“STM32CubeMX教程1 工程建立”

3.1.1、时钟树配置

系统时钟使用8MHz外部高速时钟HSE,HCLK、PCLK1和PCLK2均设置为STM32F407能达到的最高时钟频率,具体如下图所示

3.1.2、外设参数配置

在Pinout & Configuration页面左边功能分类栏目Analog中单击其中DAC

在Mode中勾选OUT1 Configuration

选择TIM6的外部触发事件作为DAC OU1输出的触发源,不选择波形生成模式,因为本实验要生成自定义波形

具体配置如下图所示

单击Configuration中的DMA Settings选项卡对DAC的DMA请求进行设置

单击ADD按键增加DMA请求,这里可选的只有一个DAC1

选择想要使用的DMA Stream,并设置优先级,将DMA请求模式设置为循环模式,外设地址不增加,内存地址递增,数据宽度选择字Word

上述配置如下图所示

3.1.3、外设中断配置

在Pinout & Configuration页面左边System Core/NVIC中勾选DMA1 Stream5 全局中断,然后选择合适的中断优先级即可

3.2、生成代码

3.2.0、配置Project Manager页面

单击进入Project Manager页面,在左边Project分栏中修改工程名称、工程目录和工具链,然后在Code Generator中勾选“Gnerate peripheral initialization as a pair of 'c/h' files per peripheral”,最后单击页面右上角GENERATE CODE生成工程,具体如下图所示

详细Project Manager配置内容读者可以阅读“STM32CubeMX教程1 工程建立”实验3.4.3小节

3.2.1、外设初始化调用流程

在生成的工程代码主函数中新增了MX_DMA_Init()函数,该函数对DAC使用的DMA1时钟使能,由于启用了该DMA的中断,因此还对中断优先级及使能进行了配置,如下图所示

DAC的初始化调用流程与“STM32CubeMX教程16 DAC - 输出3.3V内任意电压”实验一致,只是因为本实验配置了DMA,因此在HAL_DAC_MspInit()函数中增加了对使用的DAC1 DMA请求的相关配置代码,如下图所示

3.2.2、外设中断调用流程

DMA全局中断事件回调函数为一个函数指针,当使用HAL_DAC_Start_DMA()函数启动DAC传输时,会将DMA全局中断事件回调函数指针指向具体的函数,这里指向了DAC_DMAConvCpltCh1()函数

在DAC_DMAConvCpltCh1()函数中最终调用了DAC OU1 DMA传输完成中断回调函数HAL_DAC_ConvCpltCallbackCh1(),该函数为虚函数,需要用户重新实现

启用DMA的外设中断调用流程可参考“STM32CubeMX教程12 DMA 直接内存读取”实验3.2.2、外设中断调用流程小节,上述具体过程如下图所述

3.2.3、添加其他必要代码

采集正弦波y=2047*(sin(x)+1)的一个周期2pi内n个采样点,并将其定义在一个uint32_t 数组中,笔者这里定义了128个采样点

为什么非要正弦波函数为y=2047*(sin(x)+1)?

因为DAC的输出范围为0~4095,而sin(x)的输出范围为-1~1,因此需要采集的正弦波采样点最好缩放到0-4095范围,这样输出的波形更好显示

源代码如下所示 (注释1)

/*正弦波数据,12bit,1个周期128个点, 0-4095之间变化*/
const uint32_t userWave[] = 
{
    2047,   2147,	2248,   2347,	2446,	2544,	2641,	2737,
    2830,   2922,	3012,	3099,	3184,	3266,	3346,	3422,
    3494,   3564,	3629,	3691,	3749,	3803,	3852,	3897,
    3938,   3974,	4006,	4033,	4055,	4072,	4084,	4092,
    4094,   4092,	4084,	4072,	4055,	4033,	4006,	3974,
    3938,   3897,	3852,	3803,	3749,	3691,	3629,	3564,
    3494,   3422,	3346,	3266,	3184,	3099,	3012,	2922,
    2830,   2737,	2641,	2544,	2446,	2347,	2248,	2147,
    2047,   1947,	1846,	1747,	1648,	1550,	1453,	1357,
    1264,   1172,	1082,	995 ,	910 ,	828 ,	748 ,	672 ,
    600 ,   530 ,	465 ,	403 ,	345 ,	291 ,	242 ,	197 ,
    156 ,   120 ,	88  ,	61  ,	39  ,	22  ,	10  ,	2   ,
    0   ,   2   ,	10  ,	22  ,	39  ,	61  ,	88  ,	120 ,
    156 ,   197 ,	242 ,	291 ,	345 ,	403 ,   465,	530 ,
    600 ,   672 ,	748 ,	828 ,	910 ,	995 ,	1082,	1172,
    1264,   1357,	1453,   1550,	1648,	1747,	1846,	1947
};

在dac.c中重新实现DAC OU1 DMA传输完成中断回调函数HAL_DAC_ConvCpltCallbackCh1(),源代码如下

/*DAC OUT1 DMA传输完成中断回调函数*/
void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac)
{
    /*翻转RED_LED引脚状态*/
    HAL_GPIO_TogglePin(RED_LED_GPIO_Port,RED_LED_Pin);
}

在main.c文件主函数main中以DMA方式启动DAC输出,源代码如下

HAL_DAC_Start_DMA(&hdac,DAC_CHANNEL_1,userWave,128,DAC_ALIGN_12B_R);
HAL_TIM_Base_Start(&htim6);

4、常用函数

/*以DMA启动DAC输出*/
HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, const uint32_t *pData, uint32_t Length,uint32_t Alignment)
 
/*停止以DMA启动的DAC输出*/
HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel)
 
/*DAC OUT1 DMA传输完成时间中断回调函数*/
void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac)

5、烧录验证

烧录程序,单片机上电后,将示波器的探头挂钩与DAC OUT1引脚PA4相连接,接地环与开发板上的GND引脚连接,将示波器每格电压幅值调节为1.00V,将每格子采集时间调节为10ms,然后开启示波器对DAC OU1输出的波形采集

因为定时器溢出时间为0.1ms,而DMA传输的数据为正弦波一个周期内的128个样本点,因此生成的正弦波周期为128*0.1ms=12.8ms,这与示波器采集到的正弦波波形周期一致,如下图所示为示波器采集到的正弦波形

在DAC OUT1 DMA传输完成时间中断回调函数中翻转了RED_LED(PF9)引脚的状态,经过上述分析知道,传输完成一次所需事件应该为输出正弦波形的周期,也即12.8ms,因此使用逻辑分析仪器采集PF9引脚的状态,发现PF9引脚确实12.8ms翻转一次状态,逻辑分析仪采集的波形如下图所示

6、注释详解

注释1:正弦波数组定义来源 DAC输出正弦波帖子文章来源地址https://www.toymoban.com/news/detail-804445.html

到了这里,关于STM32CubeMX教程18 DAC - DMA输出自定义波形的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 定时器(PWM输出)触发ADC采样(DMA)——STM32CubeMX

    我用的单片机是STM32F103CBTX 定时器:使用PWM输出的模式 ADC:使用DMA的模式 (在不使用DMA的情况下,定时器控制ADC进行数据采集只能是单通道!如果开启了多通道,读取到的ADC采集值只会是最后一个通道的值!所以,要想使用定时器控制ADC采集 多通道 , 必须使用DMA !)  看

    2024年04月10日
    浏览(50)
  • STM32CubeMX教程12 DMA 直接内存读取

    开发板(正点原子stm32f407探索者开发板V2.4) STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK-Arm) ST-LINK/V2驱动 野火DAP仿真器 XCOM V2.6串口助手 使用STM32CubeMX软件配置STM32F407开发板上 串口USART1以DMA方式传输数据 ,然后实现与实验“STM32CubeMX教程9 USART/UART 异步通信”相同的目标

    2024年02月03日
    浏览(81)
  • STM32CubeMX+MDK通过I2S接口进行音频输入输出(全双工读写一个DMA回调)

    目前有一个关于通过STM32F411CEUx的I2S总线接口控制SSS1700芯片进行音频输入输出的研究。 SSS1700 是具有片上振荡器的 3S 高度集成的USB音频控制器芯片 。 SSS1700 功能支持96 KHz 24 位采样率,带外部音频编解码器(24 位/96KHz I2S 输入和输出)并具有内置立体声16/24位ADC、立体声16/24位

    2024年04月12日
    浏览(47)
  • STM32CubeMX教程2 GPIO输出 - 点亮LED灯

    开发板(STM32F407G-DISC1) STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK-Arm) ST-LINK/V2驱动 使用STM32CubeMX软件配置STM32F407开发板点亮LED灯 笔者使用的STM32F407G-DISC1开发板主控制器为STM32F407VGT6,该MCU封装为LQFP 100,一共100个引脚,除去16个POWER引脚、1个NRST引脚和一个BOOT0引脚外,

    2024年02月03日
    浏览(58)
  • STM32CubeMX教程8 TIM 通用定时器 - 输出比较

    开发板(STM32F407G-DISC1) STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK-Arm) ST-LINK/V2驱动 逻辑分析仪nanoDLA 使用STM32CubeMX软件配置STM32F407 通用定时器的输出比较通道 ,并将其输出到四个LED灯引脚实现LED灯流水灯效果 STM32F407的定时器通道均可以实现输出比较功能, 输出比较功

    2024年02月03日
    浏览(77)
  • 【STM32】HAL库 STM32CubeMX——DMA (串口DMA发送接收)

    软件: STM32CubeMX KEIL5 mcuisp 串口通信助手 硬件: STM32F103C8Tx 杜邦线,面包板,USB转TTL DMA,全称Direct Memory Access,即直接存储器访问。 DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。 我们知道系统的运

    2024年02月12日
    浏览(63)
  • STM32实验-输出DAC正弦波

    首先我们知道正弦波的解析式为y=Asin(omiga*x+fei)+b,拓展到STM32中则会得到如下的式子: y=2048*sin((2*pi/samples)*x)+2048. 其中形参的取值范围是(samples/2)maxval,采样的间隔是2*pi/samples。 接下来编写我们的函数代码dac_sin.c: 接下来编写函数头文件dac_sin.h: 最后编写主函数main.c: 到这

    2024年02月15日
    浏览(30)
  • 【STM32 CubeMX】串口编程DMA

    在嵌入式系统中,串口通信是一项至关重要的功能,它允许单片机与外部设备进行数据交换,如传感器、显示器或其他设备。然而,在高速数据传输的场景下,传统的串口通信方式可能会使CPU过于繁忙,从而影响系统的性能。为了解决这一问题,STM32系列微控制器提供了DMA(

    2024年02月20日
    浏览(56)
  • STM32实验-PWM DAC模拟输出

    一般一个STM32只有2个DAC输出通道,如果需要多路DAC输出,可以选择外扩DAC,但成本回相当高。于是在一些精度要求不高的场合,我们采用定时器输出PWM和RC滤波器模拟DAC来代替外扩DAC。 PWM占空比可由以下式子计算出:p = n / N (n是on的时间,即带宽,N是周期) PWM周期是由ARR决定

    2024年02月08日
    浏览(40)
  • 【stm32】DAC输出三角波锯齿波

    导入DAC.ioc(见上节DAC学习笔记) CubeMX图形化配置 DAC配置 实现0.1ms定时周期 时钟树配置 程序编写 实现效果 采用CubeMonitor监测生成波形 也可用示波器检测波形生成结果 在此处更改配置 使用DMA触发任意波形 若要调整锯齿波的周期,修改TIM6的分频系数和计数周期即可 程序编写

    2024年02月22日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包