STM32CubeMX系列 | DAC数模转换

发布者:InnovateMind最新更新时间:2023-03-21 来源: zhihu关键字:STM32CubeMX系列  DAC  数模转换 手机看文章 扫描二维码
随时随地手机看文章

1. DAC简介

DAC(digital to analog converter)即数模转换器,它可以将数字信号转换为模拟信号,它的功能与ADC相反。在常见的数字信号系统中,大部分传感器信号被转化成电压信号,而ADC把电压模拟信号转换成易于计算机存储、处理的数字编码,由计算机处理完成后,再由DAC输出电压模拟信号来驱动某些执行器件,使人类易于感知。如音频信号的采集和还原就是这样的一个过程 STM32F1的DAC模块是12位数字输入,电压输出型的DAC。可以配置为8位或12位模式,也可以与DMA控制器配合使用,DAC工作在12位模式下时,数据可以设置为左对齐或右对齐。DAC模块有2个输出通道,每个通道都有单独的转换器。在双DAC模式下,2个通道可以独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出。DAC可以通过引脚输入参考电压 VREF 以获得更精确的转换结果。DAC结构框图如下示:

  • VDDA 和 VSSA 是DAC模块的供电引脚, VREF+ 是DAC模块的参考电压,DAC_OUTx是DAC的输出通道;当参考电压为 VREF+ 时,DAC的输出电压是线性的(0~ VREF+ ),12位模式下DAC输出电压计算公式如下:
    DACx 输出电压 = VREF+ * ( DORx / 4095 )

  • DAC输出是受DORx 寄存器直接控制的,但是不能直接往DORx 寄存器写入数据,而是要通过DHRx间接的传给DORx 寄存器,实现对DAC输出的控制。如果未选择硬件触发,1个APB1时钟周期后,DHRx中存储的数据将自动转移到DORx 寄存器;如果选择硬件触发,将在3个APB1时钟周期后进行转移

  • 当DORx加载了DHRx内容时,模拟输出电压将在一端时间 tSETTING 后可用,具体取决于电源电压和模拟输出负载,可以从数据手册查到 tSETTING 的典型值为3us,最大值为4us,因此DAC的转换速度最快是250K左右

  • DAC可通过外部事件(定时器、外部中断线)触发转换,外部触发源列表如下示

2. 硬件设计

本实验通过D1指示灯来提示系统运行状态,K_UP用来增加DAC输入值,K_DOWN用来减少DAC输入值,输入值的改变将控制DAC_OUT1的电压输出,通过USART1将输出的电压值打印出来

  • D1指示灯

  • DAC_OUT1(PA4)

  • USART1串口

  • K_UP和K_DOWN按键

3. 软件设计

3.1 STM32CubeMX设置

  • RCC设置外接HSE,时钟设置为72M

  • PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平

  • USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位

  • PA0设置为GPIO输入模式、下拉模式;PE3设置为GPIO输入模式、上拉模式

  • 激活DAC_OUT1,关闭输出缓冲,不使用触发功能

  • 输入工程名,选择工程路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码

3.2 MDK-ARM编程

  • 在dac.c文件中可以看到DAC初始化相关函数

void MX_DAC_Init(void){

  DAC_ChannelConfTypeDef sConfig = {0};

  /** DAC Initialization */

  hdac.Instance = DAC;

  if (HAL_DAC_Init(&hdac) != HAL_OK){

    Error_Handler();

  }

  /** DAC channel OUT1 config */

  sConfig.DAC_Trigger = DAC_TRIGGER_NONE;   //不使用触发功能

  sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;  //输出缓冲关闭

  if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK){

    Error_Handler();

  }

}


void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle){

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  if(dacHandle->Instance==DAC)  {

  /* DAC clock enable */

  __HAL_RCC_DAC_CLK_ENABLE();   //使能DAC时钟

  __HAL_RCC_GPIOA_CLK_ENABLE(); 

  GPIO_InitStruct.Pin = GPIO_PIN_4;

  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;  //模拟

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  }

}

创建按键驱动文件key.c 和相关头文件key.h

