Skip to main content
zamlox
Associate II
February 26, 2022
Solved

Cannot get valid values using ADC1 channel 11 on PC1

Hello,

I'm using a Nucleo board (NUCLEO-G070RB) with STM32F103RB MCU and I try to use channel 11 of ADC1 mapped to PC1 to get values from a humidity sensor. I noticed that the values are invalid and it's not because of the sensor. 

I created a sample application and connected PC1 to VCC but the values are about 2000 instead of 4095. When I connect to GND I get same values instead of 0.

Here is the code:

#include "stm32f103xb.h"
 
uint32_t adcValue = 0;
 
int main(void)
{
	/* Enable GPIOC clock */
	RCC->APB2ENR |= (1U<<4);
	/* Configure PC1 to analog input */
	GPIOC->CRL &= ~(1U<<4);	// MODE1[0]: 0
	GPIOC->CRL &= ~(1U<<5);	// MODE1[1]: 0	input mode
	GPIOC->CRL &= ~(1U<<6);	// CNF1[0]: 0
	GPIOC->CRL &= ~(1U<<7);	// CNF1[1]: 0	analog mode
#if 0
	/* Enable GPIOA clock */
	RCC->APB2ENR |= (1U<<2);
	/* Configure PA1 to analog input */
	GPIOA->CRL &= ~(1U<<4);	// MODE1[0]: 0
	GPIOA->CRL &= ~(1U<<5);	// MODE1[1]: 0	input mode
	GPIOA->CRL &= ~(1U<<6);	// CNF1[0]: 0
	GPIOA->CRL &= ~(1U<<7);	// CNF1[1]: 0	analog mode
#endif
	/* Enable ADC1 clock */
	RCC->APB2ENR |= (1U<<9);
	/* Set channel 11 for ADC1 */
	ADC1->SQR3 = 11U;
#if 0
	/* Set channel 1 for ADC1 */
	ADC1->SQR3 = 1U;
#endif
	/* Set number of conversions */
	ADC1->SQR1 = 0;	// L[3:0]: 0000 -> 1 conversion
	/* Enable ADC1 */
	ADC1->CR2 |= (1U<<0);	// set ADON to 1
	/* Enable continuous mode */
	ADC1->CR2 |= (1U<<1);	// set CONT to 1
 
	/* Set start software flag */
	ADC1->CR2 |= (1U<<22);	// set SWSTART to 1
	/* Set ADON again to start conversion */
	ADC1->CR2 |= (1U<<0);	// set ADON to 1
 
	while(1)
	{
		/* Check EOC bit for end of conversion */
		while(!(ADC1->SR & 2U));
		/* Read conversion value */
		adcValue = ADC1->DR;
	}
}

When I use PA1 with channel 1 then values are correct (4095 or 0).

What can be the issue ?

Thanks.

This topic has been closed for replies.
TDK
TDKBest answer
February 26, 2022

Regardless, you could set PC1 as an output and see that you can measure it with a multimeter to verify correct hardware pinout. Or as an input and verify that IDR reads correctly.

You should also verify the register settings are correctly set by examining them in a debugger. Technically you need a delay of a few cycles between enabling a clock and using it. This may be preventing the "ADC1->SQR3 = 11U" line from happening.

https://github.com/STMicroelectronics/STM32CubeF1/blob/f5aaa9b45492d70585ade1dac4d1e33d5531c171/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h#L535

"If you feel a post has answered your question, please click ""Accept as Solution""."

5 replies

TDK
February 26, 2022

> I'm using a Nucleo board (NUCLEO-G070RB) with STM32F103RB MCU 

How, exactly? They don't have compatible pinouts.

"If you feel a post has answered your question, please click ""Accept as Solution""."
zamlox
zamloxAuthor
Associate II
February 26, 2022

I'm using following board user manual: STM32 Nucleo-64 boards (MB1360) - User manual and in this document board name is referenced as I mentioned above. I checked my board and actually is NUCLEO-F103RB.

Configuration of connectors and pins are similar with my board.

TDK
TDKBest answer
February 26, 2022

Regardless, you could set PC1 as an output and see that you can measure it with a multimeter to verify correct hardware pinout. Or as an input and verify that IDR reads correctly.

You should also verify the register settings are correctly set by examining them in a debugger. Technically you need a delay of a few cycles between enabling a clock and using it. This may be preventing the "ADC1->SQR3 = 11U" line from happening.

https://github.com/STMicroelectronics/STM32CubeF1/blob/f5aaa9b45492d70585ade1dac4d1e33d5531c171/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h#L535

"If you feel a post has answered your question, please click ""Accept as Solution""."
zamlox
zamloxAuthor
Associate II
February 26, 2022

Thank you for suggestions.

I configured PC1 in output mode, toggling ODR register each second and I connected a logic analyzer to the pin. Signal is flat, not as expected.

I used same code but configured for PA1 and the output is as expected.

I don't understand why same code works for PA1 (as output and input from ADC1) but not for PC1.

I verified register settings when testing PC1 in debug mode and all registers are set correctly.

I put a delay of 1ms after setting the channel but still not working.