cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F373VCT6 SDADC READING PROBLEM

lernd
Associate II
Posted on February 26, 2013 at 10:39

The original post was too long to process during our migration. Please click on the attachment to read the original post.
13 REPLIES 13
Amel NASRI
ST Employee
Posted on July 29, 2013 at 14:41

Hello,

How similar are both issues? Could you please explain your case, give a complete description with minimum required code?

Thanks!

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

bpacan
Associate II
Posted on August 08, 2013 at 07:48

Hi Mayla

I get correct measurements when single channel is connected (connected I mean voltage is supplied on input) and ca. 3mV read offset when one or more other channels are connected at the same time.

We use 8 channels SDADC (SDADC1:4,5,6,7,8 and SDADC3:6,7,8), LQFP64 package.

Init is done on start, first conversion is started at the end of init, SDADC_ISR stores result, changes channel and starts timer (10ms, tested up to 100ms), main loop trigger next channel conversion after timer elapsed.

This is a part of my code:

uint32_t SDADC13_Init(void)

{

   SDADC_AINStructTypeDef SDADC_AINStructure;

   GPIO_InitTypeDef GPIO_InitStructure;

   NVIC_InitTypeDef NVIC_InitStructure;

   uint32_t SDADCTimeout = 0;

   /* SDADC3 APB2 interface clock enable */

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDADC3 | RCC_APB2Periph_SDADC1, ENABLE);

   /* PWR APB1 interface clock enable */

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

   /* Enable SDADC3 analog interface */

   PWR_SDADCAnalogCmd(PWR_SDADCAnalog_3, ENABLE);

   PWR_SDADCAnalogCmd(PWR_SDADCAnalog_1, ENABLE);

   /* Set the SDADC divider: 0.5MHz...6MHz */

   //64/48=1,33MHz

   RCC_SDADCCLKConfig(RCC_SDADCCLK_SYSCLK_Div48);

   /* RCC_AHBPeriph_GPIOD Peripheral clock enable */

   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE, ENABLE);

   /* SDADC1 channels */

   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;

   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

   GPIO_Init(GPIOD, &GPIO_InitStructure);

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_14 | GPIO_Pin_15;

   GPIO_Init(GPIOB, &GPIO_InitStructure);

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;

   GPIO_Init(GPIOE, &GPIO_InitStructure);

   /* Select External reference: The reference voltage selection is available

   only in SDADC1 and therefore to select the VREF for SDADC2/SDADC3, SDADC1

   clock must be already enabled */

   SDADC_VREFSelect(SDADC_VREF_Ext);//SDADC_VREF_Ext

   /* Insert delay equal to ~5 ms */

   int times;// = times;

   for(times = 0; times < 320000; times++)asm(''nop'');

   /* Enable SDADC1 */

   SDADC_Cmd(SDADC3, ENABLE);

   SDADC_Cmd(SDADC1, ENABLE);

   /* Enter initialization mode */

   SDADC_InitModeCmd(SDADC3, ENABLE);

   SDADC_InitModeCmd(SDADC1, ENABLE);

   SDADCTimeout = SDADC_INIT_TIMEOUT;

   /* wait for INITRDY flag to be set */

   while((SDADC_GetFlagStatus(SDADC3, SDADC_FLAG_INITRDY) == RESET) && (--SDADCTimeout != 0));

   if(SDADCTimeout == 0)

   {

   /* INITRDY flag can not set */

   return 1;

   }

   SDADCTimeout = SDADC_INIT_TIMEOUT;

   /* wait for INITRDY flag to be set */

   while((SDADC_GetFlagStatus(SDADC1, SDADC_FLAG_INITRDY) == RESET) && (--SDADCTimeout != 0));

   if(SDADCTimeout == 0)

   {

   /* INITRDY flag can not set */

   return 1;

   }

   /* Analog Input configuration conf0: use single ended zero reference */

   SDADC_AINStructure.SDADC_InputMode = SDADC_InputMode_SEOffset;

   SDADC_AINStructure.SDADC_Gain = SDADC_Gain_1_2;

   SDADC_AINStructure.SDADC_CommonMode = SDADC_CommonMode_VSSA;

   SDADC_AINStructure.SDADC_Offset = 0x7FF;

   SDADC_AINInit(SDADC3, SDADC_Conf_0, &SDADC_AINStructure);

   SDADC_AINInit(SDADC1, SDADC_Conf_0, &SDADC_AINStructure);

   /* select SDADC channels to use conf0 */

   SDADC_ChannelConfig(SDADC1, SDADC_Channel_4 | SDADC_Channel_5 | SDADC_Channel_6 | SDADC_Channel_7 | SDADC_Channel_8, SDADC_Conf_0);

   SDADC_ChannelConfig(SDADC3, SDADC_Channel_6 | SDADC_Channel_7 | SDADC_Channel_8, SDADC_Conf_0);

   /* Disable continuous mode */

   SDADC_InjectedContinuousModeCmd(SDADC3, DISABLE);

   SDADC_InjectedContinuousModeCmd(SDADC1, DISABLE);

   /* Exit initialization mode */

   SDADC_InitModeCmd(SDADC3, DISABLE);

   SDADC_InitModeCmd(SDADC1, DISABLE);

   /* NVIC Configuration */

   NVIC_InitStructure.NVIC_IRQChannel = SDADC3_IRQn;

   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 11;

   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

   NVIC_Init(&NVIC_InitStructure);

   NVIC_InitStructure.NVIC_IRQChannel = SDADC1_IRQn;

   NVIC_Init(&NVIC_InitStructure);

   /* Enable end of injected conversion interrupt */

   SDADC_ITConfig(SDADC3, SDADC_IT_JEOC, ENABLE);

   SDADC_ITConfig(SDADC1, SDADC_IT_JEOC, ENABLE);

   // start converting, rest will be done from ISR and graph

   sAnInS.ucChannel = 0;

   SDADC_InjectedChannelSelect(SDADC3, SDADC_Channel_6);

   SDADC_SoftwareStartInjectedConv(SDADC3);

   return 0;

}

