记录一下,方便以后翻阅~
主要内容:
1) DAC数模转换原理;
2) 寄存器和库函数介绍;
3) 相关实验代码解读。
实验功能:系统启动后,按WK_UP键,输出电压加200点,对应电压值200*3.3/4096,按KEY1,输出电压值减200点,每次按键,输出电压值会传至串口调试助手上。
官方资料:《STM32中文参考手册V10》第12章——数字模拟转换DAC
硬件连接
1. 数模转换原理
STM32的DAC模块是12位数字输入,电压输出型的DAC。DAC可以配置为8位或12位模式,也可与DMA控制器配合使用。DAC工作在12位模式时,数据可以设置成左对齐或右对齐。DAC模块有2个输出通道,每个通道有单独的转换器。在双DAC模式下,2个通道可以独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出。DAC可通过引脚输入参考电压VREF+以获得更精确的转换结果。
2. DAC模块特点
2.1 2个DAC转换器,每个转换器对应1个输出通道;
2.2 8位或者12位单调输出;
2.3 12位模式下数据左对齐或者右对齐;
2.4 同步更新功能;
2.5 噪声波形生成;
2.6 三角波形生成;
2.7 双DAC通道同时或者分别转换;
2.8 每个通道都有DMA功能。
3. DAC模块框图

3.1 VDDA和VSSA为DAC模块模拟部分的供电;
3.2 Vref+则是DAC模块的参考电压;
3.3 数字不是写入DORx寄存器里,是写入在DHRx寄存器里;
3.4 DAC_OUTx就是DAC的输出通道了(对应PA4或PA5引脚)。

DAC_OUT1 ->PA4
DAC_OUT2 ->PA5

4. DAC转换

5. DAC数据格式

6. 选择DAC触发

7. DAC输出电压

8. 使能DAC通道

9. 使能DAC输出缓存

如果使能DAC输出缓存的话,虽然输出能力强一点,但是输出没法到0。
10. DAC相关寄存器一览

10.1 DAC控制寄存器DAC_CR

10.2 DAC通道1的12位右对齐数据保持寄存器DAC_DHR12R1

10.3 DAC通道1的12位左对齐数据保持寄存器DAC_DHR12L1

10.4 DAC通道1的8位右对齐数据保持寄存器DAC_DHR8R1

10.5 DAC通道1数据输出寄存器DAC_DOR1

11. DAC一般配置步骤
11.1 使能PA口时钟,设置PA4为模拟输入;
11.2 使能DAC1时钟;
11.3 初始化DAC,设置DAC工作模式;
11.4 使能DAC转换通道;
11.5 设置DAC输出值。
12. 相关实验代码解读
12.1 adc.h头文件代码解读

#ifndef __ADC_H
#define __ADC_H
#include "sys.h"
//申明三个函数//
void Adc_Init(void);
u16  Get_Adc(u8 ch);
u16 Get_Adc_Average(u8 ch,u8 times);
#endif

12.2 adc.c文件代码解读

 #include "adc.h"#include "delay.h"//配置ADC1一般步骤:////1)开启PA口时钟和ADC1时钟,设置PA1为模拟输入;////2)复位ADC1,同时设置ADC1分频因子;////3)初始化ADC1参数,设置ADC1的工作模式以及规则序列的相关信息;////4)使能ADC并校准;////5)配置规则通道参数;////6)开启软件转换;////7)等待转换完成,读取ADC值。////编写Adc_Init初始化函数//
void  Adc_Init(void)
{  ADC_InitTypeDef  ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;//使能GPIOA和ADC1通道时钟//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE );   RCC_ADCCLKConfig(RCC_PCLK2_Div6);                   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M////配置GPIO参数,引脚1,模拟输入//                         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;       //模拟输入引脚GPIO_Init(GPIOA, &GPIO_InitStructure); ADC_DeInit(ADC1);                                   //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值////配置ADC_Init参数//ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                  //独立模式//ADC_InitStructure.ADC_ScanConvMode = DISABLE;                       //单通道模式//ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                 //单次转换模式//ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //软件触发启动//ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;              //ADC数据右对齐//ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure);    ADC_Cmd(ADC1, ENABLE);                      //使能指定的ADC1////以下四个函数用于校准//ADC_ResetCalibration(ADC1);                 //使能复位校准//   while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束//ADC_StartCalibration(ADC1);                 //开启AD校准//while(ADC_GetCalibrationStatus(ADC1));      //等待校准结束//
}
u16 Get_Adc(u8 ch)
{//设置指定ADC的规则组通道,四个入口参数//ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );          ADC_SoftwareStartConvCmd(ADC1, ENABLE);          //使能指定的ADC1的软件转换启动功能// while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));  //等待转换结束//return ADC_GetConversionValue(ADC1);             //返回最近一次ADC1规则组的转换结果//
}
u16 Get_Adc_Average(u8 ch,u8 times)
{u32 temp_val=0;u8 t;for(t=0;t<times;t++){temp_val+=Get_Adc(ch);delay_ms(5);}return temp_val/times;
}

