cancel
Showing results for 
Search instead for 
Did you mean: 

Cannot get continuous data from SDADC

KShen.1
Associate II

Background: I use the stm32373c evaluation board to make project. One part of the project is to use the 16bit SDADC to acquire sinewaveform generated from function generator and send the data to pc sw thr. uart. I follow the evaluation board example called "SDADC_Voltmeter" and modify the code for my own use. 

I found I cannot get the whole sinwaveform because many data has the same value, they are not continuous. I am not sure if there's important SDADC configuration setting I need to notice?

The attachment is the waveform pic get from pc sw thr. uart, inner debug screenshot and the "SDADC_Voltmeter" example code.

Thanks for help!

0693W00000FBpDcQAL.png 

 I also try to use the Inner debug to watch the data acquired from sdadc, unfortunately they are the same issue... many number is the same, not continuous...0693W00000FBpM5QAL.png

1 ACCEPTED SOLUTION

Accepted Solutions
KShen.1
Associate II

I think i found the reason why board cannot acquire high speed adc data. As the code is based on example, the original example code set the gpio speed to low. I alter it to high, then looks like it works. 

View solution in original post

3 REPLIES 3

Perhaps I missed the USART stuff. The project is incomplete, and no point posting a copy of the unmodified example files. Find a better example for the task at hand.

If you want to capture wave forms you'd do much better using DMA to take periodic samples, not spin in a loop, somewhat asynchronously and post measurements to a slow serial connection.

You'd want a sample rate at least twice that of the wave form you're trying to capture to meet the Nyquist criterion

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
KShen.1
Associate II

Tesla, Thank you for your reply!

Actually in the project, I create a global data array and put the array in the loop. During the loop, the data array will be updated every time after acquired a new value. I also add a timer to save the data every 100ms. The uart will transmit the saved data out when serial port receive a proper command byte.

As the original code is long and messy, I just collect some useful code here. Thanks for the help!

/* InjectedConvData contains the result of the conversion, updated in HAL_SDADC_InjectedConvCpltCallback*/
__IO int16_t InjectedConvData = 0;
 
/* Buffer used for reception */
uint8_t aRxCmd[RXCMDSIZE] = {0};
uint16_t aRxData[TXDATASIZE] = {0};
uint16_t data[TXDATASIZE + 1] = {0};
uint cnt_acq = 0;
uint cnt_data = 0; 
 
int main(void)
{
  __IO uint16_t newDigi = 0;
...................
...................
 
 while (endOfExample == 0)
  {
	/* Compute the input voltage */
	inputVoltageMv = (((InjectedConvData + 32768) * SDADC_VREF) / (SDADC_GAIN * SDADC_RESOL));
 
	/* Update new data to data array line */
	newDigi = 65536 * inputVoltageMv / 3300;
	if (cnt_data < TXDATASIZE)
	{
		aRxData[cnt_data] = newDigi;
	}
	else
	{
		cnt_data = 0;
	}
	cnt_data++;
 }
................
}
 
/**
  * @brief  Injected conversion complete callback.
  * @param  hsdadc : SDADC handle.
  * @retval None
  */
void HAL_SDADC_InjectedConvCpltCallback(SDADC_HandleTypeDef *hsdadc)
{
  /* Get conversion value */
  InjectedConvData = HAL_SDADC_InjectedGetValue(hsdadc, (uint32_t *) &InjChannel);
}
 
/**
  * @brief  Period elapsed callback in non blocking mode
  * @param  htim : TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	/* build data array line */
	int cnt;
	cnt = cnt_data - 1;
	if (cnt < 0) return;
 
	//rearrange data array line
	for (int i = cnt; i < TXDATASIZE; i++)
		data[i - cnt ] = aRxData[i];
	for (int j = 0; j < cnt; j++)
		data[TXDATASIZE - cnt + j] = aRxData[j];
}
 
/**
  * @brief  Rx Transfer completed callback
  * @param  huart: UART handle
  * @note   This example shows a simple way to report end of DMA Rx transfer, and
  *         you can add your own implementation.
  * @retval None
  */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  uint8_t SN[] = "***123456***";
  int cnt;
  switch(*aRxCmd)
  {
	case 0x96 : //Transmit data
	   	if (HAL_UART_Transmit(&UartHandle, (uint8_t*)data, TXDATASIZE, 500)!= HAL_OK)
	   	{
	   		Error_Handler();
	   	}
	   	break;
 
	default : //Return hex back if the received cmd is invalid
		if(HAL_UART_Transmit_DMA(&UartHandle, (uint8_t*)aRxCmd, RXCMDSIZE)!= HAL_OK)
		{
			Error_Handler();
		}
		break;
  }
 
  if (HAL_UART_Receive_DMA(&UartHandle, (uint8_t *)aRxCmd, RXCMDSIZE) != HAL_OK)
  {
	/* Transfer error in reception process */
	Error_Handler();
  }
}

Up to here, i just realized probably the global data array cannot save the real updated number as the loop runs too much faster...??? How do u think? Thanks!

​Kevin

KShen.1
Associate II

I think i found the reason why board cannot acquire high speed adc data. As the code is based on example, the original example code set the gpio speed to low. I alter it to high, then looks like it works.