2023-06-12 08:18 PM - edited 2023-11-20 03:24 AM
I have an STM32G474RE, I have not used any HAL or LL libraries, I have only programmed using the registers, my issue is that I am only getting 0 on the output of the ADC, I read through the reference manual and still couldn't solve the problem. I have used ADC channel 1 and PA0 pin since that is what was written in the manual. The output from the UART is shown below.
Thank you in advance for giving me your attention !!
#include "stm32g4xx.h"
#include <stdio.h>
void adc_calib(void);
void adc_init(void);
void adc_conversion(void);
uint32_t adc_read(void);
void adc_init(void)
{
//Enable Debugging LED
RCC->AHB2ENR |=(1U<<0);
GPIOA->MODER |=(1U<<10);
GPIOA->MODER &=~(1U<<11);
//Set PA0 to analog mode
GPIOA->MODER |=(1U<<0)|(1U<<1);
//Enable clock access to ADC12
RCC->AHB2ENR |=(1U<<13);
//Setting CK MODE to adc_hclk/4 (Synchronous clock mode)
ADC12_COMMON ->CCR |=(1U<<16);
ADC12_COMMON ->CCR |=(1U<<17);
//Setting PRE Scaler to 0100: input ADC clock divided by 8
ADC12_COMMON ->CCR &=~(1U<<18);
ADC12_COMMON ->CCR &=~(1U<<19);
ADC12_COMMON ->CCR |= (1U<<20);
ADC12_COMMON ->CCR &=~(1U<<21);
//Disabling ADC from DEEP PWD
ADC1->CR &=~(1U<<29);
//Enabling ADVERGEN
ADC1->CR |=(1U<<28);
//Waiting
for(int i=0;i<1000000;i++)
{
}
}
void adc_calib(void)
{
//Disabling ADEN
ADC1->CR &=~ (1U<<0);
//Disabling ADCALIF
ADC1->CR &=~ (1U<<30);
//Enabling ADCAL
ADC1->CR |= (1U<<31);
//Waiting for ADCAL to finish calibrating
while((ADC1->CR & (1U<<31))!=0)
{
}
//Enabling ADEN
ADC1->CR |=(1U<<0);
}
void adc_conversion(void)
{
//Disabling ADSTART
ADC1->CR &=~(1U<<2);
//Setting length to (0000: 1 conversion)
ADC1->SQR1 &=~(1U<<0);
ADC1->SQR1 &=~(1U<<1);
ADC1->SQR1 &=~(1U<<2);
ADC1->SQR1 &=~(1U<<3);
//Setting priority 1 to Channel 1 (0001)
ADC1->SQR1 |= (1U<<6);
//Setting Sampling time to 12.5 ADC clock cycles (010)
ADC1->SMPR1&=~(1U<<6);
ADC1->SMPR1|= (1U<<7);
ADC1->SMPR1&=~(1U<<8);
}
uint32_t adc_read(void)
{
//ADC is set to continuous conversion mode
ADC1->CFGR |= (1U<<13);
//Enabling ADSTART
ADC1->CR |=(1U<<2);
//Wait for ADC to start
while(!(ADC1->CR & (1U<<2)))
{
}
//Wait for EOC flag to set
while(!(ADC1->ISR & (1U<<2)))
{
}
//Turn on debugging LED to indicate the program is ready to send data
GPIOA->ODR ^=(1U<<5);
//Read data from DR
return(ADC1->DR);
}
2023-06-12 09:45 PM
Not verse in STM32G4, however, if you do need to de-clunk the system, use a debug proble such as ST Link, run the code, stop the code, open the watch window and look at the SFR registers of the GPIO and ADC to find out. You may actually manually change some registers then continue the code.... faster than rebuild every itteration.
2023-06-12 10:15 PM
Although I think it's great that you are writing registers directly, I think it makes sense to use bit defines to make the code more readable.
Not only for us, but also for yourself. Or will you remember in 6 months what bit y of register x means?
2023-06-12 10:22 PM
Sorry im new to this, I have added comments to each line if that helps, will work on defines and update the code once i complete it.
2023-06-12 10:27 PM
Sorry im new to this, I have added comments to each line if that helps, will work on "defines" and update the code once i complete it.
2023-06-12 10:33 PM
I used the stk link debugger, however since there is some issue with my live expressions, I use the UART to display values
2023-06-13 01:02 AM
I would try to write the entire code using HAL FW and verify its functionality. Then with the help of the debugger find out where, what and how to set.
2023-06-13 01:24 AM
I wrote the code in HAL and it worked as intended, I need help in figuring out what I am doing wrong.
2023-06-13 02:55 AM
Run the code in debug mode and watch step by step how the GPIO is set, how the ADC is turned on, how the channel is configured and compare it with your own code. You will see where the difference is and it will be easier to understand the correct sequence of individual steps.