I am starting with series of articles, to try to make simple oscilloscope with STM32F746G Discovery board. I am not sure where this project will lead us. I’d just like to make simple oscilloscope to watch low frequency signals. In this article I just want to make analog-to-digital coverter work.
First we need to complete part 1 and part 2 of STEmWin with Touch Screen on STM32F746G Dicovery so that we can display stuff on LCD to get feedback on how things (don’t) work. Once we have the “Hello world!” done, we can continue with getting to know the A/D converter.
First we will get ADC (A/D converter) to work to get some values we will later display on LCD.
Inside our microcontroller there is a thermal sensor connected to one of the A/D channels. We will use this one, because this way we do not need to add any outside components to our board.
ADC in our controller is quite complicated if we want to know all about it. Below is a simplifed drawing of the A/D system:
We have a Input selection with scan control, sample and hold, ADC, different triggers and Start and Stop control.
Anyone who needs a detailed tutorial on STM32 ADC can read this article, here I will just show how to get ADC working.
If we check the STM32F746xx datasheet, we can see under Section 2.40 on page 43 that thermal sensor is connected to ADC Channel 1, Input 18.
Now we need to add some HAL libraries to our project to be able to use ADC.
Inside our repository C:\Users\%USER%\STM32Cube\Repository\STM32Cube_FW_F7_V1.8.0\Drivers\STM32F7xx_HAL_Driver we need to copy:
- stm32f7xx_hal_adc.h and stm32f7xx_hal_adc_ex.h to Drivers -> STM32F7xx_HAL_Driver -> Inc inside our project.
- stm32f7xx_hal_adc.c and stm32f7xx_hal_adc_ex.c to Drivers -> STM32F7xx_HAL_Driver -> Src inside our project.
Nest we need to change stm32f7xx_hal_conf.h inside Inc folder in root of our project. We need to uncomment the line that says: #define HAL_ADC_MODULE_ENABLED.
Next we need to add ADC initialization.
We will create function inside main.c named MX_ADC1_Init.
First we need to create function prototype:
Then we need to copy following code in between /* USER CODE BEGIN 4 */ and /* USER CODE END 4 */ almost at the end of main.c:
static void MX_ADC1_Init(void)
/* Enable ADC peripheral */
/* Configure the global features of the ADC (Clock, Resolution, Data Alignment and number
of conversion) */
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
/* Configure for the selected ADC regular channel its corresponding rank in the sequence\
and its sample time. */
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
For everything to work we need to call this function. We do it by adding it to user code Init:
/* USER CODE BEGIN Init */
/* USER CODE END Init */
We also need to define a variable:
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
Now all we need to do is start ADC, read temperature and display it on LCD:
/* USER CODE BEGIN WHILE */
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
rawValue = HAL_ADC_GetValue(&hadc1);
temp = ((float)rawValue) / 4095 * 3300;
temp = ((temp - 760.0) / 2.5) + 25;
GUI_DispFloatFix(temp, 4, 1);
HAL_Delay(1000); //Display updates every second
/* USER CODE END 3 */
Now if we compile and program our board, we should see core temperature in the middle of display, it will show degrees celsius as this is what we use here in Europe. Mine shows somewhere aorund 35 to 40 degreees as this is core temperature of processor not the surrounding temperature.
This is for now, see you next time!
6 thoughts on “ADC conversion on STM32F746G-Discovery”
wow,, this is very helpful. I am beginner with st controllers, this is good resource.
Thank you very much for your comment!
This is most excellent indeed.. I too am just starting out.
im wondering though how, instead of getting the raw value from the core temp sensor, you change the code to read from one of the arduino analogue pins on the board?
You can change settings inside function MX_ADC1_Init. There is setting for ADC channel. Change this line: sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
Hope it helps!
so if, for example, y0u wanted the ADC to ‘monitor’ one of the analog pins (A0-A5) you would simply change the ‘ADC_CHANNEL_TEMPSENSOR’ to the corresponding ADC channel. i.e. if you wanted GPIOA-5, you would use ADC channel 5? assuming that you have initialized GPIOA-5 as an analog pin…
have i got this right?
It is not that simple, because A0..A5 are connected to different ports. You need to look at schematics of Nucleo board in user manual UM1724. You also need to read how the ADC is connected inside microcontroller, which registers need to be changed. I would suggest you to get a copy of Mastering STM32 written by Carmine Noviello, link here.
Comments are closed.