RT-Thread Studio学习(十三)DAC

RT-Thread Studio学习(十三)DAC

  • 一、简介
  • 二、新建RT-Thread项目并使用外部时钟
  • 三、启用DAC
  • 四、测试
  • 五、总结

一、简介

本文将基于STM32F407VET芯片介绍如何在RT-Thread Studio开发环境下使用DAC设备。硬件及开发环境如下:

  • OS WIN10
  • STM32F407VET6
  • STM32CubeMX v6.10.0
  • STM32Cube MCU Package for STM32F4 Series v1.28.0
  • RT-Thread Studio v2.2.7
  • RT-Thread Source Code v5.0.2
  • STM32F4 chip support packages v0.2.3

二、新建RT-Thread项目并使用外部时钟

打开RT-Thread Studio软件新建基于芯片的项目,并使用外部时钟系统,具体参见《RT-Thread Studio学习(一)使用外部时钟系统》。

三、启用DAC

  1. 打开DAC驱动框架
    RT-Thread Setting 中借助图形化配置工具打开软件DAC的驱动框架,如下图所示
    在这里插入图片描述
  2. 定义DAC相关的宏
    board.h文件末尾添加:
/*-------------------------- DAC CONFIG BEGIN --------------------------*/

/** if you want to use dac you can use the following instructions.
 *
 * STEP 1, open dac driver framework support in the RT-Thread Settings file
 *
 * STEP 2, define macro related to the dac
 *                 such as     #define BSP_USING_DAC1
 *
 * STEP 3, copy your dac init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
 *                 such as     void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle)
 *
 * STEP 4, modify your stm32xxxx_hal_config.h file to support dac peripherals. define macro related to the peripherals
 *                 such as     #define HAL_DAC_MODULE_ENABLED
 *
 */

#define BSP_USING_DAC1

/*-------------------------- DAC CONFIG END --------------------------*/
  1. 复制DAC初始化函数
    双击RT-Thread Studio工程中的cubemx.ioc文件,使能DAC1和DAC2,具体如下图:
    在这里插入图片描述从使能DAC后再重新生成STM32CubeMX代码,将.\cubemx\Src\dac.c中的函数HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle)复制到board.c的末尾。
void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(dacHandle->Instance==DAC)
  {
  /* USER CODE BEGIN DAC_MspInit 0 */

  /* USER CODE END DAC_MspInit 0 */
    /* DAC clock enable */
    __HAL_RCC_DAC_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**DAC GPIO Configuration
    PA4     ------> DAC_OUT1
    PA5     ------> DAC_OUT2
    */
    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USER CODE BEGIN DAC_MspInit 1 */

  /* USER CODE END DAC_MspInit 1 */
  }
}
  1. 定义.\cubemx\Inc\stm32f4xx_hal_conf.h中的相关宏
#define HAL_DAC_MODULE_ENABLED

四、测试

修改main.c的代码为:

/*
 * Copyright (c) 2006-2024, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-01-15     RT-Thread    first version
 */

#include <rtthread.h>
#include "stm32f4xx.h"
#include <rtdevice.h>

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

// PA4     ------> DAC_OUT1
// PA5     ------> DAC_OUT2
DAC_HandleTypeDef hdac;

#define DAC_DEV_NAME        "dac1"  /* DAC 设备名称 */
#define DAC_DEV_CHANNEL     1       /* DAC 通道 */
#define REFER_VOLTAGE       330         /* 参考电压 3.3V,数据精度乘以100保留2位小数*/
#define CONVERT_BITS        (1 << 12)   /* 转换位数为12位 */


