STM32 DAC 输出正弦波、三角波、方波

DAC可以将数字信号转换成模拟信号,在嵌入式系统开发中运用的十分广泛。在STM32实际运用中,可直接将数值映射成端口的电压值,通过大量的采样点输出,可达到输出指定波形的目的。

1、设置系统时钟(Clock)

2、打开DAC输出通道

3、生成代码后,在User Code 2 处开启DAC通道

HAL_DAC_Start(&hdac,DAC1_CHANNEL_1);

 4、通过DAC显示方波

main函数中 while循环内容如下

  while (1)
  {
    /* USER CODE END WHILE */
		HAL_DAC_SetValue(&hdac,DAC1_CHANNEL_1,DAC_ALIGN_12B_R,4095);
		HAL_Delay(1);
		HAL_DAC_SetValue(&hdac,DAC1_CHANNEL_1,DAC_ALIGN_12B_R,0);
		HAL_Delay(1);
    /* USER CODE BEGIN 3 */
  }

HAL_DAC_SetValue()为DAC输出设置函数,默认输出为12位的数字信号。

因此,SetValue的阈值为 0-4095(数值过大会溢出)

烧录程序后,DAC输出端口波形如下: 

 5、通过DAC显示正弦波

首先将之前while循环内的方波程序清除。

要输出正弦波,需要使DAC输出光滑的连续的曲线,因此需要大量采样点。

此处,我采用python程序生成了256个采样点,即将一个正弦波周期划分为256个点。

Sin采样点生成Python程序如下:

import numpy as np
import math

#修改本变量可以更改点数,如16、32、64等
POINT_NUM = 256

pi = math.pi

#一个周期 POINT_NUM 个点
n = np.linspace(0,2*pi,POINT_NUM)

#计算POINT_NUM个点的正弦值
a = map(math.sin,n)

r =[]
for i in a:
   #调整幅值至在0~1区间
   i+=1

   #按3.3V电压调整幅值
   i*= 3.3/2

   #求取dac数值,12位dac LSB = 3.3V/2**12
   ri = round(i*2**12/3.3)

   #检查参数
   if ri >= 4095:
      ri = 4095

   #得到dac数值序列
   r.append( ri )

print(list(map(int,r)))

生成的数据如下

{2048, 2098, 2149, 2199, 2250, 2300, 2350, 2399, 2449, 2498, 2548, 2596, 2645, 2693, 2741, 2788, 2835, 2881, 2927, 2972, 3017, 3061, 3105, 3148, 3190, 3231, 3272, 3312, 3351, 3390, 3428, 3465, 3501, 3536, 3570, 3603, 3636, 3667, 3697, 3727, 3755, 3783, 3809, 3834, 3858, 3881, 3903, 3924, 3944, 3962, 3980, 3996, 4011, 4025, 4037, 4049, 4059, 4068, 4075, 4082, 4087, 4091, 4094, 4095, 4095, 4095, 4093, 4089, 4085, 4079, 4072, 4063, 4054, 4043, 4031, 4018, 4003, 3988, 3971, 3953, 3934, 3914, 3892, 3870, 3846, 3822, 3796, 3769, 3741, 3712, 3682, 3651, 3620, 3587, 3553, 3518, 3483, 3446, 3409, 3371, 3332, 3292, 3252, 3211, 3169, 3126, 3083, 3039, 2995, 2950, 2904, 2858, 2811, 2764, 2717, 2669, 2621, 2572, 2523, 2474, 2424, 2375, 2325, 2275, 2224, 2174, 2124, 2073, 2023, 1972, 1922, 1872, 1821, 1771, 1721, 1672, 1622, 1573, 1524, 1475, 1427, 1379, 1332, 1285, 1238, 1192, 1146, 1101, 1057, 1013, 970, 927, 885, 844, 804, 764, 725, 687, 650, 613, 578, 543, 509, 476, 445, 414, 384, 355, 327, 300, 274, 250, 226, 204, 182, 162, 143, 125, 108, 93, 78, 65, 53, 42, 33, 24, 17, 11, 7, 3, 1, 0, 0, 2, 5, 9, 14, 21, 28, 37, 47, 59, 71, 85, 100, 116, 134, 152, 172, 193, 215, 238, 262, 287, 313, 341, 369, 399, 429, 460, 493, 526, 560, 595, 631, 668, 706, 745, 784, 824, 865, 906, 948, 991, 1035, 1079, 1124, 1169, 1215, 1261, 1308, 1355, 1403, 1451, 1500, 1548, 1598, 1647, 1697, 1746, 1796, 1846, 1897, 1947, 1998, 2048}

