15讲 | STM32通过DAC产生正弦波

一、DAC简介

数字/模拟转换模块(DAC)是 12 位数字输入,电压输出的数字/模拟转换器。

DAC 可以配置为 8 位或 12 位模式,也可以与DMA控制器配合使用。

DAC 工作在 12 位(12位,数字输出范围为 0 ~ 4095 数据可对应参考电压 0 ~ 3.3V,每个数字对应一个电压值)模式时,数据可以设置成左对齐或右对齐。

DAC 模块有 2 个输出通道,每个通道都有单独的转换器。

在双 DAC 模式下,2 个通道可以独立地进行转换,也可以同时进行转换并同步地更新 2 个通道的输出。

DAC 可以通过引脚输入参考电压 VREF+ 以获得更精确的转换结果。


二、DAC通道框图

1)供电为模拟电源供电,参考电压为 Vref+,DORx为转换部分(将数字转换为),DHRx 为设置部分,DAC_OUTx 为输出部分(一般输出 0~3.3V),通过触发,将DHRx的数据传入到控制逻辑然后进行转换。

2)固定周期波形:先设定好DHRx的数据,然后通过定时

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要使用STM32DAC模块产生正弦波,可以使用以下步骤: 1. 初始化DAC模块,包括时钟使能、GPIO配置和DAC配置等; 2. 定义正弦波数组,可以使用sin函数计算出每个采样点的数值; 3. 启动定时器以固定的采样率产生DAC数据; 4. 在定时器中断中,将正弦波数组中下一个采样点数据写入DAC数据寄存器中; 5. 监测DAC中断标志位,确保数据已经输出完毕。 下面是一个基于STM32CubeMX和HAL库的DAC产生正弦波的例子代码: ```c #include "main.h" #include <math.h> #define SAMPLE_RATE 20000 // 20kHz采样率 #define SAMPLE_NUM 100 // 正弦波采样点数 DAC_HandleTypeDef hdac; TIM_HandleTypeDef htim6; static uint16_t sinewave[SAMPLE_NUM]; // 正弦波数据数组 static void MX_GPIO_Init(void); static void MX_DAC_Init(void); static void MX_TIM6_Init(void); void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); int main(void) { HAL_Init(); MX_GPIO_Init(); MX_DAC_Init(); MX_TIM6_Init(); for (int i = 0; i < SAMPLE_NUM; i++) { sinewave[i] = (uint16_t)(2048 * (1 + sin(2 * M_PI * i / SAMPLE_NUM))); // 生成正弦波数据,最大输出值为4095(12位DAC) } HAL_DAC_Start(&hdac, DAC_CHANNEL_1); HAL_TIM_Base_Start_IT(&htim6); while (1) { // Main loop } } static void MX_DAC_Init(void) { DAC_ChannelConfTypeDef sConfig = {0}; hdac.Instance = DAC; if (HAL_DAC_Init(&hdac) != HAL_OK) { Error_Handler(); } sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO; // DAC使用定时器6触发 sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK) { Error_Handler(); } } static void MX_TIM6_Init(void) { TIM_MasterConfigTypeDef sMasterConfig = {0}; htim6.Instance = TIM6; htim6.Init.Prescaler = HAL_RCC_GetHCLKFreq() / (SAMPLE_NUM * SAMPLE_RATE) - 1; // 定时器时钟频率 = 系统时钟 / PSC htim6.Init.CounterMode = TIM_COUNTERMODE_UP; htim6.Init.Period = SAMPLE_NUM - 1; // 计数器从0到99,共100次 if (HAL_TIM_Base_Init(&htim6) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK) { Error_Handler(); } } void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM6) { static uint8_t index = 0; // 当前采样点索引 uint16_t value = sinewave[index]; HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value); // 写入DAC数据寄存器 index = (index + 1) % SAMPLE_NUM; } } static void MX_GPIO_Init(void) { // DAC输出GPIO初始化 GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_4; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } void Error_Handler(void) { // 程序发生错误时停机 while (1) { } } ``` 需要注意的是,当DAC模块输出到外部电路时,需要使用一定的滤波电路来去除采样过程中可能产生的高频噪声。另外,如果要实现多声道输出,可以使用不同的DAC通道,或者使用DMA功能直接传输多通道数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个写代码的修车工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值