[ST_MICRO]/STM32F32016. 12. 11. 22:19

[STM32F373 EVM] SDADC 16bit ADC 테스트

[STM32F373 EVM] SDADC 16bit ADC 테스트




STM32F3시리즈를 보면서 가장 눈길이 가는것은 16bit ADC (SDADC) 이다.  저가이면서 16bit ADC가 포함된 MCU로 사용하기에 좋을것 같다.



SDADC 특징

- Precise 16-bit sigma-delta ADCs (21 channels)

- 1.2/1.8V reference

- 16.6 ksps (multiple channels and up to 50 ksps)

- The data can be automatically stored in a system RAM buffer, reducing the software overhead. 

- Self-calibration (offset)

- 7 gain settings from 0.5x to 32x (analog gains: 0.5 - 8, digital gains: 16 - 32)




STM32F373 SDADC 블록도
STM32F372CBT6 은 48핀 패키지이고 SDADC1 만 사용가능하다.
따라서 PB0, PB1, PE8, PE9, PB2 만 사용 가능하다. 차동 입력은 2채널 가능하다.

PB0 -> ADC_IN8, SDADC1_AIN6P
PB1 -> ADC_IN9, SDADC1_AIN5P, SDADC1_AIN6M

PB2 -> SDADC1_AIN4P,SDADC2_AIN6P

PE8 -> SDADC1_AIN8P, SDADC2_AIN8P
PE9 -> SDADC1_AIN7P,SDADC1_AIN8M,SDADC2_AIN7P,SDADC2_AIN8M


PB14 -> SDADC3_AIN8P
PB15 -> SDADC3_AIN7P, SDADC3_AIN8M, RTC_REFCLKIN

PD8 SDADC3_AIN6P




그리고 16비트 ADC를 이용한 테스트 예제로 압력센서 MPX2102A와 온도센서 PT100 예제를 제공하니 테스트 해보면 좋을것 같다.



STM32F373의 ADC는 12bit, 16bit ADC가 모두 외부 레퍼런스 입력이 가능하다.
내부 레퍼런스는 1.2V, 1.8V 설정이 가능한데... 정밀도에대한 언급은 없는것 같다.
(1.2V애대한 언급만 있다. 1.16V< 1.21V< 1.26V, 100 ppm/°C)





STM32F372  SDADC ADC16 테스트 동영상


PB0 -> ADC_IN8, SDADC1_AIN6P 포트에 가변 저항을 연결하여 16bit ADC값을 TFT LCD 화면에 출력하고 그래프로 표시하는 테스트 예제를 진행했다

좀더 정밀한 분석이 필요하겠지만 대략적으로 봐도 값이 아주 안정적으로 들어온다.






STM32F372  SDADC 초기화 코드


void Adc16_Init(void)

{

  SDADC_ConfParamTypeDef confParam;

    

  hsdadc.Instance = SDADC1;

  hsdadc.Init.ReferenceVoltage = SDADC_VREF_VREFINT2;

  hsdadc.Init.IdleLowPowerMode = SDADC_LOWPOWER_NONE;

  hsdadc.Init.FastConversionMode = SDADC_FAST_CONV_DISABLE;

  hsdadc.Init.SlowClockMode = SDADC_SLOW_CLOCK_DISABLE; 

  

  if (HAL_SDADC_Init(&hsdadc) != HAL_OK)

  {

  

  }


  confParam.CommonMode = SDADC_COMMON_MODE_VSSA;

  confParam.Gain = SDADC_GAIN_1;

  confParam.InputMode = SDADC_INPUT_MODE_SE_ZERO_REFERENCE;

  confParam.Offset = 0x00000000;  

  

  if (HAL_SDADC_PrepareChannelConfig(&hsdadc, SDADC_CONF_INDEX_0, &confParam) != HAL_OK)

  {

    /* An error occurs during the preparation of the channel's configuration */

  }


  /* associate POT_SDADC_CHANNEL to the configuration 0 */

  if (HAL_SDADC_AssociateChannelConfig(&hsdadc, POT_SDADC_CHANNEL, SDADC_CONF_INDEX_0) != HAL_OK)

  {

    /* An error occurs during the association of the channel to the prepared configuration */

  }


  /* select POT_SDADC_CHANNEL for injected conversion and continuous mode */

  if (HAL_SDADC_InjectedConfigChannel(&hsdadc, POT_SDADC_CHANNEL, SDADC_CONTINUOUS_CONV_ON) != HAL_OK)

  {

    /* An error occurs during the selection of the channel for the injected conversion */

  }


  /* Select external trigger for injected conversion */

  if (HAL_SDADC_SelectInjectedTrigger(&hsdadc, SDADC_SOFTWARE_TRIGGER) != HAL_OK)

  {

    /* An error occurs during the selection of the trigger */

  }


  /* Start Calibration in polling mode */

  if (HAL_SDADC_CalibrationStart(&hsdadc, SDADC_CALIBRATION_SEQ_1) != HAL_OK)

  {

    /* An error occurs during the starting phase of the calibration */

  }


  /* Pool for the end of calibration */

  if (HAL_SDADC_PollForCalibEvent(&hsdadc, HAL_MAX_DELAY) != HAL_OK)

  {

    /* An error occurs while waiting for the end of the calibration */

  }


  /* Start injected conversion in interrupt mode */

  if (HAL_SDADC_InjectedStart_IT(&hsdadc) != HAL_OK)

  {

    /* An error occurs during the configuration of the injected conversion in interrupt mode */

  }  

}





STM32F372  SDADC 인터럽트 핸들러


void HAL_SDADC_InjectedConvCpltCallback(SDADC_HandleTypeDef *hsdadc)

{

  /* Get conversion value */

  gAdcData = HAL_SDADC_InjectedGetValue(hsdadc, (uint32_t *) &InjChannel);

}



void SDADC1_IRQHandler(void)

{

  HAL_SDADC_IRQHandler(&hsdadc);

}















Posted by nexp

댓글을 달아 주세요