12.3 dac.h头文件代码解读

#ifndef __DAC_H
#define __DAC_H
#include "sys.h"
//申明两个函数//
void Dac1_Init(void);
void Dac1_Set_Vol(u16 vol);
#endif

12.4 dac.c文件代码解读

#include "dac.h"
//DAC1配置步骤包括://
//1)使能PA口时钟,设置PA4为模拟输入;//
//2)使能DAC1时钟//
//3)初始化DAC,设置DAC工作模式//
//4)使能DAC转换通道//
//5)设置DAC输出值//
//DAC通道1输出初始化函数//
void Dac1_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;DAC_InitTypeDef  DAC_InitType;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );              //使能GPIOA通道时钟//RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );                //使能DAC通道时钟// //GPIOA配置,引脚4,模拟输入//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;                           //引脚4//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                       //模拟输入//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_4) ;                                    //PA.4 输出高////DAC初始化配置//    DAC_InitType.DAC_Trigger=DAC_Trigger_None;                          //不使用触发功能//DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;            //不使用波形发生//DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;  //屏蔽、幅值设置,通常配合波形发生使用//DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;            //DAC1输出缓存关闭//DAC_Init(DAC_Channel_1,&DAC_InitType);DAC_Cmd(DAC_Channel_1, ENABLE);                                     //使能DAC1转换通道//DAC_SetChannel1Data(DAC_Align_12b_R, 0);                            //12位右对齐数据格式设置DAC值//
}
//设置通道1输出电压,vol:0~3300,代表0~3.3V//
void Dac1_Set_Vol(u16 vol)
{float temp=vol;temp/=1000;temp=temp*4096/3.3;DAC_SetChannel1Data(DAC_Align_12b_R,temp);                           //12位右对齐数据格式设置DAC值//
}

12.5 main.c文件代码解读

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "dac.h"
#include "adc.h"int main(void){  u16 adcx;float temp; u16 dacval=0;u8 key;delay_init();        //延时函数初始化//  uart_init(115200);   //串口初始化为115200//KEY_Init();          //初始化按键程序//LED_Init();          //LED端口初始化//LED0=1;LED1=1;Adc_Init();          //ADC初始化//Dac1_Init();         //DAC初始化//DAC_SetChannel1Data(DAC_Align_12b_R, 0);          while(1){key=KEY_Scan(0);     if(key==WKUP_PRES){   if(dacval<4000){dacval+=200;LED0=0;                                        //加电压时,LED0亮//}DAC_SetChannel1Data(DAC_Align_12b_R, dacval);  //dacval值<4000时,DAC输出值加200,否则输出值为4000// }else if(key==KEY1_PRES) {if(dacval>200){dacval-=200;LED1=0;                                        //减电压时,LED1亮//}else dacval=0;DAC_SetChannel1Data(DAC_Align_12b_R, dacval);  //dacval值>200时,DAC输出值减200,否则输出值为0// }  if(key==KEY1_PRES||key==WKUP_PRES)               //WKUP或KEY1按下了//{  adcx=DAC_GetDataOutputValue(DAC_Channel_1);     //读取DAC传至ADC的值//printf("电压原始值:%d\n",adcx);                 temp=(float)adcx*(3.3/4096);                    //归一化电压值//    printf("电压实际值:%f\n",temp);}     delay_ms(500); LED0=1; LED1=1;   }}

13. 实验结果

旧知识点
1)复习如何新建工程模板,可参考STM32学习心得二:新建工程模板;
2)复习基于库函数的初始化函数的一般格式,可参考STM32学习心得三:GPIO实验-基于库函数;
3)复习寄存器地址,可参考STM32学习心得四:GPIO实验-基于寄存器;
4)复习位操作,可参考STM32学习心得五:GPIO实验-基于位操作;
5)复习寄存器地址名称映射,可参考STM32学习心得六:相关C语言学习及寄存器地址名称映射解读;
6)复习时钟系统框图,可参考STM32学习心得七:STM32时钟系统框图解读及相关函数;
7)复习延迟函数,可参考STM32学习心得九:Systick滴答定时器和延时函数解读;
8)复习ST-LINK仿真器的参数配置,可参考STM32学习心得十:在Keil MDK软件中配置ST-LINK仿真器;
9)复习ST-LINK调试方法,可参考STM32学习心得十一:ST-LINK调试原理+软硬件仿真调试方法;
10)复习如何对GPIO进行复用,可参考STM32学习心得十二:端口复用和重映射;
11)复习串口通信相关知识,可参考STM32学习心得十四:串口通信相关知识及配置方法;
12)复习ADC原理及一般配置步骤,可参考STM32学习心得二十三:ADC转换原理及模数转换实验和STM32学习心得二十四:内部温度传感器原理及实验和STM32学习心得二十五:光敏传感器原理及实验。

