AnsweredAssumed Answered

How to reconstruct input signal by using DAC?

Question asked by goutham gumm on May 23, 2018

I am working on a project in which -

  1. I have to continuously monitor the the ADC input on a microcontroller and check if the value crosses a certain threshold.
  2. If the value crosses the threshold, start a timer for 100ms.
  3. Within this period,use DMA to tranfer ADC samples to a buffer.After the period elapses,a periodelapsed callback will be called where I stop the timer and the ADC DMA transfer process.

I am giving an ADC input from a piezoelectric sensor and I want to send these samples onto a the output of a DAC and check on my oscilloscope if it matches with my input. But I am not sure how to do that. Can anyone guide me here? I have configured my ADC sampling rate to about 50 microseconds and timer period to 100 milliseconds. Here is my code - 

#include "main.h"#include "stm32f4xx_hal.h"#include "usb_host.h"ADC_HandleTypeDef hadc1;DMA_HandleTypeDef hdma_adc1;DAC_HandleTypeDef hdac;DMA_HandleTypeDef hdma_dac1;I2C_HandleTypeDef hi2c1;TIM_HandleTypeDef htim3; /* Private variables ---------------------------------------------------------*/int do_once;int entry_count=0;int interrupt_counter=0;uint16_t raw_value = 0;uint16_t buffer[2000]={0};float VDDAmillivolts=0;/* 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_I2C1_Init(void);static void MX_ADC1_Init(void);static void MX_DAC_Init(void);static void MX_TIM3_Init(void);void MX_USB_HOST_Process(void);void errorhandle(); /* USER CODE BEGIN PFP *//* Private function prototypes -----------------------------------------------*/void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){    if(htim->Instance==TIM3)    {        HAL_ADC_Stop_DMA(&hadc1);        HAL_TIM_Base_Stop_IT(&htim3);        do_once=1;        interrupt_counter++;     }}/* USER CODE END PFP */    * @brief  The application entry point.  *  * @retval None  */int main(void){    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */  HAL_Init();  /* Configure the system clock */  SystemClock_Config();   /* Initialize all configured peripherals */  MX_GPIO_Init();  MX_DMA_Init();  MX_I2C1_Init();  MX_USB_HOST_Init();  MX_ADC1_Init();  MX_DAC_Init();  MX_TIM3_Init();    /* Infinite loop */  /* USER CODE BEGIN WHILE */   while (1)  {        do_once =0;        for(int index=0;index<2000;index++)        {            buffer[index]=0;        }        HAL_ADC_Start(&hadc1);        while (!(__HAL_ADC_GET_FLAG(&hadc1,ADC_FLAG_EOC)));        raw_value=HAL_ADC_GetValue(&hadc1);         VDDAmillivolts=(raw_value*3000)/(0xFFF);        if(VDDAmillivolts1>200)        {            entry_count++;            HAL_TIM_Base_Start_IT(&htim3);            while(do_once==0)            {                 if(HAL_ADC_Start_DMA(&hadc1,(uint32_t*)buffer,2000)!= HAL_OK)                    errorhandle();            }      }     }       /* USER CODE END WHILE */   /**   * @brief System Clock Configuration   * @retval None   */void SystemClock_Config(void){   RCC_OscInitTypeDef RCC_OscInitStruct;  RCC_ClkInitTypeDef RCC_ClkInitStruct;     /**Configure the main internal regulator output voltage      */  __HAL_RCC_PWR_CLK_ENABLE();   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);     /**Initializes the CPU, AHB and APB busses clocks      */  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 = 8;  RCC_OscInitStruct.PLL.PLLN = 336;  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;  RCC_OscInitStruct.PLL.PLLQ = 7;  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_5) != 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);}/* ADC1 init function */static void MX_ADC1_Init(void){   ADC_ChannelConfTypeDef sConfig;     /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)      */  hadc1.Instance = ADC1;  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;  hadc1.Init.Resolution = ADC_RESOLUTION_12B;  hadc1.Init.ScanConvMode = DISABLE;  hadc1.Init.ContinuousConvMode = ENABLE;  hadc1.Init.DiscontinuousConvMode = DISABLE;  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;  hadc1.Init.NbrOfConversion = 1;  hadc1.Init.DMAContinuousRequests = ENABLE;  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;  if (HAL_ADC_Init(&hadc1) != HAL_OK)  {    _Error_Handler(__FILE__, __LINE__);  }     /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.      */  sConfig.Channel = ADC_CHANNEL_1;  sConfig.Rank = 1;  sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)  {    _Error_Handler(__FILE__, __LINE__);  }}/* DAC init function */static void MX_DAC_Init(void){   DAC_ChannelConfTypeDef sConfig;     /**DAC Initialization      */  hdac.Instance = DAC;  if (HAL_DAC_Init(&hdac) != HAL_OK)  {    _Error_Handler(__FILE__, __LINE__);  }     /**DAC channel OUT1 config      */  sConfig.DAC_Trigger = DAC_TRIGGER_SOFTWARE;  sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;  if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK)  {    _Error_Handler(__FILE__, __LINE__);  }     /**DAC channel OUT2 config      */  if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_2) != HAL_OK)  {    _Error_Handler(__FILE__, __LINE__);  }}/* I2C1 init function */static void MX_I2C1_Init(void){   hi2c1.Instance = I2C1;  hi2c1.Init.ClockSpeed = 100000;  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;  hi2c1.Init.OwnAddress1 = 0;  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;  hi2c1.Init.OwnAddress2 = 0;  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;  if (HAL_I2C_Init(&hi2c1) != HAL_OK)  {    _Error_Handler(__FILE__, __LINE__);  }}/* TIM3 init function */static void MX_TIM3_Init(void){   TIM_ClockConfigTypeDef sClockSourceConfig;  TIM_MasterConfigTypeDef sMasterConfig;   htim3.Instance = TIM3;  htim3.Init.Prescaler = 8399;  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;  htim3.Init.Period = 999;  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)  {    _Error_Handler(__FILE__, __LINE__);  }   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)  {    _Error_Handler(__FILE__, __LINE__);  }   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)  {    _Error_Handler(__FILE__, __LINE__);  }}/**    * Enable DMA controller clock   */static void MX_DMA_Init(void) {  /* DMA controller clock enable */  __HAL_RCC_DMA2_CLK_ENABLE();  __HAL_RCC_DMA1_CLK_ENABLE();   /* DMA interrupt init */  /* DMA1_Stream5_IRQn interrupt configuration */  HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);  HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);  /* DMA2_Stream0_IRQn interrupt configuration */  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);}/** Configure pins as          * Analog          * Input          * Output         * EVENT_OUT         * EXTI      PC3   ------> I2S2_SD      PA6   ------> SPI1_MISO      PA7   ------> SPI1_MOSI      PB10   ------> I2S2_CK      PC7   ------> I2S3_MCK      PC10   ------> I2S3_CK      PC12   ------> I2S3_SD */static void MX_GPIO_Init(void){   GPIO_InitTypeDef GPIO_InitStruct;   /* GPIO Ports Clock Enable */  __HAL_RCC_GPIOE_CLK_ENABLE();  __HAL_RCC_GPIOC_CLK_ENABLE();  __HAL_RCC_GPIOH_CLK_ENABLE();  __HAL_RCC_GPIOA_CLK_ENABLE();  __HAL_RCC_GPIOB_CLK_ENABLE();  __HAL_RCC_GPIOD_CLK_ENABLE();   /*Configure GPIO pin Output Level */  HAL_GPIO_WritePin(CS_I2C_SPI_GPIO_Port, CS_I2C_SPI_Pin, GPIO_PIN_RESET);   /*Configure GPIO pin Output Level */  HAL_GPIO_WritePin(OTG_FS_PowerSwitchOn_GPIO_Port, OTG_FS_PowerSwitchOn_Pin, GPIO_PIN_SET);   /*Configure GPIO pin Output Level */  HAL_GPIO_WritePin(GPIOD, LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin                            |Audio_RST_Pin, GPIO_PIN_RESET);   /*Configure GPIO pin : CS_I2C_SPI_Pin */  GPIO_InitStruct.Pin = CS_I2C_SPI_Pin;  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  GPIO_InitStruct.Pull = GPIO_NOPULL;  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;  HAL_GPIO_Init(CS_I2C_SPI_GPIO_Port, &GPIO_InitStruct);   /*Configure GPIO pin : OTG_FS_PowerSwitchOn_Pin */  GPIO_InitStruct.Pin = OTG_FS_PowerSwitchOn_Pin;  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  GPIO_InitStruct.Pull = GPIO_NOPULL;  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;  HAL_GPIO_Init(OTG_FS_PowerSwitchOn_GPIO_Port, &GPIO_InitStruct);   /*Configure GPIO pin : PDM_OUT_Pin */  GPIO_InitStruct.Pin = PDM_OUT_Pin;  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;  GPIO_InitStruct.Pull = GPIO_NOPULL;  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;  GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;  HAL_GPIO_Init(PDM_OUT_GPIO_Port, &GPIO_InitStruct);   /*Configure GPIO pin : B1_Pin */  GPIO_InitStruct.Pin = B1_Pin;  GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;  GPIO_InitStruct.Pull = GPIO_NOPULL;  HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);   /*Configure GPIO pins : SPI1_MISO_Pin SPI1_MOSI_Pin */  GPIO_InitStruct.Pin = SPI1_MISO_Pin|SPI1_MOSI_Pin;  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;  GPIO_InitStruct.Pull = GPIO_NOPULL;  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;  GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);   /*Configure GPIO pin : BOOT1_Pin */  GPIO_InitStruct.Pin = BOOT1_Pin;  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;  GPIO_InitStruct.Pull = GPIO_NOPULL;  HAL_GPIO_Init(BOOT1_GPIO_Port, &GPIO_InitStruct);   /*Configure GPIO pin : CLK_IN_Pin */  GPIO_InitStruct.Pin = CLK_IN_Pin;  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;  GPIO_InitStruct.Pull = GPIO_NOPULL;  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;  GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;  HAL_GPIO_Init(CLK_IN_GPIO_Port, &GPIO_InitStruct);   /*Configure GPIO pins : LD4_Pin LD3_Pin LD5_Pin LD6_Pin                             Audio_RST_Pin */  GPIO_InitStruct.Pin = LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin                            |Audio_RST_Pin;  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  GPIO_InitStruct.Pull = GPIO_NOPULL;  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);   /*Configure GPIO pins : I2S3_MCK_Pin I2S3_SCK_Pin I2S3_SD_Pin */  GPIO_InitStruct.Pin = I2S3_MCK_Pin|I2S3_SCK_Pin|I2S3_SD_Pin;  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;  GPIO_InitStruct.Pull = GPIO_NOPULL;  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;  GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);   /*Configure GPIO pin : OTG_FS_OverCurrent_Pin */  GPIO_InitStruct.Pin = OTG_FS_OverCurrent_Pin;  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;  GPIO_InitStruct.Pull = GPIO_NOPULL;  HAL_GPIO_Init(OTG_FS_OverCurrent_GPIO_Port, &GPIO_InitStruct);   /*Configure GPIO pin : MEMS_INT2_Pin */  GPIO_InitStruct.Pin = MEMS_INT2_Pin;  GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;  GPIO_InitStruct.Pull = GPIO_NOPULL;  HAL_GPIO_Init(MEMS_INT2_GPIO_Port, &GPIO_InitStruct);}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//**   * @brief  This function is executed in case of error occurrence.   * @param  file: The file name as string.   * @param  line: The line in file as a number.   * @retval None   */void errorhandle(){    while(1)    {    }}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,      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */  /* USER CODE END 6 */}#endif /* USE_FULL_ASSERT *//**   * @}   *//**   * @}   *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Outcomes