OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 19777|回复: 25

用STM32实现函数信号发生器

[复制链接]

3

主题

4

帖子

0

精华

新手入门

积分
36
金钱
36
注册时间
2015-5-15
在线时间
0 小时
发表于 2015-5-28 14:14:37 | 显示全部楼层 |阅读模式
5金钱
用STM32做函数信号发生器,用DAC描点的方式显示出方波,正弦波,锯齿波,通过按键的方式改变波形频率幅度相位,谁有这样的程序,跪求

最佳答案

查看完整内容[请看2#楼]

自己慢慢看,,,, [mw_shl_code=c,true]#ifndef __BSP_WAVEMAKER_H #define __BSP_WAVEMAKER_H #include "stm32f10x.h" #define DAC_DHR12RD_Address 0x40007420 #define DAC_DHR8R1_Address 0x40007410 #define DAC_DHR12R1_Address 0x40007408 /* DMA 传输数据长度 */ enum { DMA_BufferSize_36 = 36, DMA_BufferSize_50 = 50, DMA_BufferSize_100 = 100, }; /* 波形类型 * ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

424

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1020
金钱
1020
注册时间
2014-9-4
在线时间
199 小时
发表于 2015-5-28 14:14:38 | 显示全部楼层
自己慢慢看,,,,

[mw_shl_code=c,true]#ifndef __BSP_WAVEMAKER_H #define __BSP_WAVEMAKER_H #include "stm32f10x.h" #define DAC_DHR12RD_Address 0x40007420 #define DAC_DHR8R1_Address 0x40007410 #define DAC_DHR12R1_Address 0x40007408 /* DMA 传输数据长度 */ enum { DMA_BufferSize_36 = 36, DMA_BufferSize_50 = 50, DMA_BufferSize_100 = 100, }; /* 波形类型 */ enum { WT_RECT = 0, /* 矩形波 */ WT_SIN = 1, /* 正弦波 */ WT_TRIA = 2, /* 三角波 */ WT_SAW = 3, /* 锯齿波 */ WT_NOISE = 4, /* 噪声 */ }; /* 正弦波 */ typedef struct { uint32_t Frequency; //频率 uint16_t Amplitude; //幅值 }SIN_T; /* 三角波 */ typedef struct { uint16_t Frequency; //频率 uint16_t Amplitude; //幅值 }TRIA_T; /* 锯齿波 */ typedef struct { uint32_t Frequency; //频率 uint16_t Amplitude; //幅值 }SAW_T; /* 矩形波 */ typedef struct { uint32_t Frequency; //频率 uint16_t Amplitude; //幅值 uint8_t DutyCycle; //占空比 }RECT_T; /* 噪声 */ typedef struct { uint16_t Frequency; //频率 uint16_t Amplitude; //幅值 }NOISE_T; extern SIN_T g_Sine; extern RECT_T g_Rect; extern SAW_T g_Saw; extern NOISE_T g_Noise; extern TRIA_T g_Tria; void InitWaveMaker(void); void SetupWaveType(uint8_t _ucType,uint32_t _ulFrequency,uint16_t _usAmplitude, uint8_t _ucDutyCycle); #endif[/mw_shl_code]

[mw_shl_code=c,true]#include "stm32f10x.h" #include <stdio.h> #include "stdlib.h" #include "bsp_WaveMaker.h" #include "arm_math.h" SIN_T g_Sine; /*正弦波*/ RECT_T g_Rect; /*矩形波*/ SAW_T g_Saw; /*锯齿波*/ NOISE_T g_Noise; /*噪声 */ TRIA_T g_Tria; /*三角波*/ uint16_t g_Wave[100]; /******************************************************************************* * 函数名: InitWaveMaker * 输 入: 无 * 输 出: 无 * 功能说明:初始化波形发生器。 *******************************************************************************/ void InitWaveMaker(void) { GPIO_InitTypeDef GPIO_InitStructure; DAC_InitTypeDef DAC_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); /*初始化DAC 通道1 */ DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO; DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; DAC_Init(DAC_Channel_1, &DAC_InitStructure); DAC_DMACmd(DAC_Channel_1, ENABLE); /* 配置PA4为DAC_OUT1 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } /* ********************************************************************************************************* * 函 数 名: InitWaveFreq(uint32_t _usFrequency, uint8_t _ucDMABuffuerSize) * 功能说明: 用于初始化各种波形的产生 * 形 参:_usFrequency 表示要产生波形的触发频率, * _ucDMABuffuerSize 表示DMA要传输的数据数。 * 返 回 值: 无 ********************************************************************************************************* */ void InitWaveFreq(uint32_t _usFrequency, uint8_t _ucDMABuffuerSize) { DMA_InitTypeDef DMA_InitStructure; /*初始化定时器*/ TIM_PrescalerConfig(TIM6, 0, TIM_PSCReloadMode_Update); TIM_SetAutoreload(TIM6, _usFrequency); TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update); /*初始化DMA */ DMA_DeInit(DMA2_Channel3); DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12R1_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&g_Wave; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = _ucDMABuffuerSize; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_Low ; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA2_Channel3, &DMA_InitStructure); DMA_Cmd(DMA2_Channel3, ENABLE); } /* ********************************************************************************************************* * 函 数 名: SetupWaveType * 功能说明: 用于建立产生各种波形 * 形 参:_ucType 表示要产生的波形的类型 _ulFrequency 表示波形的触发频率 _usAmplitude 表示波形的幅值 _ucDutyCycle 表示矩形波的占空比 * 返 回 值: 无 ********************************************************************************************************* */ void SetupWaveType(uint8_t _ucType,uint32_t _ulFrequency,uint16_t _usAmplitude, uint8_t _ucDutyCycle) { uint8_t i; TIM_Cmd(TIM6, DISABLE); DAC_Cmd(DAC_Channel_1, DISABLE); switch (_ucType) { case WT_RECT: /* 方波 */ InitWaveFreq(720000 / _ulFrequency, DMA_BufferSize_100); /*要先初始化这个*/ for (i = 0; i < _ucDutyCycle; i++) { g_Wave = _usAmplitude; } for (i = _ucDutyCycle; i < 100; i++) { g_Wave = 0; } break; case WT_SIN: /* 正弦波 */ InitWaveFreq(720000 / _ulFrequency,DMA_BufferSize_100); for (i = 0; i < DMA_BufferSize_100; i++) { g_Wave = 1024+_usAmplitude*sin(2*3.1415926f*99*i/100); } break; case WT_SAW: /* 锯齿波 */ InitWaveFreq(720000 / _ulFrequency,DMA_BufferSize_100); for (i = 0; i < DMA_BufferSize_100; i++) { g_Wave = 100 + i*_usAmplitude; } break; case WT_TRIA: /* 三角波*/ InitWaveFreq(720000 / _ulFrequency,DMA_BufferSize_100); for (i = 0; i < DMA_BufferSize_100; i++) { g_Wave = 100 + abs(50-i)*_usAmplitude; } break; case WT_NOISE: /*噪声 */ InitWaveFreq(720000 / _ulFrequency,DMA_BufferSize_100); for (i = 0; i < DMA_BufferSize_100; i++) { g_Wave = rand()%_usAmplitude; } break; default : break; } DAC_Cmd(DAC_Channel_1, ENABLE); TIM_Cmd(TIM6, ENABLE); }[/mw_shl_code]

[mw_shl_code=c,true]//初始化显示的波形是方波 g_Rect.Frequency = 10000; //频率 g_Rect.Amplitude = 2000; //幅值 g_Rect.DutyCycle = 50; //占空比 InitWaveMaker(); //初始化 SetupWaveType(WT_RECT,g_Rect.Frequency,g_Rect.Amplitude,g_Rect.DutyCycle); //产生波形[/mw_shl_code]


https://github.com/WZTENG
回复

使用道具 举报

3

主题

4

帖子

0

精华

新手入门

积分
36
金钱
36
注册时间
2015-5-15
在线时间
0 小时
 楼主| 发表于 2015-5-29 12:53:38 | 显示全部楼层
回复【2楼】WZTENG:
---------------------------------
这是完整的还是主程序啊,一窍不通啊,能不能给个联系方式啊,拜托了大神~
回复

使用道具 举报

1

主题

17

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2015-6-2
在线时间
1 小时
发表于 2015-6-2 11:45:59 | 显示全部楼层
回复【2楼】WZTENG:
---------------------------------
大神,可不可以把程序分享出来,拜托了大神
回复

使用道具 举报

5

主题

424

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1020
金钱
1020
注册时间
2014-9-4
在线时间
199 小时
发表于 2015-6-2 12:07:40 | 显示全部楼层
 回复【4楼】 liaobin :
---------------------------------
在主函数中增加下面的语句就行了,要修改频率、幅值、占空比等参考下面的结构体自己改就行了,g_Wave放在是数据的值。看bsp_WaveMader.c的函数说明就可以了。SetupWaveType()我自己进行了上移操作当初是为了做示波器时用的。


//初始化显示的波形是方波
g_Rect.Frequency = 10000;  //频率
g_Rect.Amplitude = 2000;   //幅值
g_Rect.DutyCycle = 50;     //占空比
InitWaveMaker();           //初始化
SetupWaveType(WT_RECT,g_Rect.Frequency,g_Rect.Amplitude,g_Rect.DutyCycle);  //产生波形

bsp_WaveMaker.h

1.38 KB, 下载次数: 1196

bsp_WaveMaker.c

4.87 KB, 下载次数: 742

https://github.com/WZTENG
回复

使用道具 举报

1

主题

17

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2015-6-2
在线时间
1 小时
发表于 2015-6-2 16:39:48 | 显示全部楼层
回复【5楼】WZTENG:
---------------------------------
谢谢分享
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2015-6-2
在线时间
4 小时
发表于 2015-6-3 19:36:13 | 显示全部楼层
回复【5楼】WZTENG:
---------------------------------
哥们还在吗,我在研究你的这个程序,发现有个小问题,就是把幅值给到满值4095的时候,会有问题
比如,我把占空比调成100,幅值4095的时候并不能输出3.3V,大约是个0.8V的样子
调成4020的时候能达到3.27V左右,如果再调高,就不成了,会是0.xV,请问这是个什么原因?正常情况下不应该是4095对应3.3V吗
回复

使用道具 举报

5

主题

424

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1020
金钱
1020
注册时间
2014-9-4
在线时间
199 小时
发表于 2015-6-3 19:46:58 | 显示全部楼层
回复【7楼】yangzhen86:
---------------------------------
我有对信号进行了上移操作,比如
g_Wave = 1024+_usAmplitude*sin(2*3.1415926f*99*i/100);
g_Wave = 100 + abs(50-i)*_usAmplitude;
其中1024,100就是我上移的量,你把它去掉就行了。你输入4095加上前面的偏移量就超出了4095所以高部分没了只剩低部分出现0.8V是正常的。
https://github.com/WZTENG
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2015-6-2
在线时间
4 小时
发表于 2015-6-3 19:50:08 | 显示全部楼层
回复【8楼】WZTENG:
---------------------------------
可是在方波的时候好像没看到上移啊
g_Wave = _usAmplitude;
这样写的话,不就是直接给的么
回复

使用道具 举报

5

主题

424

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1020
金钱
1020
注册时间
2014-9-4
在线时间
199 小时
发表于 2015-6-3 19:57:43 | 显示全部楼层
回复【9楼】yangzhen86:
---------------------------------
理论上是没错的,实际用示波器测量一下波形,DAC的性能没认真看过手册,具体什么原因现在也不知道。
https://github.com/WZTENG
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2015-6-2
在线时间
4 小时
发表于 2015-6-3 19:59:23 | 显示全部楼层
您现在那里有没有这个问题?
我再去研究下
回复

使用道具 举报

1

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2015-10-26
在线时间
16 小时
发表于 2016-6-6 11:16:12 | 显示全部楼层
还在吗?@WZTENG ,请问一下,你程序中用定时器是什么作用?
回复

使用道具 举报

雨后的彩虹 该用户已被删除
发表于 2017-4-20 18:58:04 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

雨后的彩虹 该用户已被删除
发表于 2017-4-20 18:59:15 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

5

主题

15

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1341
金钱
1341
注册时间
2018-6-26
在线时间
139 小时
发表于 2018-7-2 17:04:05 | 显示全部楼层
请问楼主已经解决好了吗?求分享!
回复

使用道具 举报

52

主题

247

帖子

0

精华

高级会员

Rank: 4

积分
997
金钱
997
注册时间
2017-8-19
在线时间
160 小时
发表于 2018-7-2 17:38:44 | 显示全部楼层
LIZE 发表于 2018-7-2 17:04
请问楼主已经解决好了吗?求分享!

自己动手写吧。就是用DAC和TIME就可以了。往TIME中断里面塞你写好的波形函数数据。函数一般用数组进行分点存放。
回复

使用道具 举报

5

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
91
金钱
91
注册时间
2017-7-3
在线时间
17 小时
发表于 2018-10-27 20:47:18 | 显示全部楼层
前进的小蜗牛 发表于 2016-6-6 11:16
还在吗?@WZTENG ,请问一下,你程序中用定时器是什么作用?

在吗?我最近也在研究这个,但是用示波器看PA4口发出的波形发现并不是要输出的波形,请问你是怎么解决的呢?
回复

使用道具 举报

37

主题

596

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1574
金钱
1574
注册时间
2017-7-17
在线时间
308 小时
发表于 2018-10-27 23:21:52 | 显示全部楼层
哪个学校的课程设计。
回复

使用道具 举报

4

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
729
金钱
729
注册时间
2016-7-21
在线时间
281 小时
发表于 2018-11-9 16:06:00 | 显示全部楼层
RenJianYu 发表于 2018-10-27 20:47
在吗?我最近也在研究这个,但是用示波器看PA4口发出的波形发现并不是要输出的波形,请问你是怎么解决的 ...

我很早就移植了,今天测试了一下,也是显示不了想要的数据,一直是锯齿波,请问你解决了?感谢
回复

使用道具 举报

5

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
91
金钱
91
注册时间
2017-7-3
在线时间
17 小时
发表于 2018-11-9 16:48:15 | 显示全部楼层
luorong 发表于 2018-11-9 16:06
我很早就移植了,今天测试了一下,也是显示不了想要的数据,一直是锯齿波,请问你解决了?感谢

并没有
回复

使用道具 举报

4

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
729
金钱
729
注册时间
2016-7-21
在线时间
281 小时
发表于 2018-11-9 18:03:45 | 显示全部楼层

好的,感谢
回复

使用道具 举报

21

主题

86

帖子

0

精华

高级会员

Rank: 4

积分
639
金钱
639
注册时间
2017-3-6
在线时间
64 小时
发表于 2019-3-7 01:51:04 来自手机 | 显示全部楼层
我在设置频率时遇到了麻烦,不知楼主可否交流一哈
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2020-1-8
在线时间
0 小时
发表于 2020-1-11 22:17:44 | 显示全部楼层
哇塞,可以哦,这种方式真不错,值得参考参考
回复

使用道具 举报

0

主题

8

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2019-10-22
在线时间
5 小时
发表于 2020-4-8 21:08:01 | 显示全部楼层
大佬问题解决了吗 可以提供源码吗  可以给辛苦费
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
7
金钱
7
注册时间
2020-6-15
在线时间
2 小时
发表于 2021-3-7 19:34:27 | 显示全部楼层
学习了,去调试下看波形
回复

使用道具 举报

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
128
金钱
128
注册时间
2021-3-4
在线时间
28 小时
发表于 2022-7-4 18:45:05 | 显示全部楼层
BlueFox 发表于 2021-3-7 19:34
学习了,去调试下看波形

大佬,可以加好友交流一下吗,416341641
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-26 20:11

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表