当前位置:   article > 正文

STM32的DAC生成正弦波、三角波、方波(库函数版本)_stm32生成正弦波

stm32生成正弦波

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

 

 


前言

本文章使用的stm32的型号为STM32ZET6(正点原子战舰版),先使用matlab生成波函数的数据表,存进数组里,再使用DAC及DMA生成波。


 

一、获取波函数数据表

这一步是让ai写的,下面是sin函数的matlab的程序,其他波函数也可参考。

我是生成txt文件后复制,直接输出再复制也一样。

可以在一些在线网站跑这类代码,推荐一个免费的代码在线运行 - 锤子在线工具 (toolhelper.cn),让ai改一下代码就行。

  1. % DAC输出范围(12位DAC)
  2. DAC_range = 2^12; % 4096个离散级别
  3. % 生成正弦波形数组
  4. num_samples = 256;
  5. t = linspace(0, 2*pi, num_samples); % 时间从02*pi,等分成512
  6. sin_wave = sin(t);
  7. % 将正弦波形归一化到DAC输出范围(04095
  8. normalized_sin_wave = (sin_wave + 1) * (DAC_range - 1) / 2;
  9. % 将归一化的数组四舍五入为整数
  10. dac_output_values = round(normalized_sin_wave);
  11. % 绘制DAC输出波形
  12. figure;
  13. plot(dac_output_values);
  14. title('DAC输出正弦波形');
  15. xlabel('样本');
  16. ylabel('DAC输出值');
  17. grid on;
  18. % 将数组保存到文件中
  19. writematrix(dac_output_values, 'dac_output_values.txt');
  20. disp('DAC输出值已保存到文件:dac_output_values.txt');

 核心代码是将sin从[-1,1]的值域转换到DAC输出范围[0,4095]。

  1. % 将正弦波形归一化到DAC输出范围(04095
  2. normalized_sin_wave = (sin_wave + 1) * (DAC_range - 1) / 2;
  3. % 将归一化的数组四舍五入为整数
  4. dac_output_values = round(normalized_sin_wave);

放一组等分成64个点的sin函数数据表

2048,2251,2453,2651,2843,3027,3201,3364,3513,3648,3767,3870,3953,4018,4064,4089,4094,4079,4044,3988,3914,3821,3710,3583,3440,3284,3115,2936,2748,2553,2353,2150,1945,1742,1542,1347,1159,980,811,655,512,385,274,181,107,51,16,1,6,31,77,142,225,328,447,582,731,894,1068,1252,1444,1642,1844,2047

 

二、stm32代码

1.DAC配置

我这里把dac相关的配置放一起了

1.dac

 在参考手册可以看到,A4会自动作为输出引脚,需要设置成AIN模式

3decb29336ea466caadd4a65bf7ff089.png

  1. /*GPIO初始化*/
  2. GPIO_InitTypeDef GPIO_InitStructure; //定义结构体
  3. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入模式
  4. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //GPIO引脚A4
  5. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO速度50MHz
  6. GPIO_Init(GPIOA, &GPIO_InitStructure);

 dac参数配置

DAC_Trigger:触发方式

DAC_WaveGeneration:是否生成波。stm32的DAC可以生成噪声和三角形波两种波

DAC_LFSRUnmask_TriangleAmplitude:生成波的幅值

DAC_OutputBuffer:输出缓冲。手册解释

acdf77a9e6cf42b4813f39f050efe882.png

  1. /*DAC_InitStruct 参数初始化*/
  2. DAC_InitTypeDef DAC_InitStruct;
  3. DAC_InitStruct.DAC_Trigger = DAC_Trigger_T2_TRGO; //触发方式:定时器2触发
  4. DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None; //不生成波形
  5. DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
  6. DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Enable; //输出缓冲使能
  7. DAC_Init(DAC_Channel_1,&DAC_InitStruct); //

 

2.定时器

可以通过定时器触发周期和等份点数,计算最后波的频率。

55f64f26ef6d4760bc77a392046e5441.png

  1. TIM_PrescalerConfig(TIM2,36-1,TIM_PSCReloadMode_Update);
  2. TIM_SetAutoreload(TIM2,1000-1);
  3. TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update);

3.dma

 dma即直接内存访问,我们这里使用DMA,将自己设置的数组,搬运到DAC发送数据的地址,也就是从存储器到外设。自己使用需要更改地址,DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)sin_wave ,把sin_wave换成自己设置的数组。

