• (28)STM32——DAC数模转换笔记


    目录

    学习目标

    成果展示 

    介绍

    特点

    框图

    数据格式

    触发选择

    寄存器

    硬件 

    配置

    代码 

    总结 


    学习目标

            本节学习的是有关DAC的知识点,主要进行的是数字信号到模拟信号的转换,内容其实和我们之前学51的时候是类似的,在此就不做过多介绍,如果对AD/ DA有不太了解的同学还是建议先去看一下51的AD/DA转换。

    成果展示 

    DAC

    介绍

            STM32F4 的 DAC 模块(数字/模拟转换模块)是 12 位数字输入,电压输出型的 DAC。DAC 可以配置为 8 位或 12 位模式,也可以与 DMA 控制器配合使用。DAC 工作在 12 位模式时, 数据可以设置成左对齐或右对齐。DAC 模块有 2 个输出通道,每个通道都有单独的转换器。 在双 DAC 模式下,2 个通道可以独立地进行转换,也可以同时进行转换并同步地更新 2 个 通道的输出。DAC 可以通过引脚输入参考电压 Vref+(通 ADC 共用)以获得更精确的转换结果。

    特点

    • 2 个 DAC 转换器:每个转换器对应 1 个输出通道
    • 8 位或者 12 位单调输出
    • 12 位模式下数据左对齐或者右对齐
    • 同步更新功能
    • 噪声波形生成
    • 三角波形生成
    • 双 DAC 通道同时或者分别转换
    • 每个通道都有 DMA 功能

    框图

            图中 VDDA 和 VSSA 为 DAC 模块模拟部分的供电,而 Vref+则是 DAC 模块的参考电 压。DAC_OUTx 就是 DAC 的输出通道了(对应 PA4 或者 PA5 引脚)。 值得我们注意的是,如果我们想要写入东西到DOR中去,则必须通过DHR寄存器来写入,所以这样会有一个延迟,时间大概是3个时钟周期。

     

    数据格式

    • 8位数据右对齐:用户将数据写入DAC_DHR8Rx[7:0]位(实际存入DHRx[11:4]位)。  
    • 12 位数据左对齐:用户将数据写入 DAC_DHR12Lx[15:4]位(实际存入 DHRx[11:0] 位)。
    • 12 位数据右对齐:用户将数据写入 DAC_DHR12Rx[11:0]位(实际存入 DHRx[11:0] 位)。

     触发选择

            这个是选择触发源,我们本实验使用的是软件触发。 

    寄存器

            和之前一样,手册都有,我就不再赘述了。

    硬件 

            我们需要注意的是,DAC模块是连接到PA4引脚上的,所以我们到时候需要使能相应的GPIO,还有,本实验同时使用ADC,DAC 模块,所以还需要使用跳线帽连接ADC和DAC模块,让DAC的模拟输出作为ADC的模拟输入。

     

    配置

    1、开启 PA 口时钟,设置 PA4 为模拟输入。 

    1. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能 GPIOA 时钟
    2. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    3. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
    4. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
    5. GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化

    2、使能 DAC1 时钟。

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能 DAC 时钟

    3、初始化 DAC,设置 DAC 的工作模式。

    void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct);
    

    4、使能 DAC 转换通道。

    DAC_Cmd(DAC_Channel_1, ENABLE); //使能 DAC 通道 1

    5、设置 DAC 的输出值。

     DAC_SetChannel1Data(DAC_Align_12b_R, 0); //12 位右对齐数据格式设置 DAC 值
    

    代码 

    1. #include "dac.h"
    2. //DAC通道1输出初始化
    3. void Dac1_Init(void)
    4. {
    5. GPIO_InitTypeDef GPIO_InitStructure;
    6. DAC_InitTypeDef DAC_InitType;
    7. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
    8. RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟
    9. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    10. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
    11. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
    12. GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
    13. DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
    14. DAC_InitType.DAC_OutputBuffer = DAC_OutputBuffer_Disable; //DAC1输出缓存关闭
    15. DAC_InitType.DAC_Trigger = DAC_Trigger_None;//不使用触发功能
    16. DAC_InitType.DAC_WaveGeneration = DAC_WaveGeneration_None;//不使用波形发生
    17. DAC_Init(DAC_Channel_1,&DAC_InitType); //初始化DAC通道1
    18. DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC通道1
    19. DAC_SetChannel1Data(DAC_Align_12b_R, 0); //12位右对齐数据格式设置DAC值
    20. }

    1. #include "sys.h"
    2. #include "delay.h"
    3. #include "usart.h"
    4. #include "led.h"
    5. #include "adc.h"
    6. #include "dac.h"
    7. #include "key.h"
    8. int main(void)
    9. {
    10. u16 adcx;
    11. float temp;
    12. u8 t=0;
    13. u16 dacval=0;
    14. u8 key;
    15. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
    16. delay_init(168); //初始化延时函数
    17. uart_init(115200); //初始化串口波特率为115200
    18. LED_Init(); //初始化LED
    19. Adc_Init(); //adc初始化
    20. KEY_Init(); //按键初始化
    21. Dac1_Init(); //DAC通道1初始化
    22. DAC_SetChannel1Data(DAC_Align_12b_R,dacval);//初始值为0
    23. while(1)
    24. {
    25. t++;
    26. key=KEY_Scan(1);
    27. if(key==WKUP_PRES)
    28. {
    29. if(dacval<4000)dacval+=200;
    30. DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值
    31. }else if(key==KEY1_PRES)
    32. {
    33. if(dacval>200)dacval-=200;
    34. else dacval=0;
    35. DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值
    36. }
    37. if(t==100||key==KEY1_PRES||key==WKUP_PRES) //WKUP/KEY1按下了,或者定时时间到了
    38. {
    39. adcx=DAC_GetDataOutputValue(DAC_Channel_1);//读取前面设置DAC的值
    40. printf ("DAC VAL:%d",adcx); //显示DAC寄存器值
    41. printf ("\r\n\r\n");
    42. temp=(float)adcx*(3.3/4096); //得到DAC电压值
    43. adcx=temp;
    44. printf("DAC VOL:%fV",temp); //显示电压值
    45. printf ("\r\n\r\n");
    46. adcx=Get_Adc_Average(ADC_Channel_5,10); //得到ADC转换值
    47. temp=(float)adcx*(3.3/4096); //得到ADC电压值
    48. adcx=temp;
    49. printf("ADC VOL:%fV",temp); //显示电压值
    50. printf ("\r\n\r\n");
    51. LED0=!LED0;
    52. t=0;
    53. }
    54. delay_ms(10);
    55. }
    56. }

    总结 

            本节DAC的基础知识就先介绍到这,后期还会对代码进行修改以及调试,继续探索一下AD/DA的功能,好了,谢谢大家的观看。

  • 相关阅读:
    STM32——STM32F103时钟解析(正点原子资料+HAL库代码分析)
    bootstrapjs开发环境搭建
    SpringCloud 微服务全栈体系(二)
    同花顺_知识_庄家技法_1打压股价
    用VS Code搞Qt6:编译源代码与基本配置
    神经网络在控制中的作用,间歇控制器的工作原理
    rust持续学习 Fn FnMut FnOnce
    【Python 千题 —— 基础篇】分句成词
    2023CRM排行:深度对比16款CRM
    易点易动固定资产管理系统: 帮助您应对2023年年终固定资产大盘点
  • 原文地址:https://blog.csdn.net/weixin_66578482/article/details/126436715