uint8_t KEY_Scan(uint8_t mode){

    static uint8_t key = 1;     

    if(mode == 1){                      

        key = 1;

    }


    if(key&&(KEY_UP==1||KEY_DOWN==0||KEY_LEFT==0||KEY_RIGHT==0)){

        HAL_Delay(10);                  

        key = 0;

        if(KEY_UP==1)               return KEY_UP_PRES;

        else if(KEY_DOWN==0)        return KEY_DOWN_PRES; 

        else if(KEY_LEFT==0)        return KEY_LEFT_PRES; 

        else if(KEY_RIGHT==0)       return KEY_RIGHT_PRES; 

    }

    else if(KEY_UP==0&&KEY_DOWN==1&&KEY_LEFT==1&&KEY_RIGHT==1){

        key = 1;

    }   

    return 0;

}

在main.c文件下编写DAC测试代码

int main(void){

  /* USER CODE BEGIN 1 */

  uint16_t dac_val;     //读取的DAC值

  float dac_vol;        //转换后的电压值

  uint8_t t = 0;

  uint16_t dac_setval = 0;  //DAC设置值

  uint8_t key;

  /* USER CODE END 1 */

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  MX_DAC_Init();

  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */

  HAL_DAC_Start(&hdac,DAC_CHANNEL_1);   //开启DAC通道1

  HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,0);  //设置初始值为0

  /* USER CODE END 2 */

  while (1){

    t++;

        key = KEY_Scan(0);

        if(key == KEY_UP_PRES){

            if(dac_setval < 4000)

                dac_setval += 200;

            HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,dac_setval);

        }

        else if(key == KEY_DOWN_PRES){

            if(dac_setval > 200)

                dac_setval -= 200;

            else

                dac_setval = 0;

            HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,dac_setval);

        }


        if(t == 10 || key == KEY_UP_PRES || key == KEY_DOWN_PRES){  //按键按下了或定时时间到

            dac_val = HAL_DAC_GetValue(&hdac,DAC_CHANNEL_1);

            printf("DAC_OUT1 DAC value: %drn",dac_val);

            dac_vol = dac_val * (3.3/4096);

            printf("DAC_OUT1 VOL value: %.2fVrn",dac_vol);

            printf("rn");

            t = 0;

        }

        HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);

        HAL_Delay(100);

  }

}

4. 下载验证

编译无误后下载到开发板,可用看到D1指示灯不断闪烁,同时打印出DAC通道1的DAC值和电压值,当按下K_UP按键输出电压增大,按下K_DOWN按键输出电压减小


关键字:STM32CubeMX系列  DAC  数模转换 引用地址:STM32CubeMX系列 | DAC数模转换

上一篇:STM32CubeMX系列 | 内部温度传感器
下一篇:STM32CubeMX系列 | I2C总线

推荐阅读最新更新时间:2024-11-05 06:54