void SDADC3_IRQHandler(void)

{

...

ulData = SDADC_GetInjectedConversionValue(SDADCx, &ulChannel);

SDADC_NEXT_CH(&ulChannel);

TIMER_START(ulTimer);

...

}

void MainLoop_SDADCtask(void)

{

...

if(TIMER_ELAPSED(ulTimer) >=

 10){

SDADC_InjectedChannelSelect(SDADCx, ulChannel);

         SDADC_SoftwareStartInjectedConv(SDADCx);

}

...

}

grisha
Associate
Posted on September 02, 2015 at 20:32

I use STM32F373, i have problem measurement Sigma-Delta ADC.

In the middle of the measuring range is 1.65V ADC overstatement at 880-900 units, which is about 50 millivolts given that VREF 3.3V See scheme. Why is overstating the ADC?

Example I took out of the library strandanoy ST

STM32F37x_DSP_StdPeriph_Lib_V1.0.0\Project\STM32F37x_StdPeriph_Examples\SDADC\SDADC_Voltmeter.

http://www.st.com/web/en/catalog/tools/PF258151

Downloads

/* Includes ------------------------------------------------------------------*/
#include ''main.h''
/** @addtogroup Template_Project
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#if defined (USE_STM32373C_EVAL)
#define MESSAGE1 ''STM32F37x CortexM4 '' 
#define MESSAGE2 '' Device running on '' 
#define MESSAGE3 '' STM32373C-EVAL '' 
#endif
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
USART_InitTypeDef USART_InitStructure;
static
__IO uint32_t TimingDelay;
RCC_ClocksTypeDef RCC_Clocks;
/* Private function prototypes -----------------------------------------------*/
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program.
* @param None
* @retval None
*/
int
main(
void
)
{
/*!< At this stage the microcontrollers clock setting is already configured, 
this is done through SystemInit() function which is called from startup
file (startup_stm32f37x.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f37x.c file
*/
/* SysTick end of count event each 10ms */
RCC_GetClocksFreq(&RCC_Clocks);
SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);
/* Initialize LEDs, Key Button, LCD and COM port(USART) available on
STM32373C-EVAL board *****************************************************/
STM_EVAL_LEDInit(LED1);
STM_EVAL_LEDInit(LED2);
STM_EVAL_LEDInit(LED3);
STM_EVAL_LEDInit(LED4);
/* USARTx configured as follow:
- BaudRate = 115200 baud 
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
STM_EVAL_COMInit(COM1, &USART_InitStructure);
/* Initialize the LCD */
#if defined (USE_STM32373C_EVAL)
STM32373C_LCD_Init();
#endif
/* Display message on STM32373C-EVAL LCD ************************************/
/* Clear the LCD */
LCD_Clear(LCD_COLOR_WHITE);
/* Set the LCD Back Color */
LCD_SetBackColor(LCD_COLOR_BLUE);
/* Set the LCD Text Color */
LCD_SetTextColor(LCD_COLOR_WHITE);
LCD_DisplayStringLine(LCD_LINE_0, (uint8_t *)MESSAGE1);
LCD_DisplayStringLine(LCD_LINE_1, (uint8_t *)MESSAGE2);
LCD_DisplayStringLine(LCD_LINE_2, (uint8_t *)MESSAGE3);
/* Retarget the C library printf function to the USARTx, can be USART2 or USART3
depending on the EVAL board you are using ********************************/
printf(
''\n\r %s''
, MESSAGE1);
printf(
'' %s''
, MESSAGE2);
printf(
'' %s\n\r''
, MESSAGE3);
/* Add your application code here
*/
/* Infinite loop */
while
(1)
{
/* Toggle LD1 */
STM_EVAL_LEDToggle(LED1);
/* Insert 50 ms delay */
Delay(5);
/* Toggle LD2 */
STM_EVAL_LEDToggle(LED2);
/* Insert 50 ms delay */
Delay(5);
/* Toggle LD3 */
STM_EVAL_LEDToggle(LED3);
/* Insert 50 ms delay */
Delay(5);
/* Toggle LD4 */
STM_EVAL_LEDToggle(LED4);
/* Insert 50 ms delay */
Delay(5);
}
}
/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
USART_SendData(EVAL_COM1, (uint8_t) ch);
/* Loop until the end of transmission */
while
(USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET)
{}
return
ch;
}
/**
* @brief Inserts a delay time.
* @param nTime: specifies the delay time length, in 10 ms.
* @retval None
*/
void
Delay(__IO uint32_t nTime)
{
TimingDelay = nTime;
while
(TimingDelay != 0);
}
/**
* @brief Decrements the TimingDelay variable.
* @param None
* @retval None
*/
void
TimingDelay_Decrement(
void
)
{
if
(TimingDelay != 0x00)
{ 
TimingDelay--;
}
}
#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 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) */
/* Infinite loop */
while
(1)
{
}
}
#endif
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
/* Includes ------------------------------------------------------------------*/
#include ''stm32f37x.h''
#include ''stm32f37x_conf.h''
//#include ''stm32373c_eval.h''
#include <stdio.h>
//#include ''stm32373c_eval/stm32373c_eval_lcd.h''
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Message to be displayed on LCD */
#define MESSAGE1 '' Voltmeter ''
/* A potentiometer (POT) is connected to PB1 which corresponds to SDADC1 channel 5P */
#define POT_GPIO_PORT GPIOE
#define POT_GPIO_PIN GPIO_Pin_8
#define POT_GPIO_CLK RCC_AHBPeriph_GPIOE
#define POT_SDADC SDADC1
#define POT_SDADC_CLK RCC_APB2Periph_SDADC1
#define POT_SDADC_PWR PWR_SDADCAnalog_1
#define POT_SDADC_VREF SDADC_VREF_Ext /* External reference is selected */
#define POT_SDADC_GAIN SDADC_Gain_1 /* Internal gain 1 is seleted: 
SDADC_GAIN must be updated according to
POT_SDADC_GAIN */
#define SDADC_GAIN (uint32_t) 1 /* SDADC internal gain is set to 1: update this define
according to POT_SDADC_GAIN */
#define POT_SDADC_CHANNEL SDADC_Channel_8
#define SDADC_RESOL (uint32_t) 65535 /* 2e16 - 1 */
#define SDADC_INIT_TIMEOUT 30 /* ~ about two SDADC clock cycles after INIT is set */
#define SDADC_CAL_TIMEOUT 4*30720 /* ~5.12 ms at 6 MHz in a single calibration sequence */
#define SDADC_VREF (float) 3300 /* SDADC external reference is set to 3.3V */
//#define RESISTANCE_COEFFICIENT (float)0.385f
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void
TimingDelay_Decrement(
void
);
void
Delay(__IO uint32_t nTime);
#endif /* __MAIN_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

________________

Attachments :

Delta-Sigma-ADC_STM32F373.png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0i7&d=%2Fa%2F0X0000000bds%2Ff70IeFpT5RASXT4lE3J9OdnFieXtdwoXC.5kDgjFjnc&asPdf=false

______-_____.png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0nt&d=%2Fa%2F0X0000000bdp%2FKYAD_isx2IA772j1EhQUblBHePyhaEH6TYZ63AfXgLE&asPdf=false
geryhold
Associate
Posted on September 20, 2015 at 14:56

Problem solved

The documents in the delta sigma ADC is written that there are two types of errors, 1 and 2. The offset error gain error. Offset error is eliminated calibration initialization program (or you can do it manually after each measurement to take away or add a fixed number), but with the gain error is written that when Vin = Vref does not mean that it would be 65,535, is connected with the fact that the input chain RC. And therefore it is necessary after each measurement multiplied by the factor, or change the voltage Vref in the calculation formulas. I like using REF3333 -3.3V, and enter values ​​in the formula have 3.21 volts, while I enter values ​​ADC gives 65535