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

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输出数据寄存器 - DORXif (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://xiahunao.cn/news/2979082.html

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

相关文章

2024平替电容笔买哪个品牌好?iPad电容笔全能榜单热门款TOP5分享!

2024年&#xff0c;随着科技的不断发展和消费者对生活品质的追求&#xff0c;电容笔作为一种创新的无纸化工具&#xff0c;逐渐走进人们的生活和工作中。然而&#xff0c;在电容笔市场的繁荣背后&#xff0c;也隐藏着品质良莠不齐的现象。众多品牌为了追求利润&#xff0c;推出…

SCSS全局配置 vue项目(二)

目录 1、先要查看node版本 2、安装对应的node-sass、sass-loader版本 2.1根据项目使用的node版本安装对应的node-sass版本 2.2根据node-sass版本选择兼容的sass-loader版本&#xff0c;不然项目无法正常运行 3、在 vue.config.js 中配置&#xff1a; 4、在组件中…

QT QZipReader改进,以支持大于2G的zip文件

QZipReader对ZIP文件读取非常方便好用。即使在最新版的QT 6.6.1里&#xff0c;仍然存在一些问题&#xff1a;对于大于2G的zip文件不支持。 虽然有标准zlib可调用&#xff0c;但包装成一个易用且功能成熟的zip解压功能库&#xff0c;还是有很大的工作量&#xff0c;也需要有一定…

【理性讨论】进口主食冻干高价是不是智商税?SC主食冻干全解+测评分享

说到高端主食冻干产品&#xff0c;SC无疑是其中的明星品牌。无论是在哪个平台搜索“主食冻干”等关键词&#xff0c;SC都能轻松进入视线。在双11、618等促销活动中&#xff0c;尽管SC的价格相对较高&#xff0c;但其销量却还不错&#xff0c;这足以说明众多宠物主人对SC冻干品质…

国产技术迎来突破,光量子芯片横空出世,中文编程也有好消息

国外光刻机不再牛&#xff0c;随着这项技术问世&#xff0c;我们摆脱芯片卡脖子困境成为可能&#xff01; 欧美国家在科技领域一直遥遥领先&#xff0c;那我们该如何实现后来居上呢&#xff1f;答案就在于我国在全球处于领先地位的量子科技&#xff0c;以及新近问世、令人瞩目…

如何在React中构建动态下拉组件 - 解释React复合组件模式

下拉菜单长期以来一直是网站和应用程序中的重要组成部分。它们是用户交互的默默英雄&#xff0c;通过简单的点击或轻触默默地促进着无数的操作和决策。 今天你可能已经遇到了其中之一&#xff0c;无论是在你最喜爱的在线商店上选择类别&#xff0c;还是在注册表单上选择你的出…

骨传导耳机哪个牌子好?5款年度精品骨传导耳机推荐

在骨传导耳机最开始出现的时候&#xff0c;相信很多人都只关心骨传导耳机的外观颜值和特殊的传声方式&#xff0c;但当你真正用过一段时间后&#xff0c;对骨传导耳机有了更加深入的了解后就会关注到骨传导耳机的使用体验、音质表现、蓝牙性能等具体功能&#xff0c;而随着骨传…

上位机图像处理和嵌入式模块部署(树莓派4b的一种固件部署方法)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 如果软件开发好了之后&#xff0c;下面就是实施和部署。对于树莓派4b来说&#xff0c;部署其实就是烧录卡和拷贝文件。之前我们烧录卡&#xff0c;…

RK3568 学习笔记 : u-boot 千兆网络无法 ping 通PC问题的解决

前言 开发板型号&#xff1a; 【正点原子】 的 RK3568 开发板 使用 虚拟机 ubuntu 20.04 收到单独 编译 RK3568 u-boot 【问题】u-boot 千兆网络无法ping 通&#xff1f;Linux 下千兆网络正常&#xff0c;说明&#xff1a;开发板硬件正常 u-boot 下网络如果通了&#xff0c;…

Unity的旋转实现一些方法总结(案例:通过输入,玩家进行旋转移动)

目录 1. Transform.Rotate 方法 使用 2. Transform.rotation 或 Transform.localRotation 属性与四元数 使用方式&#xff1a; 小案例 &#xff1a;目标旋转角度计算&#xff1a;targetRotation&#xff08;Quaternion类型&#xff09; 玩家发现敌人位置&#xff0c;玩家…

【数据结构】AVL树(万字超详细 附动图)

一、前言 二、AVL树的性质 三、AVL树节点的定义 四、AVL树的插入 五、AVL树的平衡调整 六、AVL树的验证 6.1 验证有序 6.2 验证平衡 七、AVL树的删除 八、AVL树的性能和代码 一、前言 还没有学习过二叉搜索树的同学可以移步 【数据结构】二叉搜索树-CSDN博客https:/…

【C++】:构造函数和析构函数

目录 前言一&#xff0c;构造函数**1.1 什么是构造函数****1.2 构造函数的特性**1.3 总结 二&#xff0c;析构函数**2.1 什么是析构函数****2.2 析构函数的特性****2.3 总结** 前言 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并…

WebGL绘制和变换三角形

1、绘制多个点 构建三维模型的基本单位是三角形。不管三维模型的形状多么复杂&#xff0c;其基本组成部分都是三角形&#xff0c;只不过复杂的模型由更多的三角形构成而已。 gl.vertexAttrib3f()一次只能向顶点着色器传入一个顶点&#xff0c;而绘制三角形、矩形和立方体等&am…

mysql内存优化

临时更改 查看缓冲池大小 show variables like innodb_buffer_pool_size%;通过sql修改&#xff0c;重启后会失效 SET GLOBAL innodb_buffer_pool_size 4294967296;字节转换网站 永久更改 通过my.cnf配置修改&#xff0c;永久生效 进入mysql容器&#xff0c;vi /etc/my.cnf…

良品生活(C端产品设计)

一、产品定义 用户 人群&#xff1a;有某种兴趣的人群&#xff08;喜欢无印良品的商品&#xff09;。 需求&#xff1a;对某种兴趣有内容消费需求&#xff0c;同时也有与别人分享内容的兴趣。 角色&#xff1a;普通用户&#xff0c;内容创作者。 公司 诉求&#xff1a;通…

绿联 安装transmission

绿联 安装transmission及中文UI 1、镜像 linuxserver/transmission:latest 2、安装 2.1、创建容器 按需配置权重。 2.2、基础设置 2.3、网络 桥接即可。 注&#xff1a;如果使用IPV6&#xff0c;请选择"host"模式。 注&#xff1a;如果使用IPV6&#xff0c;请选…

武汉大学博士,华为上班5年多,月薪多少。。。

最近&#xff0c;一位来自武汉大学的博士研究生透露了自己在华为公司工作五年后的薪酬情况。 据他透露&#xff0c;他在2018年加入华为时的月薪为2.4万&#xff0c;随着时间的推移&#xff0c;到了2023年&#xff0c;他的月薪已经增长至4.4万&#xff01;此外&#xff0c;他还透…

某翻译平台翻译接口逆向之加解密参数刨析

上文链接 某翻译平台翻译接口逆向之webpack学习 分析参数 加密参数&#xff1a; ${t} function S(e, t) {return _(client${u}&mysticTime${e}&product${d}&key${t}) } function k(e, t) {const n (new Date).getTime();return {sign: S(n, e),client: u,produc…

vue实现水平排列且水平居中

样式实现 .body{text-align: center; } .body_content{display: inline-block; } .body_content_cardList{display: flex;flex-wrap: wrap;text-align: center; }<div class"body"><div class"body_content"><div class"body_content…