• 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()

    相关库函数介绍

    关键结构体介绍

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

    源码

    dac.c

    1. #include "./BSP/DAC/dac.h"
    2. DAC_HandleTypeDef g_dac_handle;
    3. /* DAC初始化函数 */
    4. void dac_init(void)
    5. {
    6. DAC_ChannelConfTypeDef dac_ch_conf;
    7. g_dac_handle.Instance = DAC;
    8. HAL_DAC_Init(&g_dac_handle); /* 初始化DAC */
    9. dac_ch_conf.DAC_Trigger = DAC_TRIGGER_NONE; /* 不使用触发功能 */
    10. dac_ch_conf.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE; /* DAC输出缓冲关闭 */
    11. HAL_DAC_ConfigChannel(&g_dac_handle, &dac_ch_conf, DAC_CHANNEL_1); /* 配置DAC通道1 */
    12. HAL_DAC_Start(&g_dac_handle, DAC_CHANNEL_1); /* 开启DAC通道1 */
    13. }
    14. /* DAC MSP初始化函数 */
    15. void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
    16. {
    17. if (hdac->Instance == DAC)
    18. {
    19. GPIO_InitTypeDef gpio_init_struct;
    20. __HAL_RCC_DAC_CLK_ENABLE();
    21. __HAL_RCC_GPIOA_CLK_ENABLE();
    22. gpio_init_struct.Pin = GPIO_PIN_4;
    23. gpio_init_struct.Mode = GPIO_MODE_ANALOG;
    24. HAL_GPIO_Init(GPIOA, &gpio_init_struct);
    25. }
    26. }
    27. /* 设置通道输出电压 */
    28. void dac_set_voltage(uint16_t vol)/*用0-3300表示0-3.3V*/
    29. {
    30. double temp = vol;
    31. temp /= 1000;
    32. temp = temp * 4096 / 3.3;//DAC输出数据寄存器 - DORX
    33. if (temp >= 4096)temp = 4095; /* 如果值大于等于4096, 则取4095 */
    34. HAL_DAC_SetValue(&g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, temp); /* 12位右对齐数据格式设置DAC值 */
    35. }

    dac.h

    1. #ifndef __DAC_H
    2. #define __DAC_H
    3. #include "./SYSTEM/sys/sys.h"
    4. void dac_init(void);
    5. void dac_set_voltage(uint16_t vol);
    6. #endif

    main.c

    1. #include "./SYSTEM/sys/sys.h"
    2. #include "./SYSTEM/usart/usart.h"
    3. #include "./SYSTEM/delay/delay.h"
    4. #include "./BSP/LED/led.h"
    5. #include "./BSP/LCD/lcd.h"
    6. #include "./BSP/KEY/key.h"
    7. #include "./BSP/DAC/dac.h"
    8. #include "./BSP/ADC/adc.h"
    9. int main(void)
    10. {
    11. uint16_t adcx;
    12. float temp;
    13. HAL_Init(); /* 初始化HAL库 */
    14. sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    15. delay_init(72); /* 延时初始化 */
    16. usart_init(115200); /* 串口初始化为115200 */
    17. led_init(); /* 初始化LED */
    18. lcd_init(); /* 初始化LCD */
    19. key_init(); /* 初始化按键 */
    20. adc_init(); /* 初始化ADC */
    21. dac_init(); /* 初始化DAC1_OUT1通道 */
    22. lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
    23. lcd_show_string(30, 70, 200, 16, 16, "ADC TEST", RED);
    24. lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    25. lcd_show_string(30, 110, 200, 16, 16, "ADC1_CH1_VAL:", BLUE);
    26. lcd_show_string(30, 130, 200, 16, 16, "ADC1_CH1_VOL:0.000V", BLUE); /* 先在固定位置显示小数点 */
    27. dac_set_voltage(2000);
    28. while (1)
    29. {
    30. adcx = adc_get_result();
    31. lcd_show_xnum(134, 110, adcx, 5, 16, 0, BLUE); /* 显示ADCC采样后的原始值 */
    32. temp = (float)adcx * (3.3 / 4096); /* 获取计算后的带小数的实际电压值,比如3.1111 */
    33. adcx = temp; /* 赋值整数部分给adcx变量,因为adcx为u16整形 */
    34. lcd_show_xnum(134, 130, adcx, 1, 16, 0, BLUE); /* 显示电压值的整数部分,3.1111的话,这里就是显示3 */
    35. temp -= adcx; /* 把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111 */
    36. temp *= 1000; /* 小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。 */
    37. lcd_show_xnum(150, 130, temp, 3, 16, 0X80, BLUE);/* 显示小数部分(前面转换为了整形显示),这里显示的就是111. */
    38. LED0_TOGGLE();
    39. delay_ms(250);
    40. }
    41. }

    DAC输出三角波实验

    实验简要

    1,功能描述

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

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

           TEN1位置0   

    3,关闭输出缓冲

            BOFF1位置1

    4,使用12位右对齐模式

            将数字量写入DAC_DHR12R1寄存器

     源码

    dac.c

    1. #include "./BSP/DAC/dac.h"
    2. #include "./SYSTEM/delay/delay.h"
    3. DAC_HandleTypeDef g_dac_handle;
    4. /* DAC初始化函数 */
    5. void dac_init(void)
    6. {
    7. DAC_ChannelConfTypeDef dac_ch_conf;
    8. g_dac_handle.Instance = DAC;
    9. HAL_DAC_Init(&g_dac_handle);
    10. dac_ch_conf.DAC_Trigger = DAC_TRIGGER_NONE;
    11. dac_ch_conf.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
    12. HAL_DAC_ConfigChannel(&g_dac_handle, &dac_ch_conf, DAC_CHANNEL_1);
    13. HAL_DAC_Start(&g_dac_handle, DAC_CHANNEL_1);
    14. }
    15. /* DAC MSP初始化函数 */
    16. void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
    17. {
    18. if (hdac->Instance == DAC)
    19. {
    20. GPIO_InitTypeDef gpio_init_struct;
    21. __HAL_RCC_GPIOA_CLK_ENABLE();
    22. __HAL_RCC_DAC_CLK_ENABLE();
    23. gpio_init_struct.Pin = GPIO_PIN_4;
    24. gpio_init_struct.Mode = GPIO_MODE_ANALOG;
    25. HAL_GPIO_Init(GPIOA, &gpio_init_struct);
    26. }
    27. }
    28. void dac_triangular_wave(uint16_t maxval, uint16_t dt, uint16_t samples, uint16_t n)
    29. {
    30. uint16_t i, j;
    31. float incval; /* 递增量 */
    32. float Curval; /* 当前值 */
    33. if(samples > ((maxval + 1) * 2))return ; /* 数据不合法 */
    34. incval = (maxval + 1) / (samples / 2); /* 计算递增量 */
    35. for(j = 0; j < n; j++)
    36. {
    37. Curval = 0;
    38. HAL_DAC_SetValue(&g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, Curval); /* 先输出0 */
    39. for(i = 0; i < (samples / 2); i++) /* 输出上升沿 */
    40. {
    41. Curval += incval; /* 新的输出值 */
    42. HAL_DAC_SetValue(&g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, Curval);
    43. delay_us(dt);
    44. }
    45. for(i = 0; i < (samples / 2); i++) /* 输出下降沿 */
    46. {
    47. Curval -= incval; /* 新的输出值 */
    48. HAL_DAC_SetValue(&g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, Curval);
    49. delay_us(dt);
    50. }
    51. }
    52. }

    dac.h

    1. #ifndef __DAC_H
    2. #define __DAC_H
    3. #include "./SYSTEM/sys/sys.h"
    4. void dac_init(void);
    5. void dac_triangular_wave(uint16_t maxval, uint16_t dt, uint16_t samples, uint16_t n);
    6. #endif

    main.c

    1. #include "./SYSTEM/sys/sys.h"
    2. #include "./SYSTEM/usart/usart.h"
    3. #include "./SYSTEM/delay/delay.h"
    4. #include "./BSP/LED/led.h"
    5. #include "./BSP/LCD/lcd.h"
    6. #include "./BSP/ADC/adc.h"
    7. #include "./BSP/DAC/dac.h"
    8. #include "./BSP/KEY/key.h"
    9. int main(void)
    10. {
    11. uint8_t t = 0;
    12. uint8_t key;
    13. HAL_Init(); /* 初始化HAL库 */
    14. sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    15. delay_init(72); /* 延时初始化 */
    16. usart_init(115200); /* 串口初始化为115200 */
    17. led_init(); /* 初始化LED */
    18. lcd_init(); /* 初始化LCD */
    19. key_init(); /* 初始化按键 */
    20. dac_init(); /* 初始化DAC1_OUT1通道 */
    21. lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
    22. lcd_show_string(30, 70, 200, 16, 16, "DAC Triangular WAVE TEST", RED);
    23. lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    24. lcd_show_string(30, 110, 200, 16, 16, "KEY0:Wave1 KEY1:Wave2", RED);
    25. lcd_show_string(30, 130, 200, 16, 16, "DAC None", BLUE); /* 提示无输出 */
    26. while (1)
    27. {
    28. t++;
    29. key = key_scan(0); /* 按键扫描 */
    30. if (key == KEY0_PRES) /* 高采样率 , 100hz波形 , 实际只有65.5hz */
    31. {
    32. lcd_show_string(30, 130, 200, 16, 16, "DAC Wave1 ", BLUE);
    33. dac_triangular_wave(4095, 5, 2000, 100); /* 幅值4095, 采样点间隔5us, 2000个采样点, 100个波形 */
    34. lcd_show_string(30, 130, 200, 16, 16, "DAC None ", BLUE);
    35. }
    36. else if (key == KEY1_PRES) /* 低采样率 , 100hz波形 , 实际99.5hz */
    37. {
    38. lcd_show_string(30, 130, 200, 16, 16, "DAC Wave2 ", BLUE);
    39. dac_triangular_wave(4095, 500, 20, 100); /* 幅值4095, 采样点间隔500us, 20个采样点, 100个波形 */
    40. lcd_show_string(30, 130, 200, 16, 16, "DAC None ", BLUE);
    41. }
    42. if (t == 10) /* 定时时间到了 */
    43. {
    44. LED0_TOGGLE(); /* LED0闪烁 */
    45. t = 0;
    46. }
    47. delay_ms(10);
    48. }
    49. }

  • 相关阅读:
    2022年全球市场抗菌整理剂总体规模、主要生产商、主要地区、产品和应用细分研究报告
    我们真的需要链式查询吗?
    【redis实现自增流水并设置过期时间】
    Python 用户输入和字符串格式化指南
    视联网拓展乡村振兴新思路
    浅析显卡市场的未来走向:现在可以抄底了吗?
    商标复审成功率是多少?
    新式茶饮品牌如何写出生活感软文
    查看显存和内存大小
    #力扣:21. 合并两个有序链表@FDDLC
  • 原文地址:https://blog.csdn.net/2302_79878697/article/details/138128073