Skip to main content
Marius CO
Associate II
November 29, 2018
Question

F303RE Nucleo analogue reading inconsistency

  • November 29, 2018
  • 0 replies
  • 585 views

Pretty much the code is generated by Cube.

I am reading 11 adc's some on adc1 and some on adc2. If I put the pins to 0 gnd i have consistent reading 0. All pins to 3.3v I have

But reading in a loop

pa7,pa7,pa7,pa7,pa7,pa7

pa7 4095

pa7 4095

pa7 4031

pa7 4031

pa7 4032

the value varied from 4032 to 4095

Now in a 3.3v/2 divisor varies from 1965 to 1929

pa7 1929

pa7 1929

pa7 1930

pa7 1950

pa7 1965

pa7 1964

pa7 1965

then all pins to 0

pa7 0 for gnd

pa1 0

pa0 0

pa5 0

pa6 0

pc0 0

pc1 0

pc2 0

pc3 0

3.3v all pins reads different values

pa7 4028 for 3.3v

pa1 4020

pa0 4017

pa5 4032

pa6 4026

pc0 4020

pc1 4013

pc2 4018

pc3 4017

I have a termistor and calc formula gives temp errors in orders of 10 degress

My adc init is for both adc's:

static void myInit_Adc(ADC_HandleTypeDef* hadc)
{
 hadc->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
 hadc->Init.Resolution = ADC_RESOLUTION_12B;
 hadc->Init.DataAlign = ADC_DATAALIGN_RIGHT;
 hadc->Init.ScanConvMode = ADC_SCAN_DISABLE;
 hadc->Init.EOCSelection = ADC_EOC_SINGLE_CONV;
 hadc->Init.LowPowerAutoWait = DISABLE;
 //hadc->Init.LowPowerAutoPowerOff = DISABLE;
 hadc->Init.ContinuousConvMode = DISABLE;
 hadc->Init.DiscontinuousConvMode = DISABLE;
 hadc->Init.ExternalTrigConv = ADC_SOFTWARE_START;
 hadc->Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
 hadc->Init.DMAContinuousRequests = DISABLE;
 hadc->Init.Overrun = ADC_OVR_DATA_PRESERVED;
}

My channel config is:

tatic void myInitChannels(ADC_HandleTypeDef* hadc,
 ADC_ChannelConfTypeDef* sConfig)
{
 uint32_t channels[]={ADC_CHANNEL_1,
 ADC_CHANNEL_2,
 ADC_CHANNEL_3,
 ADC_CHANNEL_4,
 ADC_CHANNEL_5,
 ADC_CHANNEL_6,
 ADC_CHANNEL_7,
 ADC_CHANNEL_8,
 ADC_CHANNEL_9,
 };
 
 uint32_t ranks[]= {ADC_REGULAR_RANK_1,
 ADC_REGULAR_RANK_1,
 ADC_REGULAR_RANK_1,
 ADC_REGULAR_RANK_1,
 ADC_REGULAR_RANK_1,
 ADC_REGULAR_RANK_1,
 ADC_REGULAR_RANK_1,
 ADC_REGULAR_RANK_1,
 ADC_REGULAR_RANK_1,
 };
 for(int c=0; c<sizeof(channels)/sizeof(channels[0]);c++)
 {
 sConfig->Channel = channels[c];
 sConfig->Rank = ranks[c];
 sConfig->SingleDiff = ADC_SINGLE_ENDED;
 sConfig->SamplingTime = ADC_SAMPLETIME_61CYCLES_5;//ADC_SAMPLETIME_1CYCLE_5;
 sConfig->OffsetNumber = ADC_OFFSET_NONE;
 sConfig->Offset = 0;
 if (HAL_ADC_ConfigChannel(hadc, sConfig) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 }
 
}

My select channel function is

void select_adc(uint32_t channel, ADC_HandleTypeDef* ahd, bool sel)
{
 ADC_ChannelConfTypeDef sConfig;
 if(sel)
 {
 sConfig.Channel = channel;//ADC_CHANNEL_1;
 sConfig.Rank = ADC_REGULAR_RANK_1;
 sConfig.SingleDiff = ADC_SINGLE_ENDED;
 sConfig.SamplingTime = ADC_SAMPLETIME_61CYCLES_5;
 sConfig.OffsetNumber = ADC_OFFSET_NONE;
 sConfig.Offset = 0;
 if (HAL_ADC_ConfigChannel(ahd, &sConfig) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 }
 else
 {
 sConfig.Rank = ADC_RANK_NONE;
 if (HAL_ADC_ConfigChannel(ahd, &sConfig) != HAL_OK)
 {
 _Error_Handler(__FILE__, __LINE__);
 }
 }
}

My analogue read is:

static void _anal_read(struct AnalogPin* pin)
{
 int32_t values[4];
 bool err=false;
 
 if(pin->fromIT)
 {
 if(pin->calcFoo)
 {
 (*pin->calcFoo)(pin);
 }
 return;
 }
 select_adc(pin->channel,pin->adc,true); //channel
 for(int i=0;i<4;i++)
 {
 
 if(HAL_OK==HAL_ADC_Start(pin->adc))
 {
 if(HAL_ADC_PollForConversion(pin->adc, 1000) == HAL_OK)
 {
 values[i] = HAL_ADC_GetValue(pin->adc);
 }
 else
 {
 if(ERRREPO)
 {
 printf("# ? Error adc pool\r\n");
 err=true;
 break;
 }
 }
 while(HAL_OK!=HAL_ADC_Stop(pin->adc))
 {
 ;
 }
 HAL_Delay(8);
 }
 }
 if(!err)
 {
 select_adc(pin->channel,pin->adc,false); //channel
 pin->curval = (values[1]+values[2]+values[3])/3;
 if(pin->calcFoo)
 {
 (*pin->calcFoo)(pin);
 }
 return;
 }
 
 pin->curval = -1;
 if(ERRREPO)
 printf("# ? ADC failed this time\r\n");
}

Thank you

This topic has been closed for replies.