8f5706f79ab244a19385728da89735ca.png

 参考手册上说明了数据应当写入DHRx寄存器,我这里12R1代表12位右对齐。

  1. /*DMA初始化*/
  2. DMA_InitTypeDef DMA_InitStructure; //定义结构体变量
  3. DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&DAC -> DHR12R1; //外设基地址
  4. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据宽度,选择半字
  5. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址自增,选择失能
  6. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)sin_wave ; //存储器基地址
  7. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //存储器数据宽度,选择半字,与源数据宽度对应
  8. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /存储器地址自增,选择使能,每次转运后,数组移到下一个位置
  9. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,选择由存储到外设
  10. DMA_InitStructure.DMA_BufferSize = 512; //转运的数据大小
  11. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //模式,选择循环模式
  12. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先级,选择中等
  13. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存
  14. DMA_Init(DMA2_Channel3, &DMA_InitStructure); //将结构体变量交给DMA_Init,配置DMA2的通道3

 

2.完整代码 

DAC.c

  1. #include "stm32f10x.h"
  2. //sin波数据表
  3. uint16_t sin_wave[64]={2048,2251,2453,2651,2843,3027,3201,3364,3513,3648,3767,3870,3953,4018,4064,4089,4094,4079,4044,3988,3914,3821,3710,3583,3440,3284,3115,2936,2748,2553,2353,2150,1945,1742,1542,1347,1159,980,811,655,512,385,274,181,107,51,16,1,6,31,77,142,225,328,447,582,731,894,1068,1252,1444,1642,1844,2047};
  4. //三角波数据表
  5. uint16_t triangle_wave[512]={0,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240,256,272,288,305,321,337,353,369,385,401,417,433,449,465,481,497,513,529,545,561,577,593,609,625,641,657,673,689,705,721,737,753,769,785,801,817,833,849,865,882,898,914,930,946,962,978,994,1010,1026,1042,1058,1074,1090,1106,1122,1138,1154,1170,1186,1202,1218,1234,1250,1266,1282,1298,1314,1330,1346,1362,1378,1394,1410,1426,1442,1458,1475,1491,1507,1523,1539,1555,1571,1587,1603,1619,1635,1651,1667,1683,1699,1715,1731,1747,1763,1779,1795,1811,1827,1843,1859,1875,1891,1907,1923,1939,1955,1971,1987,2003,2019,2035,2052,2068,2084,2100,2116,2132,2148,2164,2180,2196,2212,2228,2244,2260,2276,2292,2308,2324,2340,2356,2372,2388,2404,2420,2436,2452,2468,2484,2500,2516,2532,2548,2564,2580,2596,2612,2628,2645,2661,2677,2693,2709,2725,2741,2757,2773,2789,2805,2821,2837,2853,2869,2885,2901,2917,2933,2949,2965,2981,2997,3013,3029,3045,3061,3077,3093,3109,3125,3141,3157,3173,3189,3205,3222,3238,3254,3270,3286,3302,3318,3334,3350,3366,3382,3398,3414,3430,3446,3462,3478,3494,3510,3526,3542,3558,3574,3590,3606,3622,3638,3654,3670,3686,3702,3718,3734,3750,3766,3782,3798,3815,3831,3847,3863,3879,3895,3911,3927,3943,3959,3975,3991,4007,4023,4039,4055,4071,4087,4087,4071,4055,4039,4023,4007,3991,3975,3959,3943,3927,3911,3895,3879,3863,3847,3831,3815,3798,3782,3766,3750,3734,3718,3702,3686,3670,3654,3638,3622,3606,3590,3574,3558,3542,3526,3510,3494,3478,3462,3446,3430,3414,3398,3382,3366,3350,3334,3318,3302,3286,3270,3254,3238,3222,3205,3189,3173,3157,3141,3125,3109,3093,3077,3061,3045,3029,3013,2997,2981,2965,2949,2933,2917,2901,2885,2869,2853,2837,2821,2805,2789,2773,2757,2741,2725,2709,2693,2677,2661,2645,2628,2612,2596,2580,2564,2548,2532,2516,2500,2484,2468,2452,2436,2420,2404,2388,2372,2356,2340,2324,2308,2292,2276,2260,2244,2228,2212,2196,2180,2164,2148,2132,2116,2100,2084,2068,2052,2035,2019,2003,1987,1971,1955,1939,1923,1907,1891,1875,1859,1843,1827,1811,1795,1779,1763,1747,1731,1715,1699,1683,1667,1651,1635,1619,1603,1587,1571,1555,1539,1523,1507,1491,1475,1458,1442,1426,1410,1394,1378,1362,1346,1330,1314,1298,1282,1266,1250,1234,1218,1202,1186,1170,1154,1138,1122,1106,1090,1074,1058,1042,1026,1010,994,978,962,946,930,914,898,882,865,849,833,817,801,785,769,753,737,721,705,689,673,657,641,625,609,593,577,561,545,529,513,497,481,465,449,433,417,401,385,369,353,337,321,305,288,272,256,240,224,208,192,176,160,144,128,112,96,80,64,48,32,16,0
  6. };
  7. //方波数据表
  8. uint16_t square_wave[512]={4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4095
  9. };
  10. //单通道DAC初始化
  11. void dac_config_init()
  12. {
  13. /*开启时钟*/
  14. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
  15. RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); //开启DAC时钟
  16. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); //开启DMA时钟
  17. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启定时器2时钟
  18. /*GPIO初始化*/
  19. GPIO_InitTypeDef GPIO_InitStructure; //定义结构体
  20. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入模式
  21. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //GPIO引脚A4
  22. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO速度50MHz
  23. GPIO_Init(GPIOA, &GPIO_InitStructure);
  24. /*定时器2配置*/
  25. TIM_PrescalerConfig(TIM2,36-1,TIM_PSCReloadMode_Update);
  26. TIM_SetAutoreload(TIM2,1000-1);
  27. TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update);
  28. /*DAC_InitStruct 参数初始化*/
  29. DAC_InitTypeDef DAC_InitStruct;
  30. DAC_InitStruct.DAC_Trigger = DAC_Trigger_T2_TRGO; //触发方式:定时器2触发
  31. DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None; //不生成波形
  32. DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
  33. DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Enable; //输出缓冲使能
  34. DAC_Init(DAC_Channel_1,&DAC_InitStruct); //
  35. /*DMA初始化*/
  36. DMA_InitTypeDef DMA_InitStructure; //定义结构体变量
  37. DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&DAC -> DHR12R1; //外设基地址
  38. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据宽度,选择半字
  39. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址自增,选择失能
  40. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)sin_wave ; //存储器基地址
  41. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //存储器数据宽度,选择半字,与源数据宽度对应
  42. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器地址自增,选择使能,每次转运后,数组移到下一个位置
  43. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,选择由存储到外设
  44. DMA_InitStructure.DMA_BufferSize = 512; //转运的数据大小
  45. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //模式,选择循环模式
  46. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先级,选择中等
  47. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存
  48. DMA_Init(DMA2_Channel3, &DMA_InitStructure); //将结构体变量交给DMA_Init,配置DMA2的通道3
  49. /*使能*/
  50. TIM_Cmd(TIM2, ENABLE); //定时器2使能
  51. DMA_Cmd(DMA2_Channel3,ENABLE); //使能dma
  52. DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC通道1
  53. DAC_DMACmd(DAC_Channel_1, ENABLE); //使能DAC通道的DMA
  54. }

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "DAC.h"
  3. int main(void)
  4. {
  5. dac_config_init();
  6. while (1)
  7. {
  8. }
  9. }

三、示波器效果

拍的有点糊,频率和理论值差不多

 

704e916115ba4265849e9d2e99ef1d3d.jpeg

d6283f6e5fdd4bbeb5e06364f1f96a12.jpeg

906ddb60f0ce4430aa1a774add3fb140.jpeg

总结

全文讲解了stm32使用dac生成波的全流程,对其中一些参数进行解释说明。

这篇文章是给自己梳理一下做实验的思路,相信也有其他做实验的同学需要(手动狗头)。

参考文章:38. DAC—输出正弦波 — [野火]STM32库开发实战指南——基于野火指南者开发板 文档 (embedfire.com)

 

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

闽ICP备14008679号