2021-10-07 03:52 PM
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!
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...
Solved! Go to Solution.
2021-10-18 11:05 AM
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.
2021-10-07 05:08 PM
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
2021-10-08 02:23 PM
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
2021-10-18 11:05 AM
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.