STM32 HAL库F103系列之DAC实验(一)

news2025/1/13 15:55:31

DAC输出实验

原理图

DAC数据格式

 DAC输出电压

DORX - 数据输出寄存器 

Vref+  == 3.3V

实验简要

1,功能描述

        通过DAC1通道1(PA4)输出预设电压,

        然后由ADC1通道1 (PA1) 采集,最后显示ADC转换的数字量及换算后的电压值

 2,关闭通道1触发(即自动)

         TEN1位置0 

3,关闭输出缓冲

        BOFF1位置1

4,使用12位右对齐模式

        将数字量写入DAC_DHR12R1寄存器

配置步骤

1,初始化DAC

        HAL_DAC_Init()

2DAC MSP初始化

        HAL_DAC_MspInit()     配置NVICCLOCKGPIO

3,配置DAC相应通道相关参数

        HAL_DAC_ConfigChannel()

4,启动D/A转换

        HAL_DAC_Start()

5,设置输出数字量

        HAL_DAC_SetValue()

6,读取通道输出数字量(可选)

        HAL_DAC_GetValue()

相关库函数介绍

关键结构体介绍

typedef struct 
{ 
	DAC_TypeDef *Instance; 			/* DAC 寄存器基地址 */
 	__IO HAL_DAC_StateTypeDef State; 	/* DAC 工作状态 */
 	HAL_LockTypeDef Lock; 			/* DAC 锁定对象 */
 	DMA_HandleTypeDef *DMA_Handle1; 	/* 通道 1 的 DMA 处理句柄指针 */
 	DMA_HandleTypeDef *DMA_Handle2; 	/* 通道 2 的 DMA 处理句柄指针 */
 	__IO uint32_t ErrorCode; 			/* DAC 错误代码 */ 
} DAC_HandleTypeDef; 
typedef struct 
{
 	uint32_t DAC_Trigger; 		/* DAC 触发源的选择 */
 	uint32_t DAC_OutputBuffer; 	/* 启用或者禁用 DAC 通道输出缓冲区 */
 } DAC_ChannelConfTypeDef;

源码

dac.c

#include "./BSP/DAC/dac.h"


DAC_HandleTypeDef g_dac_handle;

/* DAC初始化函数 */
void dac_init(void)
{
    DAC_ChannelConfTypeDef dac_ch_conf;

    g_dac_handle.Instance = DAC;
    HAL_DAC_Init(&g_dac_handle);                                        /* 初始化DAC */

    dac_ch_conf.DAC_Trigger = DAC_TRIGGER_NONE;                         /* 不使用触发功能 */
    dac_ch_conf.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;            /* DAC输出缓冲关闭 */

    HAL_DAC_ConfigChannel(&g_dac_handle, &dac_ch_conf, DAC_CHANNEL_1);  /* 配置DAC通道1 */
    HAL_DAC_Start(&g_dac_handle, DAC_CHANNEL_1);                        /* 开启DAC通道1 */
}

/* DAC MSP初始化函数 */
void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
{
    if (hdac->Instance == DAC)
    {
        GPIO_InitTypeDef gpio_init_struct;

        __HAL_RCC_DAC_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();

        gpio_init_struct.Pin = GPIO_PIN_4;
        gpio_init_struct.Mode = GPIO_MODE_ANALOG;
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);
    }
}

/* 设置通道输出电压 */
void dac_set_voltage(uint16_t vol)/*用0-3300表示0-3.3V*/
{
    double temp = vol;
    temp /= 1000;
    temp = temp * 4096 / 3.3;//DAC输出数据寄存器 - DORX

    if (temp >= 4096)temp = 4095;   /* 如果值大于等于4096, 则取4095 */

    HAL_DAC_SetValue(&g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, temp); /* 12位右对齐数据格式设置DAC值 */
}

dac.h

#ifndef __DAC_H
#define __DAC_H

#include "./SYSTEM/sys/sys.h"


void dac_init(void);
void dac_set_voltage(uint16_t vol);

#endif


main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./BSP/DAC/dac.h"
#include "./BSP/ADC/adc.h"


