cancel
Showing results for 
Search instead for 
Did you mean: 

I'm having issues getting ADC to work on my custom board using STM32 Cube IDE. Please help.

DerekS
Associate II

Hello,

I'm having trouble getting ADC to work, and I feel like I've tried everything to get any kind of result. I'm starting to think that this individual chip is having issues but I want to rule out any user error before I replace it. It seems to never store any kind of data and always just returns 0 as well as an error code 1. I've tried all ADC modes at this point and it never provides any kind of data.

Here are the facts;

I'm using a STM32H743ZIT6 on a custom board and im programming with STM32CubeIDE using a STLINK3 and SWD.

My board uses a 48 Mhz crystal that is configured inside the IDE and seems to work fine since I have other functions of the processor working.

I have a display connected to SPI that is working fine.

I have a voltage divider connected to PA1 that provides 2V up to 3.3 V ( this is verified) and I'm trying to measure it, I have it enabled as an ADC input with DMA.

When I do an adc error call, It gives me error 1, meaning there is an internal error.

Register ADEN is enabled, However, ADRDY will not and cannot be set. Every time I try to set it, it just goes back.

The ADC clock mux is greyed out when I configure the chip in stm32cubeide. When I highlight it, it just tells me to enable ADC, which i have. I've tried turning on multiple adcs but it remains greyed out, not sure if that's normal or not.

Attached is my entire code library, It's mostly cube generated code with the addition of the display code. Please let me know if you need anymore information and any assistance is appreciated.

Here is a snippet of my main.c code for quick reference.

Thank you,

#include "main.h"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <st7789.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h> //for va_list var arg functions
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
 
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
 ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
 
I2C_HandleTypeDef hi2c1;
 
SPI_HandleTypeDef hspi1;
SPI_HandleTypeDef hspi2;
DMA_HandleTypeDef hdma_spi1_tx;
DMA_HandleTypeDef hdma_spi2_tx;
DMA_HandleTypeDef hdma_spi2_rx;
 
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
 
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MPU_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_SPI1_Init(void);
static void MX_SPI2_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_DMA_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_ADC1_Init(void);
/* USER CODE BEGIN PFP */
void myprintf(const char *fmt, ...);
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint32_t value;
 
 
 
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_SPI1_Init();
  MX_SPI2_Init();
  MX_USART1_UART_Init();
  MX_DMA_Init();
  MX_USART2_UART_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */
 
  ST7789_Init();
  ST7789_Fill_Color(WHITE);
  HAL_ADC_Start_DMA(&hadc1,value,3);
 
 
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
 
 
 
  char buffer[100];
  char buffer2[100];
  uint32_t status;
 
      /* USER CODE BEGIN WHILE */
      while (1)
      {
 
 
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
 
    	  status = HAL_ADC_GetError(&hadc1);
    	  sprintf(buffer,"Error %X \r\n", status);
    	  ST7789_WriteString(10, 10, buffer, Font_16x26, GBLUE, RED);
    	  HAL_UART_Transmit(&huart1, buffer, strlen(buffer), HAL_MAX_DELAY);
    	  sprintf(buffer2,"Current %X \r\n", value);
    	  ST7789_WriteString(10, 60, buffer2, Font_16x26, GBLUE, RED);
    	  HAL_UART_Transmit(&huart1, buffer2, strlen(buffer2), HAL_MAX_DELAY);
 
    	  HAL_Delay(1000);
 
    	  ST7789_Fill_Color(WHITE);
      }
  /* USER CODE END 3 */
}

2 REPLIES 2
TDK
Guru

> uint32_t value;

> HAL_ADC_Start_DMA(&hadc1,value,3);

Should be getting a error when you compile this. You're passing an (uninitialized) integer instead of a pointer.

Unclear why you're storing 3 ADC values into a uint32_t. Probably going to be an overrun, if it were to work at all.

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

Thanks for your reply! I dived a bit more into how to properly store DMA values and ended up using this source, https://www.digikey.com/en/maker/projects/getting-started-with-stm32-working-with-adc-and-dma/f5009db3a3ed4370acaf545a3370c30c

I used their method and came up to this conclusion

0693W00000Kd2qcQAB.pngThe error flag for ADC is still at 1 and the ad_buf just sits there with 0s forever never triggering a half filled callback. Any other suggestions would be greatly appreciated.

Here is the new relevant bit of code.

#include "main.h"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <st7789.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h> //for va_list var arg functions
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
 
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define ADC_BUF_LEN 4096
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
 ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
 
I2C_HandleTypeDef hi2c1;
 
SPI_HandleTypeDef hspi1;
SPI_HandleTypeDef hspi2;
DMA_HandleTypeDef hdma_spi1_tx;
DMA_HandleTypeDef hdma_spi2_tx;
DMA_HandleTypeDef hdma_spi2_rx;
 
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
 
/* USER CODE BEGIN PV */
uint16_t adc_buf[ADC_BUF_LEN];
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MPU_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_SPI1_Init(void);
static void MX_SPI2_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_DMA_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_ADC1_Init(void);
/* USER CODE BEGIN PFP */
void myprintf(const char *fmt, ...);
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint32_t value;
 
 
 
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_SPI1_Init();
  MX_SPI2_Init();
  MX_USART1_UART_Init();
  MX_DMA_Init();
  MX_USART2_UART_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */
 
  ST7789_Init();
  ST7789_Fill_Color(WHITE);
  HAL_ADC_Start_DMA(&hadc1,(uint32_t*)adc_buf, ADC_BUF_LEN);
 
static void MX_ADC1_Init(void)
{
 
  /* USER CODE BEGIN ADC1_Init 0 */
 
  /* USER CODE END ADC1_Init 0 */
 
  ADC_MultiModeTypeDef multimode = {0};
  ADC_ChannelConfTypeDef sConfig = {0};
 
  /* USER CODE BEGIN ADC1_Init 1 */
 
  /* USER CODE END ADC1_Init 1 */
 
  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure the ADC multi-mode
  */
  multimode.Mode = ADC_MODE_INDEPENDENT;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_17;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  sConfig.OffsetSignedSaturation = DISABLE;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */
 
  /* USER CODE END ADC1_Init 2 */
 
}
static void MX_DMA_Init(void)
{
 
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA1_Stream3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);
 
}