1. 程式人生 > >STM32-DA傳送正弦波

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)。