I am using stm32 nucleo-L552ZE-Q. The ADC reading with the DMA doesn't work
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2023-03-06 07:41 AM
I am trying to read an analog signal from a sensor with the ADC of my board. I set the pins correctly I think ( DMA_continuous_requests enable, circular mode, etc. ) and I started the DMA with HAL_ADC_Start_DMA outside the while(1) loop and I put a break point inside the loop to follow the updates in my buffer. BUt when I start debugging and I go inside the loop, my program block ( task constantly runing ) and my buffer doesn't get updated. How can I read the data from the sensor with the ADC ? I also have 2 call back so that I can put breakpoints when the buffer is half full and full. but nothing works I dont understand why.
- Labels:
-
ADC
-
DMA
-
STM32L5 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2023-03-06 04:47 PM
Hello @MSadf.1,
Please provide the rest of the code using the code snippet function.
Regards,
Ryan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2023-03-06 10:35 PM
n
#define ADC_BUFFER_Size 4096
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
UART_HandleTypeDef hlpuart1;
RTC_HandleTypeDef hrtc;
PCD_HandleTypeDef hpcd_USB_FS;
/* USER CODE BEGIN PV */
uint16_t adc_buffer[ADC_BUFFER_Size];
uint16_t value;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_LPUART1_UART_Init(void);
static void MX_RTC_Init(void);
static void MX_UCPD1_Init(void);
static void MX_ADC1_Init(void);
static void MX_USB_PCD_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* 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_DMA_Init();
MX_LPUART1_UART_Init();
MX_RTC_Init();
MX_UCPD1_Init();
MX_ADC1_Init();
MX_USB_PCD_Init();
/* USER CODE BEGIN 2 */
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_BUFFER_Size);
//HAL_ADC_Start(&hadc1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_ADC_Start(&hadc1);
//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
//value = HAL_ADC_GetValue(&hadc1);
/*if (HAL_ADC_PollForConversion(&hadc1, 1000000) == HAL_OK)
{
value = HAL_ADC_GetValue(&hadc1);
}*/
//AL_ADC_Start(&hadc1);
//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
//HAL_Delay(100);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/*.......*/
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{
__NOP();
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
__NOP();
}
I connected my sensor to the A5 pin and activated the ADC on that one. The sensor is a doppler radar sensor. When there is no movement, it send nothing, and when it detect a movement, it sends a sinus signal representing the frequency shift of the movement compared to the frequency of the signal the sensor sends. I have already an evaluation PCB that transforms this sinus into a squared signal. When there is nothing coming from the sensor, the PCB send a high analog signal ( ~3.5 V). So I would like for my board to detect each falling edge and count the time between 2 falling or rising edges.
When I debug and Look at my variables, I get the errors for adc_buffer : -var-create- unable to create variable object and target Not available and my debugger crashes after SystemClock_Config
thank you
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2023-03-07 03:07 PM
Hello @MSadf.1
Step into the SystemClock_Config function to determine exactly where the issue is. If you can, provide your .ioc file. Also, make sure you are using the latest versions of STM32CubeMX/STM32CubeIDE.
Regards,
Ryan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2023-03-08 01:28 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2023-03-08 03:57 PM
Hello @MSadf.1,
I have reviewed your application and here's my input.
- ADC Configuration
- you have 2 channels enabled for ADC1 but scan mode disabled. My understanding of your application is that you only need one channel.
- Your ADC clock prescaler is too low. Your ADC clock is configured as SYSCLK which is 110MHz, while STM32L552 datasheet states it should not be over 80MHz in range 0.
- Even with a slightly higher prescaler, you may find that continuous ADC + DMA operation leads to an overrun error, which will stop conversion. I suggest you finetune ADC speed to suit your application needs and you should probably set Overrun data behavior to Overwritten if your application can afford it.
- Your sampling time is quite low. Depending on your signal it could lead to inaccuracy.
- Code :
- You can remove HAL_ADC_Start(&hadc1); from your while loop since you already started ADC_DMA in continuous mode.
- You should launch ADC calibration beforehand.
- Application wise:
- My understanding is that you need to measure your wave's period. A simpler method would be to use comparators and timers. You can configure a timer in capture mode to have a comparator threshold as input, then the period is the difference between two successive captured values.
Regards,
Ryan