cancel
Showing results for 
Search instead for 
Did you mean: 

How do I read a voltage using the A/D converter in the most basic way?

arnold_w
Senior
Posted on June 21, 2016 at 15:20

 

 

The original post was too long to process during our migration. Please click on the attachment to read the original post.
2 REPLIES 2
arnold_w
Senior
Posted on June 21, 2016 at 15:35

I just found out that the ''working code'' is not working so great. I seem to always read channel 9 (pin PB1) properly, but channel 2 (pin PA2) sometimes return values around 26-28 and sometime it returns values around 2888-2890, but the correct value is around 550. Does anybody know what's wrong?

arnold_w
Senior
Posted on June 21, 2016 at 16:41

I have reduced the code a bit, but it still behaves the same.

static
Bool_t HAL_ADC_ConfigChannel_(uint32_t channel)
{
if
(ADC_CHANNEL_9 < channel)
{
DEBUG_CODE( UART2_SW_TransmitNullTerminatedString((uint8_t*) 
''

Only channels 1-9 are implemented!''
); )
return
FALSE;
}
ADC1->SMPR2 &= ~ADC_SMPR2(ADC_SMPR2_SMP0, channel); 
// Clear the old sample time
ADC1->SMPR2 |= ADC_SMPR2(ADC_SAMPLETIME_3CYCLES, channel); 
// Set the new sample time
// Rank 1 to 6
ADC1->SQR3 &= ~ADC_SQR3_RK(ADC_SQR3_SQ1, 1); 
// Clear the old SQx bits for the selected rank
ADC1->SQR3 |= ADC_SQR3_RK(channel, 1); 
// Set the SQx bits for the selected rank
return
TRUE;
}
static
void
HAL_ADC_Start_(
void
)
{
// Enable the ADC peripheral
// Check if ADC peripheral is disabled in order to enable it and wait during
// Tstab time the ADC's stabilization
if
((ADC1->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
{
ADC1->CR2 |= ADC_CR2_ADON; 
// Enable the Peripheral
delayMicroseconds(ADC_STAB_DELAY_US);
}
if
(HAL_IS_BIT_SET(ADC1->CR2, ADC_CR2_ADON))
{ 
// Start conversion if ADC is effectively enabled
// Clear regular group conversion flag and overrun flag
ADC1->SR = ~ADC_FLAG_EOC; 
// Clear end of conversion flag
// If instance of handle correspond to ADC1 and no external
// trigger present enable software conversion of regular channels
if
(((ADC1->CR2 & ADC_CR2_EXTEN) == RESET))
{
// Enable the selected ADC software conversion for regular group
ADC1->CR2 |= (uint32_t)ADC_CR2_SWSTART;
}
}
}
static
Bool_t HAL_ADC_PollForConversion_(uint32_t Timeout)
{
uint32_t numOneMillisecondIterations = Timeout;
while
((0 < numOneMillisecondIterations--) && ((ADC1->SR & ADC_FLAG_EOC) == 0))
{
delayMicroseconds(1000);
}
if
(numOneMillisecondIterations == 0)
{
DEBUG_CODE( UART2_SW_TransmitNullTerminatedString((uint8_t*) 
''

Timeout when waiting for conversion completion!''
); )
return
FALSE;
}
ADC1->SR = ~(ADC_FLAG_STRT | ADC_FLAG_EOC); 
// Clear end of conversion flag and channel start flag
return
TRUE;
}
uint16_t readADC(uint32_t channel)
{
__HAL_RCC_ADC1_CLK_ENABLE();
ADC->CCR &= ~(ADC_CCR_ADCPRE); 
// Set ADC parameters
ADC->CCR |= ADC_CLOCKPRESCALER_PCLK_DIV2; 
// Set the ADC clock prescaler
ADC1->CR1 &= ~(ADC_CR1_SCAN); 
// Set ADC scan mode
ADC1->CR1 |= ADC_CR1_SCANCONV(DISABLE); 
// Set ADC scan mode
ADC1->CR1 &= ~(ADC_CR1_RES); 
// Set ADC resolution
ADC1->CR1 |= ADC_RESOLUTION_12B; 
// Set ADC resolution
ADC1->CR2 &= ~(ADC_CR2_ALIGN); 
// Set ADC data alignment
ADC1->CR2 |= ADC_DATAALIGN_RIGHT; 
// Set ADC data alignment
ADC1->CR2 &= ~(ADC_CR2_EXTSEL); 
// Reset the external trigger
ADC1->CR2 &= ~(ADC_CR2_EXTEN); 
// Reset the external trigger
ADC1->CR2 &= ~(ADC_CR2_CONT); 
// Disable ADC continuous conversion mode
ADC1->CR2 |= ADC_CR2_CONTINUOUS(DISABLE); 
// Disable ADC continuous conversion mode
ADC1->CR1 &= ~(ADC_CR1_DISCEN); 
// Disable the selected ADC regular discontinuous mode
ADC1->SQR1 &= ~(ADC_SQR1_L); 
// Set ADC number of conversion
ADC1->SQR1 |= ADC_SQR1(1); 
// Set ADC number of conversion
ADC1->CR2 &= ~(ADC_CR2_DDS); 
// Disable ADC DMA continuous request
ADC1->CR2 |= ADC_CR2_DMAContReq(DISABLE); 
// Disable ADC DMA continuous request
ADC1->CR2 &= ~(ADC_CR2_EOCS); 
// Disable ADC end of conversion selection
ADC1->CR2 |= ADC_CR2_EOCSelection(DISABLE); 
// Disable ADC end of conversion selection
if
(!HAL_ADC_ConfigChannel_(channel))
{
return
0xFFFF;
}
HAL_ADC_Start_();
if
(!HAL_ADC_PollForConversion_(10))
{
return
0xFFFF;
}
return
ADC1->DR;
}