2017-10-24 4 views
0

Dies ist mein Code für DAC mit DMA. Ich möchte eine Dreieckwelle der Frequenz 8kHz mit DAC erzeugen, der mit Update-Rate von 1MSPS arbeitet. Ich benutze CUBEMX und System Workbench. Ich verwende Timer Trigger für DAC. Ich arbeite an der Entdeckungskarte stm32L476. Ich bekomme keine Welle, wenn ich versuche, die Update-Rate auf 1MSPS zu setzen. Wenn ich die Aktualisierungsrate auf 500 kps setze, bekomme ich eine dreieckige Welle mit ungleichmäßiger Steigung. Kann mir jemand sagen, was ich tun soll, um dies zu beheben und was soll ich tun, damit mein Code wie gewünscht läuft?Wie funktioniert der DAC bei einer Update-Geschwindigkeit von 1MSPS?

#include "main.h" 
#include "stm32l4xx_hal.h" 
/* USER CODE BEGIN Includes */ 

/* USER CODE END Includes */ 

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

TIM_HandleTypeDef htim2; 

/* USER CODE BEGIN PV */ 
/* Private variables ------------------------------------------------------- 
--*/ 

/* USER CODE END PV */ 

/* 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_TIM2_Init(void); 

/* USER CODE BEGIN PFP */ 
/* Private function prototypes --------------------------------------------- 
--*/ 
const uint16_t val[] = {65,130,195,260,325,390,455,520, 
    585,650,715,780,846,911,976,1041, 
    1106,1171,1236,1301,1366,1431,1496,1561, 
    1626,1691,1756,1821,1886,1951,2016,2081, 
    2146,2211,2276,2341,2406,2472,2537,2602, 
    2667,2732,2797,2862,2927,2992,3057,3122, 
    3187,3252,3317,3382,3447,3512,3577,3642, 
    3707,3772,3837,3902,3967,4032,4065,4032, 
    3967,3902,3837,3772,3707,3642,3577,3512, 
    3447,3382,3317,3252,3187,3122,3057,2992, 
    2927,2862,2797,2732,2667,2602,2537,2472, 
    2406,2341,2276,2211,2146,2081,2016,1951, 
    1886,1821,1756,1691,1626,1561,1496,1431, 
    1366,1301,1236,1171,1106,1041,976,911, 
    846,780,715,650,585,520,455,390, 
    325,260,195,130,65,0}; 
/* USER CODE BEGIN 0 */ 
/* USER CODE END PFP */ 

/* USER CODE BEGIN 0 */ 
/* USER CODE END PFP */ 

/* USER CODE BEGIN 0 */ 
/* USER CODE END PFP */ 

/* USER CODE BEGIN 0 */ 

/* USER CODE END 0 */ 

int main(void) 
    { 

    /* USER CODE BEGIN 1 */ 
    int n=sizeof(val); 
    int l=n/sizeof(val[0]); 
    /* USER CODE END 1 */ 

    /* MCU Configuration------------------------------------------------------ 
----*/ 

    /* Reset of all peripherals, Initializes the Flash interface and the 
Systick. */ 
    HAL_Init(); 

    /* USER CODE BEGIN Init */ 

    /* USER CODE END Init */ 

    /* Configure the system clock */ 
    SystemClock_Config(); 

    /* USER CODE BEGIN SysInit */ 

    /* USER CODE END SysInit */ 

    /* Initialize all configured peripherals */ 
    MX_GPIO_Init(); 
    MX_DMA_Init(); 
    MX_DAC1_Init(); 
    MX_TIM2_Init(); 

    /* USER CODE BEGIN 2 */ 
    HAL_TIM_Base_Start(&htim2); 
    //HAL_DAC_Start(&hdac1, DAC_CHANNEL_2); 
    HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t*)val, l,    DAC_ALIGN_12B_R); 
    /* USER CODE END 2 */ 

    /* Infinite loop */ 
    /* USER CODE BEGIN WHILE */ 
    while (1) 
    { 
    /* USER CODE END WHILE */ 

    /* USER CODE BEGIN 3 */ 

    } 
    /* USER CODE END 3 */ 

} 