// 设置dac的使用命令 dac_set dac1 1 200
// 第一个参数为命令,第二个参数为 dac 设备名称,第 3 个参数为 dac 通道,
// 第 4 个参数为 dac 输出数值
static int dac_set(int argc, char *argv[])
{
    if(argc!=4)
    {
        rt_kprintf("Usage:    dac_set <device name> <channel> <value>\n");
        rt_kprintf("Example:  dac_set dac1 1 1000\n");
        return RT_ERROR;
    }
    rt_dac_device_t dac_dev;
    rt_uint32_t value, vol, channel;
    rt_err_t ret = RT_EOK;

    char dacdevname[RT_NAME_MAX];

    rt_strncpy(dacdevname, argv[1], RT_NAME_MAX);
    channel = atoi(argv[2]);  // DAC channel
    value = atoi(argv[3]);

    /* 查找设备 */
    dac_dev = (rt_dac_device_t)rt_device_find(dacdevname);
    if (dac_dev == RT_NULL)
    {
        rt_kprintf("dac sample run failed! can't find %s device!\n", dacdevname);
        return RT_ERROR;
    }

    /* 打开通道 */
    ret = rt_dac_enable(dac_dev, channel);

    /* 设置输出值 */
    rt_dac_write(dac_dev, channel, value);
    rt_kprintf("the value is :%d \n", value);

    /* 转换为对应电压值 */
    vol = value * REFER_VOLTAGE / CONVERT_BITS;
    rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);

    /* 延时查看效果,关闭通道后无输出 */
//    rt_thread_mdelay(500);

    /* 关闭通道 */
//    ret = rt_dac_disable(dac_dev, channel);

    return ret;
}

static int dac1_vol_sample()
{
    rt_dac_device_t dac_dev;
    rt_uint32_t value, vol;
    rt_err_t ret = RT_EOK;

    /* 查找设备 */
    dac_dev = (rt_dac_device_t)rt_device_find(DAC_DEV_NAME);
    if (dac_dev == RT_NULL)
    {
        rt_kprintf("dac sample run failed! can't find %s device!\n", DAC_DEV_NAME);
        return RT_ERROR;
    }

    /* 打开通道 */
    ret = rt_dac_enable(dac_dev, DAC_DEV_CHANNEL);

    /* 设置输出值 */
    value=1000;
    rt_dac_write(dac_dev, DAC_DEV_CHANNEL, value);
    rt_kprintf("the value is :%d \n", value);

    /* 转换为对应电压值 */
    vol = value * REFER_VOLTAGE / CONVERT_BITS;
    rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);

    /* 延时查看效果,关闭通道后无输出 */
   // rt_thread_mdelay(500);

    /* 关闭通道 */
   // ret = rt_dac_disable(dac_dev, DAC_DEV_CHANNEL);

    return ret;
}

int main(void)
{
    int count = 1;
    LOG_D("Hello RT-Thread! 2024.1.17");
    LOG_D("System CLock information");
    LOG_D("SYSCLK_Frequency = %d", HAL_RCC_GetSysClockFreq());
    LOG_D("HCLK_Frequency   = %d", HAL_RCC_GetHCLKFreq());
    LOG_D("PCLK1_Frequency  = %d", HAL_RCC_GetPCLK1Freq());
    LOG_D("PCLK2_Frequency  = %d", HAL_RCC_GetPCLK2Freq());
    LOG_D("SysTick->LOAD    = %d", SysTick->LOAD);
    LOG_D("Current tick     = %d", rt_tick_get());
    dac1_vol_sample();
    while (count++)
    {
        LOG_D("Hello RT-Thread! %d", rt_tick_get());
        rt_thread_mdelay(60000);
    }

    return RT_EOK;
}

/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(dac_set, set dac voltage. Useage: dac_set adc1 1 200);

运行结果如下:
在这里插入图片描述
在PA4和PA5脚用万用表测得输出电压为0.8082V

五、总结

不需要在board.h中添加#define BSP_USING_DAC2宏定义,因为dac1的通道2就是dac2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/329164.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

springcloud Eureka服务注册与发现

文章目录 代码地址Eureka基础知识什么是服务治理什么是服务注册与发现 单机版eurekaServerIDEA生成eurekaServer端服务注册中心类似物业公司EurekaClient端cloud-provider-payment8001修改EurekaClient端cloud-consumer-order80 集群Eureka构建步骤新建cloud-eureka-server7002…

