AnsweredAssumed Answered

STM32F4DISCOVERY IAR Optimization problem with DAC and TIMER

Question asked by GiorgioG on Jun 11, 2015
Hi everybody.
I'm learning how to use the STM32F407 mcu and I'm working with IAR and CubeMX.
I'm trying to write a program that charges the value (8bit aligned) from the ADC (PA0) in the output register of DAC1 (PA4) on each update event interrupt from TIM7 (44Khz).
On each update event the ADC value is stored in BUFFER and then in the DAC.
I've configured gpio alternate functions, nvic, rcc, dac and adc like stated in the HAL reference file.
Before trying to do ADC to DAC "bridge" I try to understand if the DAC works correctly connecting PA4 to an oscilloscope and writing a simple 8-bit ramp to the DAC in the while(1) loop in main, nothing strange happens, the sawthoot is displayed with no errors, but if I put a pin toggle (led on PD15) in the TIM7 interrupt handler to measure the timer period I can see the interrupt is only running at 1282 Hz (trying to change the prescaler and period settings does not make any difference, the interrupt will always trigger at this frequency).
If I disable the code optimization from HIGH to NONE the TIM7 interrupt starts to work correctly according to the prescaler (477) and period (3), but the DAC stops working at all. I'm a bit confused...

Code in main.c
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_DAC_Init();
  MX_TIM7_Init();
  HAL_MspInit();
  HAL_ADC_MspInit(&hadc1);
  HAL_DAC_MspInit(&hdac);
  HAL_TIM_Base_MspInit(&htim7);
  HAL_TIM_Base_Start_IT(&htim7);
  uint8_t BUFFER;
  while (1)
  {
    BUFFER=BUFFER+1;
    HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_8B_R,BUFFER);   
    HAL_DAC_Start(&hdac,DAC_CHANNEL_1);
  }
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  __PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 5;
  RCC_OscInitStruct.PLL.PLLN = 210;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
  RCC_ClkInitStruct.ClockType = 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;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

}

void MX_ADC1_Init(void)
{
  ADC_ChannelConfTypeDef sConfig;
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV6;
  hadc1.Init.Resolution = ADC_RESOLUTION8b;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.EOCSelection = EOC_SINGLE_CONV;
  HAL_ADC_Init(&hadc1);
  sConfig.Channel = ADC_CHANNEL_10;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}

void MX_DAC_Init(void)
{
  DAC_ChannelConfTypeDef sConfig;
  hdac.Instance = DAC;
  HAL_DAC_Init(&hdac);
  sConfig.DAC_Trigger = DAC_TRIGGER_SOFTWARE;
  sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
  HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1);
}

void MX_TIM7_Init(void)
{
  TIM_MasterConfigTypeDef sMasterConfig;
  htim7.Instance = TIM7;
  htim7.Init.Prescaler = 477;
  htim7.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim7.Init.Period = 3;
  HAL_TIM_Base_Init(&htim7);
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(&htim7, &sMasterConfig);
}

void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  __GPIOH_CLK_ENABLE();
  __GPIOC_CLK_ENABLE();
  __GPIOA_CLK_ENABLE();
  __GPIOD_CLK_ENABLE();
  GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}

Code in stm32f4xx_it.c
void TIM7_IRQHandler(void)
{
  HAL_TIM_IRQHandler(&htim7);
  HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_15);//TICKS();
}

Any help would be highly appreciated.

Outcomes