int main(void)
{
    uint16_t adcx;
    float temp;
    
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟, 72Mhz */
    delay_init(72);                             /* 延时初始化 */
    usart_init(115200);                         /* 串口初始化为115200 */
    led_init();                                 /* 初始化LED */
    lcd_init();                                 /* 初始化LCD */
    key_init();                                 /* 初始化按键 */
    adc_init();                                 /* 初始化ADC */
    dac_init();                                 /* 初始化DAC1_OUT1通道 */

    lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "ADC TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, 16, "ADC1_CH1_VAL:", BLUE);
    lcd_show_string(30, 130, 200, 16, 16, "ADC1_CH1_VOL:0.000V", BLUE); /* 先在固定位置显示小数点 */

    dac_set_voltage(2000);

    while (1)
    {
        adcx = adc_get_result();
        lcd_show_xnum(134, 110, adcx, 5, 16, 0, BLUE);   /* 显示ADCC采样后的原始值 */
 
        temp = (float)adcx * (3.3 / 4096);               /* 获取计算后的带小数的实际电压值,比如3.1111 */
        adcx = temp;                                     /* 赋值整数部分给adcx变量,因为adcx为u16整形 */
        lcd_show_xnum(134, 130, adcx, 1, 16, 0, BLUE);   /* 显示电压值的整数部分,3.1111的话,这里就是显示3 */

        temp -= adcx;                                    /* 把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111 */
        temp *= 1000;                                    /* 小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。 */
        lcd_show_xnum(150, 130, temp, 3, 16, 0X80, BLUE);/* 显示小数部分(前面转换为了整形显示),这里显示的就是111. */

        LED0_TOGGLE();
        delay_ms(250);
    }
}

DAC输出三角波实验

实验简要

1,功能描述

        通过DAC1通道1(PA4)输出三角波,然后通过DS100示波器查看波形

2,关闭通道1触发(即自动)

       TEN1位置0   

3,关闭输出缓冲

        BOFF1位置1

4,使用12位右对齐模式

        将数字量写入DAC_DHR12R1寄存器

 源码

dac.c

#include "./BSP/DAC/dac.h"
#include "./SYSTEM/delay/delay.h"


DAC_HandleTypeDef g_dac_handle;

/* DAC初始化函数 */
void dac_init(void)
{
    DAC_ChannelConfTypeDef dac_ch_conf;
    
    g_dac_handle.Instance = DAC;
    HAL_DAC_Init(&g_dac_handle);
    
    dac_ch_conf.DAC_Trigger = DAC_TRIGGER_NONE;
    dac_ch_conf.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
    HAL_DAC_ConfigChannel(&g_dac_handle, &dac_ch_conf, DAC_CHANNEL_1);

    HAL_DAC_Start(&g_dac_handle, DAC_CHANNEL_1);
}

/* DAC MSP初始化函数 */
void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
{
    if (hdac->Instance == DAC)
    {
        GPIO_InitTypeDef gpio_init_struct;
        
        __HAL_RCC_GPIOA_CLK_ENABLE();
        __HAL_RCC_DAC_CLK_ENABLE();

        gpio_init_struct.Pin = GPIO_PIN_4;
        gpio_init_struct.Mode = GPIO_MODE_ANALOG;
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);
    }
}


void dac_triangular_wave(uint16_t maxval, uint16_t dt, uint16_t samples, uint16_t n)
{
    uint16_t i, j;
    float incval;                               /* 递增量 */
    float Curval;                               /* 当前值 */
    
    if(samples > ((maxval + 1) * 2))return ;    /* 数据不合法 */
        
    incval = (maxval + 1) / (samples / 2);      /* 计算递增量 */
    
    for(j = 0; j < n; j++)
    { 
        Curval = 0;
        HAL_DAC_SetValue(&g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, Curval);    /* 先输出0 */
        for(i = 0; i < (samples / 2); i++)      /* 输出上升沿 */
        {
            Curval  +=  incval;                 /* 新的输出值 */
            HAL_DAC_SetValue(&g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, Curval);
            delay_us(dt);
        }
        for(i = 0; i < (samples / 2); i++)      /* 输出下降沿 */
        {
            Curval  -=  incval;                 /* 新的输出值 */
            HAL_DAC_SetValue(&g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, Curval);
            delay_us(dt);
        }
    }
}

dac.h

#ifndef __DAC_H
#define __DAC_H

#include "./SYSTEM/sys/sys.h"


void dac_init(void);
void dac_triangular_wave(uint16_t maxval, uint16_t dt, uint16_t samples, uint16_t n);

#endif



main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/ADC/adc.h"
#include "./BSP/DAC/dac.h"
#include "./BSP/KEY/key.h"