告别混乱:文件重命名,删除下划线,让文件管理更高效

在数字时代&#xff0c;经常要处理大量的文件&#xff0c;无论是工作、学习还是生活。文件名中经常有下划线、特殊字符和数字&#xff0c;使得文件管理变得混乱不堪。下面来看云炫文件管理器如何通过文件重命名删除下划线&#xff0c;让文件管理更高效。 文件名下划线被删除前后…

服务器如何重置密码?

服务器重置密码 服务器存在多种操作系统&#xff0c;本篇文章仅以RedHat、银河麒麟、Win Server系统作为举例&#xff01; 如果想了解更多服务器操作系统相关知识&#xff0c;请参看历史文章《服务器操作系统介绍》 银河麒麟破解密码 银河麒麟为国产Linux系统&#xff0c;UOS为…

【iOS】UIColor、CGColor、CIColor的区别和联系

编者在实验室小组的指导下&#xff0c;仿写了许多App&#xff0c;其中UI的颜色模仿也是令人头痛的点。设计颜色一般使用UIColor类方法直接获取颜色&#xff1a; 有时会使用 (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alph…

十大排序算法模板

☆* o(≧▽≦)o *☆嗨~我是小奥&#x1f379; &#x1f4c4;&#x1f4c4;&#x1f4c4;个人博客&#xff1a;小奥的博客 &#x1f4c4;&#x1f4c4;&#x1f4c4;CSDN&#xff1a;个人CSDN &#x1f4d9;&#x1f4d9;&#x1f4d9;Github&#xff1a;传送门 &#x1f4c5;&a…

近4w字吐血整理!只要你认真看完【C++编程核心知识】分分钟吊打面试官(包含:内存、函数、引用、类与对象、文件操作)

&#x1f308;个人主页&#xff1a;godspeed_lucip &#x1f525; 系列专栏&#xff1a;C从基础到进阶 &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于C的优质内容&#xff01;&#x1f3c6;&#x1f3c6; C核心编程&#x1f30f;1 内存分区模型&#x1f384…

在 Jenkins 中使用 SSH Servers 配置文件上传路径

引言 在使用 Jenkins 进行持续集成和持续部署&#xff08;CI/CD&#xff09;的过程中&#xff0c;有时我们需要将构建好的文件上传到远程服务器。本文将介绍如何在 Jenkins 的 SSH Servers 配置中设置文件的上传目录&#xff0c;以及这些设置是如何组合以形成最终的上传路径。…

LLVM的项目结构

所有LLVM项目都有统一的目录结构。让我们比较一下LLVM和GCC&#xff0c;即GNU编译器集合。几十年来&#xff0c;GCC几乎为您能想到的每一个系统都提供了成熟的编译器。但除了编译器&#xff0c;没有任何工具可以用这些代码&#xff0c;原因是它不为重用而设计&#xff0c;而LLV…

【问题记录】使用命令语句从kaggle中下载数据集

从Kaggle中下载Tusimple数据集 1.服务器环境中安装kaggle 使用命令&#xff1a;pip install kaggle 2.复制下载API 具体命令如下&#xff1a; kaggle datasets download -d manideep1108/tusimple3.配置kaggle.json文件 如果直接使用命令会报错&#xff1a; root:~# kagg…

FPGA——时序分析与约束(Quartus II)

FPGA时序分析与约束 FPGA结构基础数据传输模型Quartus II 时序报告Quartus II 中TimeQuest的操作实操 时序分析&#xff1a;通过分析FPGA内部各个存储器之间的数据和时钟传输路径&#xff0c;来分析数据延迟和时钟延迟的关系&#xff0c;保证所有寄存器都可以正确寄存数据。 数…

直流继电器 JT3-22/5 线圈电压DC220V电磁式 柜内固定安装 JOSEF约瑟