在 User Code Begin 0 处,新建 Sindata数组,存放生成的采样点数据。

uint32_t SinData[256]={2048, 2098, 2149, 2199, 2250, 2300, 2350, 2399, 2449, 2498, 2548, 2596, 2645, 2693, 2741, 2788, 2835, 2881, 2927, 2972, 3017, 3061, 3105, 3148, 3190, 3231, 3272, 3312, 3351, 3390, 3428, 3465, 3501, 3536, 3570, 3603, 3636, 3667, 3697, 3727, 3755, 3783, 3809, 3834, 3858, 3881, 3903, 3924, 3944, 3962, 3980, 3996, 4011, 4025, 4037, 4049, 4059, 4068, 4075, 4082, 4087, 4091, 4094, 4095, 4095, 4095, 4093, 4089, 4085, 4079, 4072, 4063, 4054, 4043, 4031, 4018, 4003, 3988, 3971, 3953, 3934, 3914, 3892, 3870, 3846, 3822, 3796, 3769, 3741, 3712, 3682, 3651, 3620, 3587, 3553, 3518, 3483, 3446, 3409, 3371, 3332, 3292, 3252, 3211, 3169, 3126, 3083, 3039, 2995, 2950, 2904, 2858, 2811, 2764, 2717, 2669, 2621, 2572, 2523, 2474, 2424,2375, 2325, 2275, 2224, 2174, 2124, 2073, 2023, 1972, 1922, 1872, 1821, 1771, 1721, 1672, 1622, 1573, 1524, 1475, 1427, 1379, 1332, 1285, 1238, 1192, 1146, 1101, 1057, 1013, 970, 927, 885, 844, 804, 764, 725, 687, 650, 613, 578, 543, 509, 476, 445, 414, 384, 355, 327, 300, 274, 250, 226, 204, 182, 162, 143, 125, 108, 93, 78, 65, 53, 42, 33, 24, 17, 11, 7, 3, 1, 0, 0, 2, 5, 9, 14, 21, 28, 37, 47, 59, 71, 85, 100, 116, 134, 152, 172, 193, 215, 238, 262, 287, 313, 341, 369, 399, 429, 460, 493, 526, 560, 595, 631, 668, 706, 745, 784, 824, 865, 906, 948, 991, 1035, 1079, 1124, 1169, 1215, 1261, 1308, 1355, 1403, 1451, 1500, 1548, 1598, 1647, 1697, 1746, 1796, 1846, 1897, 1947, 1998, 2048};

在while循环内,代码如下:

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

		for(int x=0;x<sizeof(SinData)/sizeof(SinData[0]);x++){
			HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,SinData[x]);
		}
  }

程序烧录后,DAC输出如下

 6、通过DAC输出三角波

首先将之前while循环内的正弦波程序清除。

要输出三角波,同样需要使DAC输出连续曲线,因此需要大量采样点,但不需要像正弦波那么多。

此处,我采用python程序生成了128个采样点,即将一个三角波周期划分为128个点。

三角波采样点生成Python程序如下:

POINT_NUM = 64
step=4096/POINT_NUM
a=[]
r=[]
for i in range(POINT_NUM):
    a.append(int(i*step))
for i in range(POINT_NUM):
    a.append(4096-int(i*step))

print(a)

print(len(a))

在 User Code Begin 0 处,新建 TriData数组,存放生成的采样点数据。

uint32_t TriData[]={0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, 3904, 3968, 4032, 4090,4090, 4032, 3968, 3904, 3840, 3776, 3712, 3648, 3584, 3520, 3456, 3392, 3328, 3264, 3200, 3136, 3072, 3008, 2944, 2880, 2816, 2752, 2688, 2624, 2560, 2496, 2432, 2368, 2304, 2240, 2176, 2112, 2048, 1984, 1920, 1856, 1792, 1728, 1664, 1600, 1536, 1472, 1408, 1344, 1280, 1216, 1152, 1088, 1024, 960, 896, 832, 768, 704, 640, 576, 512, 448, 384, 320, 256, 192, 128,64,0};

while函数内代码如下:

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */


		for(int x=0;x<sizeof(TriData)/sizeof(TriData[0]);x++){
			HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,TriData[x]);
		}
  }

结果如下:

总结:

DAC功能需要调用两个主要函数:HAL_DAC_Start()和HAL_DAC_SetValue()

输出不同的波形需要采用不同的采样点数据,采样次数越多输出的波形越连续,失真率越低,但占用MPU的资源也越多。因此,需要根据不同输出波形的需要,设置采样次数,一般情况下256次采样足矣。

  • 46
    点赞
  • 412
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值