基于RT-Thread的STM32F4开发第三讲——DAC

发布于:2025-05-13 ⋅ 阅读:(11) ⋅ 点赞:(0)


前言

本章利用RT-Thread最新的驱动5.1.0开发DAC模块,使用的开发板是正点原子的STM32F4探索者。很多配置和上文重复,本文不再重复叙述。


一、DAC是什么?

DAC 是 Digital-to-Analog Converter 的缩写,即数模转换器。它是一种电子设备,用于将数字信号(通常是二进制代码)转换为连续的模拟信号(如电压或电流)。在嵌入式系统、通信设备、音频系统等领域有广泛应用。
在STM32F4中DAC 模块是12 位电压输出数模转换器。DAC 可以按 8 位或 12 位模式进行配置,并且可与 DMA 控制器配合使用。在 12 位模式下,数据可以采用左对齐或右对齐。DAC 有两个输出 通道,每个通道各有一个转换器。在 DAC 双通道模式下,每个通道可以单独进行转换;当 两个通道组合在一起同步执行更新操作时,也可以同时进行转换。可通过一个输入参考电压引脚 VREF+ (与 ADC 共享)来提高分辨率。

二、RT-Thread工程创建

首先得到一个RT-Thread的STMF4系列驱动5.1.0不报错工程(RT-Thread studio的驱动5.1.0报错修改
参考上文使用cubemx配置好外设和时钟基于RT-Thread的STM32F4开发第二讲第一篇——ADC
在这里插入图片描述
如图,这是DAC外设的配置。配置好后生成工程
RT-Thread外设初始化整体的流程差不过。

  1. RT-Thread Settings外设开启
  2. 在board.h中预定义宏
  3. 在board.c中粘贴函数HAL_xxx_MspInit和HAL_xxx_MspDeInit
  4. 在stm32xxxx_hal_config.h使能HAL库外设宏定义
    其中第四步cubemx创建工程时已经完成了,不需更改了。其他配置如图
    在这里插入图片描述
    然后进入board.h文件,预定义DAC1的宏,这个文件没有像其他外设(如ADC)预先定义好再注释DAC的宏,需要我们手动添加。
    在这里插入图片描述
    将函数void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle)void HAL_DAC_MspDeInit(DAC_HandleTypeDef* dacHandle)粘贴到board.c中,具体操作看上文。
    用cubemx生成的dac.c文件中的函数void MX_DAC_Init(void),去dac_donfig.h和drv_dac.c中对比初始化配置,更新或补全外设初始化
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
注意drv_dac.c使用了很多预编译指令,如果你的芯片型号不在其中,要手动添加进去。
以上配置好后,工程不报错就可以编写DAC工作函数了

三、DAC函数编写

下面是DAC输出电压计算公式,函数rt_dac_write(dac_handle, DAC_CHANNEl, dac_value)的参数dac_value值就是DOR的值。
在这里插入图片描述

1.DAC.c

#include "DAC.h"
#include "stdlib.h"

#define     DBG_TAG     "dac"
#define     DBG_LVL     DBG_INFO
#include <rtdbg.h>

#define     DAC_ANME   "dac1"
#define     DAC_CHANNEl     1
rt_dac_device_t dac_handle;
void DAC_int(void)
{
    dac_handle = (rt_dac_device_t)rt_device_find(DAC_ANME);
    if(dac_handle == RT_NULL)
    {
        LOG_I("failed to dac handle find");
        return;
    }
    if(rt_dac_enable(dac_handle, DAC_CHANNEl) != RT_EOK){
        LOG_I("failed to dac handle enable");
        return;
    }
    if(rt_dac_write(dac_handle, DAC_CHANNEl, 2000) != RT_EOK){
        LOG_I("failed to dac output set");
        return;
    }
    LOG_I("success to dac handle init");
    return;
}
void dac_voltage(int argc,char **argv)
{
    static int dac_value = 0;
    dac_value = atoi(argv[1]);
    if(dac_value>=0 && dac_value<4096){
        if(rt_dac_write(dac_handle, DAC_CHANNEl, dac_value) != RT_EOK){
            LOG_I("failed to dac output voltage change");
            return;
        }
    }
    else {
        LOG_I("input value error");
    }
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(dac_voltage, dac voltage convert sample);

2.DAC.h

#ifndef APP_ADC_H_
#define APP_ADC_H_

#include <board.h>
#include <rtdevice.h>

int adc_init(void);
int adc_thread_init(void);

#endif /* APP_ADC_H_ */

3.main.c

#include <rtthread.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include "DAC.h"

int main(void)
{
    DAC_int();

    while (1)
    {
        rt_thread_mdelay(1000);
    }

    return RT_EOK;
}

四、结果测试

经过测试,输入的dac_value在0——4095之间,PA4引脚能输出0.15V——3.29V。如果后面结合硬件定时器可以使用DAC的高级功能——输出特定波形

五、工程分享

通过网盘分享的文件:IO_DAC.zip
链接: https://pan.baidu.com/s/121vVZVeXfjvNNqQjDr9_aA?pwd=jykw 提取码: jykw



网站公告

今日签到

点亮在社区的每一天
去签到