Skocz do zawartości

[Stm32f3] Problem z pomiarem napięcia za pomocą adc


quast

Pomocna odpowiedź

Cześć,

od jakiegoś czasu zajmuję się stmami i nadeszła pora, aby skorzystać z adc. Na płytkę STM32F3 Discovery wrzuciłem lekko zmodyfikowany program przykładowy od ST realizujący pomiar ciągły na jednym kanale. Na zadeklarowany pin (PC1) podaje napięcie 2,5V, jednak podczas debugowania przy ADC_GetConversionValue(ADC1) otrzymuję wartość 0x08000260, która przy przypisaniu do zmiennej typu uint16_t się zeruje (ze względu na przepełnienie). Mimo usilnych prób nie doszedłem do źródła błędu. Bardzo proszę o jakieś wskazówki, bo siedzę nad tym dwa dni i nie widzę błędu.

main.c

/**
 ******************************************************************************
 * @file    ADC/ADC_BasicExample/main.c 
 * @author  MCD Application Team
 * @version V1.1.1
 * @date    31-October-2014
 * @brief   Main program body
 ******************************************************************************
*/

#include "main.h"

__IO uint16_t  ADC1ConvertedValue = 0, ADC1ConvertedVoltage = 0;
__IO uint32_t TimingDelay = 0, calibration_value = 0;
ADC_InitTypeDef       ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
GPIO_InitTypeDef    GPIO_InitStructure;

int main(void)
{

 /* Configure the ADC clock */
 RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div6);

 /* Enable ADC1 clock */
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);

 /* Setup SysTick Timer for 1 micro sec interrupts  */
 if (SysTick_Config(SystemCoreClock / 1000000))
 { 
   /* Capture error */ 
   while (1)
   {}
 }

 /* ADC Channel configuration */
  /* GPIOC Periph clock enable */
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

 /* Configure ADC Channel7 as analog input */
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
 GPIO_Init(GPIOC, &GPIO_InitStructure);

 ADC_StructInit(&ADC_InitStructure);

 /* Calibration procedure */ 
 ADC_VoltageRegulatorCmd(ADC1, ENABLE);

 /* Insert delay equal to 10 micro s */
 Delay(10);

 ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
 ADC_StartCalibration(ADC1);

 while(ADC_GetCalibrationStatus(ADC1) != RESET );
 calibration_value = ADC_GetCalibrationValue(ADC1);

 ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;                                                                    
 ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;                    
 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;             
 ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;                  
 ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;          

 ADC_CommonInit(ADC1, &ADC_CommonInitStructure);

 ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Enable;
 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; 
 ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;         
 ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
 ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;   
 ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;  
 ADC_InitStructure.ADC_NbrOfRegChannel = 1;
 ADC_Init(ADC1, &ADC_InitStructure);

 /* ADC1 regular channel7 configuration */ 
 ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_7Cycles5);

 /* Enable ADC1 */
 ADC_Cmd(ADC1, ENABLE);

 /* wait for ADRDY */
 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY));

 /* Start ADC1 Software Conversion */ 
 ADC_StartConversion(ADC1);   

 /* Infinite loop */
 while (1)
 {
   /* Test EOC flag */
   while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);

   /* Get ADC1 converted data */
   ADC1ConvertedValue =ADC_GetConversionValue(ADC1);

   /* Compute the voltage */
   ADC1ConvertedVoltage = (ADC1ConvertedValue *3300)/0xFFF;

   Display();
 }
}

void Delay(__IO uint32_t nTime)
{ 
 TimingDelay = nTime;

 while(TimingDelay != 0);
}

void Display(void)
{
 v=(ADC1ConvertedVoltage)/1000;
 mv = (ADC1ConvertedVoltage%1000)/100;
}

#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

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.