int main(void)
{
    uint8_t t = 0; 
    uint8_t key;

    HAL_Init();                         /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    delay_init(72);                     /* 延时初始化 */
    usart_init(115200);                 /* 串口初始化为115200 */
    led_init();                         /* 初始化LED */
    lcd_init();                         /* 初始化LCD */
    key_init();                         /* 初始化按键 */
    dac_init();                         /* 初始化DAC1_OUT1通道 */

    lcd_show_string(30,  50, 200, 16, 16, "STM32", RED);
    lcd_show_string(30,  70, 200, 16, 16, "DAC Triangular WAVE TEST", RED);
    lcd_show_string(30,  90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, 16, "KEY0:Wave1  KEY1:Wave2", RED);
    lcd_show_string(30, 130, 200, 16, 16, "DAC None", BLUE); /* 提示无输出 */

    while (1)
    {
        t++;
        key = key_scan(0);                           /* 按键扫描 */

        if (key == KEY0_PRES)                        /* 高采样率 , 100hz波形 , 实际只有65.5hz */
        {
            lcd_show_string(30, 130, 200, 16, 16, "DAC Wave1 ", BLUE);
            dac_triangular_wave(4095, 5, 2000, 100); /* 幅值4095, 采样点间隔5us, 2000个采样点, 100个波形 */
            lcd_show_string(30, 130, 200, 16, 16, "DAC None  ", BLUE);
        }
        else if (key == KEY1_PRES)                   /* 低采样率 , 100hz波形 , 实际99.5hz */
        {
            lcd_show_string(30, 130, 200, 16, 16, "DAC Wave2 ", BLUE);
            dac_triangular_wave(4095, 500, 20, 100); /* 幅值4095, 采样点间隔500us, 20个采样点, 100个波形 */
            lcd_show_string(30, 130, 200, 16, 16, "DAC None  ", BLUE);
        }

        if (t == 10)                                 /* 定时时间到了 */
        {
            LED0_TOGGLE();                           /* LED0闪烁 */
            t = 0;
        }

        delay_ms(10);
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TypeError: Cannot read properties of undefined (reading ‘tapAsync‘)

项目启动&#xff0c;一直报tabAsync未定义&#xff0c;整个项目中没有找到引用的地方&#xff1b; 最终重新安装webpack4版本 解决问题&#xff1b; npm install webpack4

Android studio顶部‘app‘红叉- Moudle ‘XX.app’ dosen’t exist in project

Android studio顶部app红叉- Moudle ‘XX.app’ dosen’t exist in project 1、现象&#xff1a; 运行老项目或者有时候替换项目中的部分代码&#xff0c;明明没有错但是Android studio就编译报错了。 1.1 Android studio顶部app红叉。 1.2 点击Build没有clear菜单&#xff0…

掼蛋赢牌口诀

1、不能做头游&#xff0c;单张暂缓走。 2、起始出单张&#xff0c;表明有大王。 3、单牌先起步&#xff0c;对家应相助。 4、情况尚不明&#xff0c;对子可先行。 5、要想使个坏&#xff0c;就出三不带。 6、小顺往前凑&#xff0c;大顺必殿后。 7、哪张牌先下&#xff0c;倒数…

Electron+Vue3+ElectronForge整合 - 打包时整合 -分步打包

说明 本文介绍一下 Electron Vue3 的打包整合的基本操作。实现的效果是 &#xff1a; 1、一个正常的Vue3项目&#xff1b; 2、整合加入 Electron 框架 &#xff1a;开发时 Electron 加载的是开发的vue项目&#xff1b; 3、完成打包时整合&#xff1a;3.1 先完成vue3项目的正常…

情感识别——情感计算的模型和数据集调查

概述 情感计算指的是识别人类情感、情绪和感觉的工作&#xff0c;已经成为语言学、社会学、心理学、计算机科学和生理学等领域大量研究的主题。 本文将概述情感计算的重要性&#xff0c;涵盖思想、概念和方法。 情感计算是皮卡德于 1997 年提出的一个想法&#xff0c;此后出…

小案例:ToolBar+选项菜单

使用选项菜单&#xff0c;一般是用于做单选&#xff0c;需要重写方法&#xff1a; public boolean onCreateOptionsMenu(Menu menu) 如果想要实现事件监听&#xff0c;则采用基于回调的事件监听机制&#xff0c;可以监听到具体是哪一项被选中。即重写方法&#xff1a; publi…

基于Spring Boot的点餐平台网站设计与实现

基于Spring Boot的点餐平台网站设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 管理员登录界面&#xff0c;通过填写用户名、密码、角色…

OpenHarmony实战开发-性能测试工具SmartPerf Editor使用指导

概述 SmartPerf Editor是一款PC端桌面应用&#xff0c;通过监测、采集应用运行时FPS、CPU、GPU、Memory、Battery、Network等性能数据&#xff0c;帮助开发者了解应用的性能状况。SmartPerf Editor还集成了DrawingDoc功能&#xff0c;可录制Render Service绘制指令&#xff0c…

Idea如何本地调试线上测试服务器代码?

线上出现问题&#xff0c;但是没加日志打印拍脑门惋惜为啥不多打一行日志 加日志重新部署&#xff0c;半小时没了&#xff0c;问题还没有找到&#xff0c;头顶的灯却早已照亮了整层楼...... 排查别人线上的 bug&#xff0c;不仅代码还没看懂&#xff0c;还没一行日志&#…

Linux 终端中的目录切换

目录 ⛳️推荐 前言 理解 Linux 中的路径 利用 cd 命令变更目录 故障解决 文件或目录不存在 非目录错误 特殊目录符号 测试你的知识 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击…

AD 21、22 软件安装教程

AD2022安装包链接 链接&#xff1a;https://pan.baidu.com/s/1oMNbXibQ1Zjl0RTLdPDVGw 提取码&#xff1a;xfs4 软件下载 1.以管理员身份运行 2. 3. 4. 5.路径最好改为C盘以外的&#xff0c;如D盘&#xff0c;要新建一个空文件夹 6. 7.下载好以后 8.在Crack文件夹下找…

内插和抽取

抽取&#xff1a; 频域表达式的关系&#xff1a; 1、角频率扩大M倍 2、移动2pi、22pi…&#xff08;n-1&#xff09; 2pi 3、相加 4、幅度变为1/M 内插&#xff1a; 加入低通滤波&#xff0c;减小混叠&#xff0c;但是由于截短&#xff0c;也会造成误差&#xff0c;但是…

投资网站汇总

1、 中信证券(600030)历年财务指标——亿牛网https://eniu.com/gu/sh600030/cwzb 2、 3、 4、

Linux中文件描述符与重定向的深入探索

目录 1. 理解C语言的文件操作函数 2. 操作系统的文件操作接口 3. 文件描述符详解和其内核本质 4. 如何理解Linux下一切皆文件 5. Linux中的重定向 5.1 输出重定向 5.2 追加重定向 5.3 输入重定向 6. 结合文件描述符理解重定向 7.重定向的系统调用 在Linux操作系统中&a…

Docker容器:镜像与容器命令管理

目录 一、镜像管理命令 1、搜索镜像 2、获取镜像 3、镜像加速下载 4、查看下载的镜像文件信息 5、查看下载到本地的所有镜像 6、获取指定镜像的详细信息 7、为本地的镜像添加新的标签 8、删除镜像 8.1 删除指定的镜像 8.2 批量删除多个镜像 9、导出镜像与导入镜像 …

CUDA线程管理

核函数在主机端启动时&#xff0c;执行会转移到设备上&#xff0c;并且将控制权转移回主机。当核函数在GPU上运行时&#xff0c;主机可以运行其他函数。因此&#xff0c;主机与核函数是异步的。 此时&#xff0c;设备端也就是GPU上会产生大量的线程&#xff0c;并且每个线程都…

汇编期末复习知识点

参考文献1 第一章 概述 组成 计算机系统由硬件子系统和软件子系统组成。硬件子系统&#xff1a;组成计算机系统的所有电子的&#xff0c;机械的&#xff0c;光学的和磁性的元部件。 计算机中常用进制数表示 十进制(Decimal):数据尾部加一后缀D&#xff0c;如2355D二进制&a…

【技巧】Git 版本控制工具没有图标提示怎么办?

Git 版本控制工具在日常开发中使用率是非常高的&#xff0c;多数情况下会安装 TortoiseGit 之类的插件&#xff0c;让文件夹显示图标&#xff0c;方便观察文件的状态。但是有时装完插件之后发现&#xff0c;文件夹/文件并没有图标显示&#xff0c;可以按照以下思路进行排查&…

Git 核心概念与实操

这里写目录标题 1 版本回退2 工作区、暂存区、本地仓库、远程仓库 1 版本回退 原文链接&#xff1a;https://www.liaoxuefeng.com/wiki/896043488029600/897013573512192 首先 git log 查看提交记录 在Git中&#xff0c;用 HEAD 表示当前版本 上一个版本就是 HEAD^ &#xff…

Abaqus2024 安装教程(附免费安装包资源)

鼠标右击软件压缩包&#xff0c;选择“解压到Abaqus2024”。 鼠标右击“此电脑”&#xff0c;选择“属性”。 点击“高级系统设置”。 点击“环境变量”。 点击“新建”。 变量名输入&#xff1a;NOLICENSECHECK 变量值输入&#xff1a;true 然后点击“确定”。 点击“确定”。…