JT3系列直流继电器 系列型号 JT3-42/3电磁继电器;JT3A-40/3电磁继电器 JT3-11/3电磁继电器;JT3A-03/3电磁继电器 JT3-30/3电磁继电器;JT3A-20/3电磁继电器 JT3-02/3电磁继电器;JT3A-12/3电磁继电器 JT3-22/1电磁继电器;JT3A-24/1电磁继电器 JT3-42/1电磁继电器;JT3A-31/1电磁…

gin-vue-admin二开使用雪花算法生成唯一标识 id

场景介绍 需求场景&#xff1a; 总部采集分支的数据&#xff0c;由于分支的 id 是子增的主键 id&#xff0c;所以会出现重复的 id&#xff0c;但是这个 id 需要作为标识&#xff0c;没有实际作用&#xff0c;这里选择的是分布式 id 雪花算法生成 id 存储用来标识&#xff0c;这…

NAS入门(学习笔记)

文章目录 AutoMLNAS初期NAS当前NAS框架One-Shot NAS权重共享策略 Zero-Shot NASZen-NASNASWOTEPENAS 参考资料 AutoML 深度学习使特征学习自动化 AutoML 使深度学习自动化 自动化机器学习 (automated machine learning) 是一种自动化的数据驱动方法, 并做出一系列决策。 按…

数据分析-Pandas如何整合多张数据表

数据分析-Pandas如何整合多张数据表 数据表&#xff0c;时间序列数据在数据分析建模中很常见&#xff0c;例如天气预报&#xff0c;空气状态监测&#xff0c;股票交易等金融场景。数据分析过程中重新调整&#xff0c;重塑数据表是很重要的技巧&#xff0c;此处选择Titanic数据…

vue-cli解决跨域

在vue.config.js中 找到devServer 在devServer中创建proxy代理 proxy:{ path&#xff08;路径中包含这个path就会导航到target的目标接口&#xff09;&#xff1a;{ target:"目标接口" } } 例&#xff1a; 1 同源策略只针对于浏览器&#xff0c;代理服务器到后端接…

Linux中的定时任务(案例:定时备份和清空)

前言 Linux中的定时任务&#xff08;案例&#xff1a;定时备份和清空&#xff09; crontab 命令 Linux crontab 是用来定期执行程序的命令, 当安装完成操作系统之后&#xff0c;默认便会启动此任务调度命令。crond 命令每分钟会定期检查是否有要执行的工作&#xff0c;如果有…

CentOS Linux操作系统源码安装最新Redis版本,使用JSON数据类型踩入新坑

最近有空查阅了redis官网&#xff0c;发现redis数据类型不止Strings、Lists、Sets、Hashes、Sorted sets&#xff0c;还多了几种&#xff0c;决定先试用下JSON数据类型 1、安装Redis软件 JSON数据类型&#xff0c;对Redis版本有要求&#xff0c;需要大于4.0版本。下图是华为云…

基础+常用的数据结构

基础 java基础 JDK 和 JRE JDK&#xff0c;它是功能齐全的 Java SDK&#xff0c;是提供给开发者使用&#xff0c;能够创建和编译 Java 程序的开发套件。它包含了 JRE,同时还包含了编译 java 源码的编译器 javac 以及一些其他工具比如 javadoc&#xff08;文档注释工具&#…

前端下载文件流,设置返回值类型responseType:‘blob‘无效的问题

前言&#xff1a; 本是一个非常简单的请求&#xff0c;即是下载文件。通常的做法如下&#xff1a; 1.前端通过Vue Axios向后端请求&#xff0c;同时在请求中设置响应体为Blob格式。 2.后端相应前端的请求&#xff0c;同时返回Blob格式的文件给到前端&#xff08;如果没有步骤…

java农业信息化技术一体化服务农产品商城平台springboot+vue

农业信息化服务平台,能够推进农村农业信息化的发展,提升农业和农村信息化水平,促进先进农业技术在农业生产中的推广应用,推动农业向现代化、集约化发展。同时,进一步探索农村信息化建设的新模式,以技术规划来支撑农业未来信息化管理的发展。 开发软件有很多种可以用&#xff0c…