STM32-DA发送正弦波
2018-09-18 本文已影响0人
QUIZ_JS
开发平台
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)。