/** System Clock Configuration 
*/ 
void SystemClock_Config(void) 
{ 

    RCC_OscInitTypeDef RCC_OscInitStruct; 
    RCC_ClkInitTypeDef RCC_ClkInitStruct; 

    /**Initializes the CPU, AHB and APB busses clocks 
    */ 
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI; 
    RCC_OscInitStruct.MSIState = RCC_MSI_ON; 
    RCC_OscInitStruct.MSICalibrationValue = 0; 
    RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6; 
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; 
    RCC_OscInitStruct.PLL.PLLM = 1; 
    RCC_OscInitStruct.PLL.PLLN = 40; 
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; 
    RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; 
    RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; 
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) 
    { 
    _Error_Handler(__FILE__, __LINE__); 
    } 

    /**Initializes the CPU, AHB and APB busses clocks 
    */ 
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK 
          |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; 
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 
     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; 
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; 
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV4; 

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) 
    { 
    _Error_Handler(__FILE__, __LINE__); 
    } 

    /**Configure the main internal regulator output voltage 
    */ 
    if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) !=  HAL_OK) 
    { 
    _Error_Handler(__FILE__, __LINE__); 
    } 

    /**Configure the Systick interrupt time 
    */ 
    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); 

    /**Configure the Systick 
    */ 
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); 

    /* SysTick_IRQn interrupt configuration */ 
    HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); 
} 

/* DAC1 init function */ 
static void MX_DAC1_Init(void) 
{ 

    DAC_ChannelConfTypeDef sConfig; 

    /**DAC Initialization 
    */ 
    hdac1.Instance = DAC1; 
    if (HAL_DAC_Init(&hdac1) != HAL_OK) 
    { 
    _Error_Handler(__FILE__, __LINE__); 
    } 

    /**DAC channel OUT2 config 
    */ 
    sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE; 
    sConfig.DAC_Trigger = DAC_TRIGGER_T2_TRGO; 
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; 
    sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_ENABLE; 
    sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY; 
    if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_2) != HAL_OK) 
    { 
    _Error_Handler(__FILE__, __LINE__); 
    } 

} 

/* TIM2 init function */ 
static void MX_TIM2_Init(void) 
{ 

    TIM_ClockConfigTypeDef sClockSourceConfig; 
    TIM_MasterConfigTypeDef sMasterConfig; 

    htim2.Instance = TIM2; 
    htim2.Init.Prescaler = 19; 
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP; 
    htim2.Init.Period = 1; 
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; 
    if (HAL_TIM_Base_Init(&htim2) != HAL_OK) 
    { 
    _Error_Handler(__FILE__, __LINE__); 
    } 

    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; 
    if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) 
    { 
    _Error_Handler(__FILE__, __LINE__); 
    } 

    sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; 
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; 
    if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) !=  HAL_OK) 
    { 
    _Error_Handler(__FILE__, __LINE__); 
    } 

} 

/** 
    * Enable DMA controller clock 
     */ 
static void MX_DMA_Init(void) 
{ 
    /* DMA controller clock enable */ 
    __HAL_RCC_DMA1_CLK_ENABLE(); 

     /* DMA interrupt init */ 
    /* DMA1_Channel4_IRQn interrupt configuration */ 
     HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0); 
    HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn); 

} 

/** Configure pins as 
     * Analog 
       * Input 
       * Output 
     * EVENT_OUT 
     * EXTI 
*/ 
static void MX_GPIO_Init(void) 
{ 

    GPIO_InitTypeDef GPIO_InitStruct; 

    /* GPIO Ports Clock Enable */ 
     __HAL_RCC_GPIOA_CLK_ENABLE(); 

    /*Configure GPIO pin : PA4 */ 
    GPIO_InitStruct.Pin = GPIO_PIN_4; 
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 
    GPIO_InitStruct.Pull = GPIO_NOPULL; 
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 

} 

/* USER CODE BEGIN 4 */ 

/* USER CODE END 4 */ 

