当前位置:   article > 正文

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

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. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/486062?site
推荐阅读
相关标签
  

闽ICP备14008679号