STM32-DA发送正弦波

开发平台

STM32F0 + Cubemx + MDK V5

Cubemx配置(DA + DMA + Timer)

DA的工作原理是使用定时器在固定时间内将产生正弦波的数据通过DMA的方式传送到DA控制器,从而产生固定频率的正弦波。

DA配置

DA的DMA配置

DMA的配置

Timer的配置

Timer的主时钟配置为48MHz。

prescaler的作用是将工作的主时钟进行相应配置数据的分频。

例如下图所示设置为0代表不进行分频。如设置为1(从0开始计数),则表示对48M进行2分频,则时钟为24M。

Counter Period 的作用是表示在分频时钟下继续进行相应的分频,产生触发中断。

例如下图为239表示在48M下进行240分频,则产生的时钟48MHz / 240 = 200KHz。

即在200K的频率下发送DA的数据,每次发送的大小为half word(如上图DMA配置所示)。

MDK V5代码

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f0xx_hal.h"
#include <math.h>


/* Private variables ---------------------------------------------------------*/
DAC_HandleTypeDef hdac1;
DMA_HandleTypeDef hdma_dac1_ch1;

TIM_HandleTypeDef htim6;


/* Private variables ---------------------------------------------------------*/
#define PI 3.1415926
#define Um 1.8 /*正弦波峰峰值为1.8Vpp*/
uint16_t HZ;
#define DL 200 /*正弦波一个周期使用200个点进行描绘*/


/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_DAC1_Init(void);
static void MX_TIM6_Init(void);


/* Private function prototypes -----------------------------------------------*/
/*正弦波一个周期使用DL个点进行描绘且幅值为1.8Vpp*/
void SineWave_Data( uint16_t cycle ,uint16_t *D)
{
	uint16_t i;
	float JD;
	float ZH;
	float HD;
	for( i=0;i<cycle;i++)
	{   
		JD = 2*PI*i/cycle;  /*正弦波一个周期使用DL个点进行描绘*/
		ZH = 4096/3.23;  /*外部参考电压为3.3V,同时DA为12bits*/
		HD = (float)sin(JD);			  
		D[i]= (Um/2*HD+1)*ZH;  /*1.8Vpp的正弦波需要将sin的负半轴的数据向上平移0.9个单位*/
                               /*加1的目的是防止可能产生的信号很小部分被拉成0造成信号失真度较大*/
	}
}

int main(void)
{

	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
	MX_DMA_Init();
	MX_DAC1_Init();
	MX_TIM6_Init();


	uint16_t DualSine12bit[DL];                                                      	
	SineWave_Data(DL ,DualSine12bit);									
								
	HAL_TIM_Base_Start(&htim6);
	HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t *)DualSine12bit,DL,DAC_ALIGN_12B_R);


  while (1)
  {

  }


}

调试出现的问题

数组定义为500时,不能进入主程序且直接死掉。

需要修改startup_stm32f051x8.s文件中的

Stack_Size		EQU     0x400  /*修改为0x1000*/

在1k时有时发送不出数据

主要和1周期的sin函数点数有关系,其中绘制正弦波的点数不能超过timer触发中断的点数。
例如,本实例中发送1KHz正弦波,主要是保证DMA-1毫秒内发送的数据(DMA配置图中239)要大于绘制正弦波的点数(即程序中的DL=200)。

猜你喜欢

转载自blog.csdn.net/liuxiuqi19860119/article/details/84678890