STM32学习心得二十六:DAC数模转换实验相关推荐

  1. STM32学习心得二十四:内部温度传感器原理及实验

    记录一下,方便以后翻阅~ 主要内容: 1) STM32内部温度传感器概述: 2) 相关实验代码解读. 实验功能:系统启动后,实时将内部温度传感器的值传至串口助手上. 官方资料:<STM32中文参 ...

  2. STM32学习心得二十一:实时时钟RTC和备份寄存器BKP特征、原理及相关实验代码解读

    记录一下,方便以后翻阅~ 主要内容 1) RTC特征与原理: 2) BKP备份寄存器特征与原理: 3) RTC常用寄存器+库函数介绍: 4) 相关实验代码解读. 实验内容: 因为没有买LCD屏,所以计 ...

  3. 我的MYSQL学习心得(十六) 优化

    原文:我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看 ...

  4. JavaScript学习(二十六)—事件处理程序的添加与删除

    JavaScript学习(二十六)-事件处理程序的添加与删除 一.什么是事件? 所谓事件就是指用户或页面自身的某些行为,如点击鼠标,敲击键盘都是属于事件. 二.事件处理程序 当事件被触发时会引起某些程 ...

  5. Stduino学习(二十六)水位传感器模块

    37种传感器(二十六)水位传感器模块+Stduino Nano&UNO 本文转载自:http://www.stduino.com/forum.php?mod=viewthread&ti ...

  6. Shell脚本学习-阶段二十六-Web服务与端口

    文章目录-Shell阶段二十六-端口与服务对照表 前言 端口与Web服务对照表 简介 前言 端口与Web服务对照表 2端口:管理实用程序 3端口:压缩进程 5端口:远程作业登录 7端口:回显 9端口: ...

  7. JVM 学习笔记二十六、JVM监控及诊断工具-GUI篇

    二十六.JVM监控及诊断工具-GUI篇 1.工具概述 使用上一张命令行工具或组合能帮您获取目标Java应用性能相关的基础信息,但他们存在下列局限: (1)无法获取方法级别的分析数据,如方法间的调用关系 ...

  8. STM32入门(二十)----DAC

    DAC 理论 数模转换DAC原理 STM32的DAC的特点 框图 常用寄存器 常用库函数 实践 PWMDAC 理论 数模转换DAC原理 STM32的DAC模块(数字/模拟转换模块)是12位数字输入,电 ...

  9. Jenkins 持续集成 概念(学习笔记二十六)

    持续集成:提交.测试.构建.测试.部署 前不久接触了持续集成(Continuous Integration,CI). 一.持续集成是什么 首先说说"集成"的概念.在实际的软件开发中 ...

最新文章

  1. Android 颜色Color(转)
  2. 腾讯----贪吃的小Q
  3. 拆解苹果iPhone11
  4. 阿克曼(Ackmann)函数(信息学奥赛一本通-T1163)
  5. 你是你产品的头号用户
  6. 【温故而知新-Javascript】图片效果(图像震动效果、闪烁效果、自动切换图像)...
  7. java教程 pdf_java教程合集(25本)
  8. 如何计算代码运行的时间?
  9. 论文选题的原则、来源与方法
  10. HD2直刷WP7系统教程及详细说明【ROM+直刷驱动+内存卡工
  11. java.sql.BatchUpdateException: Data truncation: Division by 0
  12. 解决双击.jar包无法运行
  13. 笔记本电脑计算机的配置表,笔记本组装配置清单_笔记本电脑配置单及价格
  14. mysql同步数据_实现MySQL数据库数据的同步方法介绍
  15. google maps js v3 api教程(3) -- 创建infowindow
  16. 奥西tds300服务器维修,奥西Océ TDS300 驱动
  17. 一篇文章教会你将nfc运用到极致
  18. 分析云计算应用究竟有哪些类型
  19. leetcode2187. 完成旅途的最少时间(mid)(282)
  20. 软件功能性测试的21种故障模型

热门文章

  1. 强化学习:Q-Learning
  2. python 操作redis集群
  3. iOS开发之第三方分享QQ分享,史上最新最全第三方分享QQ方式实现
  4. R studio caret package 安装
  5. 如何用div+css布局页面
  6. Single-Stage 6D Object Pose Estimation 论文详解
  7. CG学习prepare
  8. UML-1.用例图 用例表
  9. python正则表达式介绍
  10. 如何快速构建论文初稿