/** 
     * @brief This function is executed in case of error occurrence. 
    * @param None 
    * @retval None 
    */ 
     void _Error_Handler(char * file, int line) 
{ 
    /* USER CODE BEGIN Error_Handler_Debug */ 
    /* User can add his own implementation to report the HAL error return  state */ 
    while(1) 
    { 
    } 
    /* USER CODE END Error_Handler_Debug */ 
} 

#ifdef USE_FULL_ASSERT 

     /** 
    * @brief Reports the name of the source file and the source line number 
    * where the assert_param error has occurred. 
    * @param file: pointer to the source file name 
     * @param line: assert_param error line source number 
    * @retval None 
    */ 
void assert_failed(uint8_t* file, uint32_t line) 
{ 
    /* USER CODE BEGIN 6 */ 
    /* User can add his own implementation to report the file name and line  number, 
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file,  line) */ 
    /* USER CODE END 6 */ 

} 

#endif 
+0

Mit "einfach zu bedienen" HAL ist immer kompliziert und zeitaufwändig ohne die Garantie, erfolgreich zu sein. –

+0

Können Sie sich bitte meinen Code ansehen und mir sagen, ob etwas nicht stimmt? Weil ich HAL lerne. Also muss ich herausfinden, wo das Problem liegt. – user8398475

Antwort

0

Es ist die Version für den STM32 mit DMA-Kanälen und einen DAC mit zwei Kanälen. Einfach für Ihren Mikro zu

void StartDAC(DAC_TypeDef *dac, int DACchannel, uint16_t Nsamples, uint16_t *samples, uint16_t psc, uint16_t arr) 
{ 

    DMA_Channel_TypeDef *DMA_Channel = !DACchannel ? DMA2_Channel3 : DMA2_Channel4; 
    TIM_TypeDef *tim = !DACchannel ? TIM6 : TIM7; 

    DMA_Channel->CCR = 0; 
    if (!DACchannel) 
    { 
     dac->CR &= ~(DAC_CR_DMAUDRIE1 | DAC_CR_DMAEN1); 
     dac->CR |= (DAC_CR_DMAUDRIE1 | DAC_CR_DMAEN1); 
    } 
    else 
    { 
     dac->CR &= ~(DAC_CR_DMAUDRIE2 | DAC_CR_DMAEN2); 
     dac->CR |= (DAC_CR_DMAUDRIE2 | DAC_CR_DMAEN2); 
    } 
    DMA_Channel->CNDTR = Nsamples; 
    DMA_Channel->CMAR = (uint32_t)samples; 
    DMA_Channel->CPAR = !(DACchannel) ? (uint32_t)&DAC->DHR12R1 : (uint32_t)&DAC->DHR12R2; 
    DMA_Channel->CCR |= DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_EN | DMA_CCR_TEIE | DMA_CCR_DIR; 
    tim->DIER = TIM_DIER_UDE;// | TIM_DIER_UIE; 
    tim->CR2 |= TIM_CR2_MMS_1; 
    tim->PSC = psc; 
    tim->ARR = arr; 
    /* tim clock frequency/((psc + 1) * (arr + 1) * nsamples) == frequency of the generated signal - do the calculations yourself*/ 
    tim->CR1 |= TIM_CR1_CEN; 
} 
0

Nun, ich habe gerade herausgefunden, wo das Problem liegt. Die DAC-Geschwindigkeit ist begrenzt, wenn sie zusammen mit dem externen Ausgangspin mit anderen Peripheriegeräten verbunden ist. Um DAC bei höheren Geschwindigkeiten zu verwenden, sollte der DAC nur mit einem externen Pin verbunden sein. Zumindest habe ich das gefunden. Zuvor hatte ich die Option ausgewählt, den DAC mit externen Pin- und On-Chip-Peripheriegeräten zu verbinden. Also konnte ich DAC nicht mit hoher Geschwindigkeit benutzen. Aber dann wählte ich die Option nur auf externen Pin (DAC nur mit externem Pin verbunden), löste das Problem und DAC funktioniert gut. Stellen Sie außerdem sicher, dass in diesem DAC-Ausgangs-Pin keine Widerstandskondensator-Serien in Reihe geschaltet sind, da sonst die Ausgangswelle gestört werden kann.

Verwandte Themen