赞
踩
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
本文章使用的stm32的型号为STM32ZET6(正点原子战舰版),先使用matlab生成波函数的数据表,存进数组里,再使用DAC及DMA生成波。
这一步是让ai写的,下面是sin函数的matlab的程序,其他波函数也可参考。
我是生成txt文件后复制,直接输出再复制也一样。
可以在一些在线网站跑这类代码,推荐一个免费的代码在线运行 - 锤子在线工具 (toolhelper.cn),让ai改一下代码就行。
- % DAC输出范围(12位DAC)
- DAC_range = 2^12; % 4096个离散级别
-
- % 生成正弦波形数组
- num_samples = 256;
- t = linspace(0, 2*pi, num_samples); % 时间从0到2*pi,等分成512份
- sin_wave = sin(t);
-
- % 将正弦波形归一化到DAC输出范围(0到4095)
- normalized_sin_wave = (sin_wave + 1) * (DAC_range - 1) / 2;
-
- % 将归一化的数组四舍五入为整数
- dac_output_values = round(normalized_sin_wave);
-
- % 绘制DAC输出波形
- figure;
- plot(dac_output_values);
- title('DAC输出正弦波形');
- xlabel('样本');
- ylabel('DAC输出值');
- grid on;
-
- % 将数组保存到文件中
- writematrix(dac_output_values, 'dac_output_values.txt');
- disp('DAC输出值已保存到文件:dac_output_values.txt');

核心代码是将sin从[-1,1]的值域转换到DAC输出范围[0,4095]。
- % 将正弦波形归一化到DAC输出范围(0到4095)
- normalized_sin_wave = (sin_wave + 1) * (DAC_range - 1) / 2;
-
- % 将归一化的数组四舍五入为整数
- 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
我这里把dac相关的配置放一起了
在参考手册可以看到,A4会自动作为输出引脚,需要设置成AIN模式
- /*GPIO初始化*/
- GPIO_InitTypeDef GPIO_InitStructure; //定义结构体
-
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入模式
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //GPIO引脚A4
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO速度50MHz
- GPIO_Init(GPIOA, &GPIO_InitStructure);
dac参数配置
DAC_Trigger:触发方式
DAC_WaveGeneration:是否生成波。stm32的DAC可以生成噪声和三角形波两种波
DAC_LFSRUnmask_TriangleAmplitude:生成波的幅值
DAC_OutputBuffer:输出缓冲。手册解释
- /*DAC_InitStruct 参数初始化*/
- DAC_InitTypeDef DAC_InitStruct;
-
- DAC_InitStruct.DAC_Trigger = DAC_Trigger_T2_TRGO; //触发方式:定时器2触发
- DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None; //不生成波形
- DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
- DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Enable; //输出缓冲使能
- DAC_Init(DAC_Channel_1,&DAC_InitStruct); //
可以通过定时器触发周期和等份点数,计算最后波的频率。
- TIM_PrescalerConfig(TIM2,36-1,TIM_PSCReloadMode_Update);
- TIM_SetAutoreload(TIM2,1000-1);
- TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update);
dma即直接内存访问,我们这里使用DMA,将自己设置的数组,搬运到DAC发送数据的地址,也就是从存储器到外设。自己使用需要更改地址,DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)sin_wave ,把sin_wave换成自己设置的数组。
参考手册上说明了数据应当写入DHRx寄存器,我这里12R1代表12位右对齐。
- /*DMA初始化*/
- DMA_InitTypeDef DMA_InitStructure; //定义结构体变量
-
-
- DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&DAC -> DHR12R1; //外设基地址
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据宽度,选择半字
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址自增,选择失能
-
- DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)sin_wave ; //存储器基地址
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //存储器数据宽度,选择半字,与源数据宽度对应
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /存储器地址自增,选择使能,每次转运后,数组移到下一个位置
-
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,选择由存储到外设
- DMA_InitStructure.DMA_BufferSize = 512; //转运的数据大小
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //模式,选择循环模式
- DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先级,选择中等
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存
- DMA_Init(DMA2_Channel3, &DMA_InitStructure); //将结构体变量交给DMA_Init,配置DMA2的通道3

DAC.c
- #include "stm32f10x.h"
-
- //sin波数据表
- 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};
- //三角波数据表
- 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
- };
- //方波数据表
- 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
- };
-
-
- //单通道DAC初始化
- void dac_config_init()
- {
-
- /*开启时钟*/
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); //开启DAC时钟
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); //开启DMA时钟
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启定时器2时钟
-
- /*GPIO初始化*/
- GPIO_InitTypeDef GPIO_InitStructure; //定义结构体
-
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入模式
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //GPIO引脚A4
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO速度50MHz
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- /*定时器2配置*/
- TIM_PrescalerConfig(TIM2,36-1,TIM_PSCReloadMode_Update);
- TIM_SetAutoreload(TIM2,1000-1);
- TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update);
-
- /*DAC_InitStruct 参数初始化*/
- DAC_InitTypeDef DAC_InitStruct;
-
- DAC_InitStruct.DAC_Trigger = DAC_Trigger_T2_TRGO; //触发方式:定时器2触发
- DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None; //不生成波形
- DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
- DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Enable; //输出缓冲使能
- DAC_Init(DAC_Channel_1,&DAC_InitStruct); //
-
-
- /*DMA初始化*/
- DMA_InitTypeDef DMA_InitStructure; //定义结构体变量
-
-
- DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&DAC -> DHR12R1; //外设基地址
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据宽度,选择半字
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址自增,选择失能
-
- DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)sin_wave ; //存储器基地址
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //存储器数据宽度,选择半字,与源数据宽度对应
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器地址自增,选择使能,每次转运后,数组移到下一个位置
-
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,选择由存储到外设
- DMA_InitStructure.DMA_BufferSize = 512; //转运的数据大小
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //模式,选择循环模式
- DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先级,选择中等
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存
- DMA_Init(DMA2_Channel3, &DMA_InitStructure); //将结构体变量交给DMA_Init,配置DMA2的通道3
-
-
- /*使能*/
- TIM_Cmd(TIM2, ENABLE); //定时器2使能
- DMA_Cmd(DMA2_Channel3,ENABLE); //使能dma
- DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC通道1
- DAC_DMACmd(DAC_Channel_1, ENABLE); //使能DAC通道的DMA
-
- }

main.c
- #include "stm32f10x.h" // Device header
- #include "DAC.h"
-
- int main(void)
- {
-
-
- dac_config_init();
-
-
- while (1)
- {
-
-
- }
- }

拍的有点糊,频率和理论值差不多
全文讲解了stm32使用dac生成波的全流程,对其中一些参数进行解释说明。
这篇文章是给自己梳理一下做实验的思路,相信也有其他做实验的同学需要(手动狗头)。
参考文章:38. DAC—输出正弦波 — [野火]STM32库开发实战指南——基于野火指南者开发板 文档 (embedfire.com)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。