STM32CubeMX系列 | 外部中断
1. 外部中断简介 STM32F1的每个IO口都可以作为外部中断的中断输入,STM32F103的中断控制器支持19个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103的19个外部中断为: EXTI线0~15:对应外部IO口的输入中断 EXTI线16:连接到PVD输出 EXTI线17:连接到RTC闹钟事件 EXTI线18:连接到USB唤醒事件 EXTI线19:连接到以太网唤醒事件(互联网型产品) STM32F103供IO口使用的中断线只有16个,但是IO口却远不止16个。下图为GPIO跟中断线的映射关系图 2. 硬件设计 用到的硬件资源有: 指示灯D1、D2 蜂
[单片机]
高速/高精度视频DAC芯片 CS7123
CS7123芯片是深圳市芯海科技有限公司自主设计的高速/高精度视频DAC芯片,其内部包括三路10位电流导引(Current Steering)结构的DAC,最大采样速度达到240MHz。CS7123结构框图见图1,它包括三路高速、10位输入的视频DA转换器、标准的TTL输入和互补输出高阻抗的模拟输出电流源。它有三路独立的10位输入端口,可以在单电源5V下工作,也可以在单电源3.3V下工作。   CS7123还有SYNC同步信号和BLANK黑电平控制信号这两个附加的视频控制信号,CS7123也具有一个待电模式。CS7123采用5V CMOS工艺制造,单片CMOS结构确保了低功耗性能。CS7123的主要功能是将三路RGB信号转换为模
[模拟电子]
高速/高精度视频<font color='red'>DAC</font>芯片 CS7123
51单片机使用DAC0832编程输出方波,锯齿波,三角波,正弦波
#include reg51.h #include math.h #define uchar unsigned char #define uint unsigned int #define PI 3.1415925 float alph; void delayms(uint x) { uchar i; while(x--); { for(i=0;i 123;i++); } } main() { uchar i; while(1) { for(alph=0;alph 2*PI;alph+=0.1) { P2=1
[单片机]
51单片机使用<font color='red'>DAC</font>0832编程输出方波,锯齿波,三角波,正弦波
STM32CubeMX系列 | 红外遥控
1. 红外遥控简介 红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低,成本低,易实现等显著优点,被诸多电子设备特别是家用电器广泛采用,并越来越多的应用到计算机系统中。 由于红外线遥控不具有像无线电遥控那样穿过障碍物去控制被控对象的能力,所以,在设计红外线遥控器时,不必要像无线电遥控器那样,每套(发射器和接收器)要有不同的遥控频率或编码(否则,就会隔墙控制或干扰邻居的家用电器),所以同类产品的红外线遥控器,可以有相同的遥控频率或编码,而不会出现遥控信号“串门”的情况。这对于大批量生产以及在家用电器上普及红外线遥控提供了极大的方面。由于红外线为不可见光,因此对环境影响很小,再由红外光波动波长远小于无线电波的波
[单片机]
ADI精密16位数模转换器AD5421
ADI AD5421,集成有4至20 mA、16位数模转换器和片上电源管理电路,非常适合环路供电的智能变送器应用,可以增强与远程工业设备的连接。针对环路供电设计选择电子器件时,功耗是首要考虑因素。AD5421的低功耗特性和智能电源管理电路,使之成为理想的解决方案。AD5421所提供的额外系统电源可以用于支持其它附加功能,例如额外的通信协议或连接显示器。过程控制行业要求高生产效率,AD5421的出色性能规格有利于满足这一需求,提高智能变送器测量的精度和可重复性。这款器件针对恶劣的工业环境而设计,稳定可靠,只需极少的设计工作就能实现高端性能。
[模拟电子]
STM32CubeMX系列 | TFTLCD显示
1. 简介 1.1 TFTLCD简介 TFT-LCD(thin film transistor-liquid crystal display)即薄膜晶体管液晶显示器。液晶显示屏的每一个像素上都设置有一个薄膜晶体管(TFT),每个像素都可以通过点脉冲直接控制,因而每个节点都相对独立,并可以连续控制,不仅提高了显示屏的反应速度,同时可以精确控制显示色阶,所以TFT液晶的色彩更真,因此TFT-LCD也被叫做真彩液晶显示器 常用的TFT液晶屏接口有8位、9位、16位、18位,这里的位数表示的是彩屏数据线的数量。常用的通信模式有6800模式和8080模式,本例程使用8080并口模式(简称80并口),8080接口有5条基本的控制线和多条数据线
[单片机]
如何成功校准开环DAC信号链
How to Successfully Calibrate an Open-Loop DAC Signal Chain 如何成功校准开环DAC信号链 简介 任何实际的电子应用都会受到多个误差源的影响,这些误差源可以使得最精密的元器件偏离其数据手册所述的行为。当应用信号链没有内置机制来自我调整这些误差时,最大程度降低误差影响的唯一方法是测量误差并系统地予以校准。 开环系统为了实现所需的性能,不使用输出来调整输入端的控制操作,而在闭环系统中,输出依赖于系统的控制操作,系统可以自动实施校正以提高性能。大多数数模转换器(DAC)信号链是“设置后不管”类型的系统,其输出的精度依赖于信号链中每个模块的精度。“设置后不管”
[模拟电子]
如何成功校准开环<font color='red'>DAC</font>信号链
升压电源和高压DAC为天线和滤波器提供调谐信号
  天线阵列和 滤波器 常常通过改变钛酸钡锶(BST)电容上的电压来进行调谐。将这种铁电材料应用于电容时,只需施加一个电压,即可导致其晶体结构发生细小的变化,从而改变其介电常数,电容值因而随之改变。相比于传统的变容二极管,电子可调谐BST电容能够处理更高的功率和更大的信号幅度。   在典型应用中,调谐电容可补偿器件容差,调整滤波器的截止频率,或者匹配可调谐天线的网络阻抗。BST电容的调谐是通过施加0 V至30 V的电压来实现。现代电子器件所用的电源电压呈现越来越低的趋势,3.3 V、2.5 V甚至1.8 V电源已成为常用电源,尤其是在电池供电的应用中。如果仅仅针对这一功能而增加一个单独的电源,尽管可以获得调谐的好处,但并不
[电源管理]
升压电源和高压<font color='red'>DAC</font>为天线和滤波器提供调谐信号
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved