2023-01-16 08:22 AM
Hello, I want to read an analog data and I didnt figure out how to use low layer libraries properly?
I am using stm32wb55rgv6 nucleo board
Code :
#include <stm32wbxx_ll_bus.h>
#include <stm32wbxx_ll_rcc.h>
#include <stm32wbxx_ll_gpio.h>
#include <stm32wbxx_ll_tim.h>
#include <stm32wbxx_ll_utils.h>
#include <stm32wbxx_ll_adc.h>
#include <stdio.h>
void SystemClock_Config(void);
void ADC_Clock_Config(void);
void adc1_init(void);
/*
* PC0 : ADC1_IN1 pin of the stm32
*
* */
uint32_t volatile sensor_value = 0;
int main(void)
{
SystemClock_Config();
ADC_Clock_Config();
adc1_init();
while(1)
{
/*1) Start adc conversion */
/*
* On this STM32 series, this function is relevant for both internal trigger (SW start)
* and external trigger.
* */
LL_ADC_REG_StartConversion(ADC1);
/*2) wait for conversion to be complete
* End of Sequence
* */
while(!(LL_ADC_IsActiveFlag_EOC(ADC1)))
{
}
/*3) read converted value */
sensor_value = LL_ADC_REG_ReadConversionData32(ADC1);
}
}
/* System Clock Configurations
* SYSCLK : 32 MHz
* HCLK : 16 MHz
* APB1 : 16 MHz
* APB2 : 16 MHz
* */
void SystemClock_Config(void)
{
/* Setting Flash Latency and wait for set
* We set latency cause flash has to be delayed due to read write operation in it
* */
LL_FLASH_SetLatency(LL_FLASH_LATENCY_1);
while(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_1)
{
}
/* Enable the MSI and waiting for enable*/
LL_RCC_MSI_Enable();
while(LL_RCC_MSI_IsReady() != 1)
{
}
/* Setting MSI range MSI works between 100kHz to 48 MHZ
* LL_RCC_MSIRANGE_10 : 32 MHz
* */
LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_10);
/* Configs on CPU1 prescaler
* We set MSI TO 32 MHz BY division 1 we get 32 MHZ for CPU1
* */
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
/* Set CPU2 prescaler which is for BLE CPU2 runs at 32 MHZ
* BLE operations requires at least 16 MHZ on HCLK2
* */
LL_C2_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
/* Setting System Clock Sourse as MSI which is configured as 32MHz
* and waiting for enabled
* */
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI);
while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI)
{
}
/* Set AHB SHARED prescaler*/
LL_RCC_SetAHB4Prescaler(LL_RCC_SYSCLK_DIV_1);
/* Set APB1 prescaler
* APB1 bus clock frequency is CPU1 frequency which is 32 MHz
* we divide by CPU freq by 1
* */
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
/* Set APB2 prescaler
* APB2 bus clock frequency is CPU1 frequency which is 32 MHz
* we divide by CPU freq by 1
* */
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
/* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function)
* It sets the HCLK frequency
* */
LL_SetSystemCoreClock(32000000);
}
void ADC_Clock_Config(void)
{
LL_RCC_PLLSAI1_ConfigDomain_ADC(LL_RCC_PLLSOURCE_MSI, LL_RCC_PLLM_DIV_2, 8, LL_RCC_PLLSAI1R_DIV_2);
LL_RCC_PLLSAI1_Enable();
LL_RCC_PLLSAI1_EnableDomain_ADC();
/* Wait till PLLSAI1 is ready */
while(LL_RCC_PLLSAI1_IsReady() != 1)
{
}
}
void adc1_init(void)
{
/* Setting ADC clock source as PLLSAI*/
LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLLSAI1);
/* 1-) Enable clock access to adc module*/
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC);
/* 2-) Enable clock acces to adc channel port*/
/* Enable peripheral clock */
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
/* 3-) Set adc channel pin mode to analog */
/* ADC_IN1 PC0*/
LL_GPIO_SetPinMode(GPIOC, LL_GPIO_PIN_0, LL_GPIO_MODE_ANALOG);
/* 4-) Set adc trigger */
/* We want to trigger by software we can use EXTI_TIM or EXTI_LINE or */
LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_SOFTWARE);
/* 5-) Set sampling sequence */
/* For now we deal with one channel so our rank should be 1 later will see details of it*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1,LL_ADC_CHANNEL_1);
/* 6-) Set Sequence length */
LL_ADC_REG_SetSequencerLength(ADC1, LL_ADC_REG_SEQ_SCAN_DISABLE);
/* If we have multiple channels we use LL_ADC_REG_SEQ_SCAN_2RANKS or more ranks depending on how many channels we have*/
/* 7-) Enable adc*/
LL_ADC_Enable(ADC1);
}
When I debugging the code is stuck at while(!LL_ADC_IsActiveFlag_EOC(ADC1))
What is the problem and how can I read analog data properly:pensive_face: ?
Thanks for helps
Solved! Go to Solution.
2023-01-16 12:18 PM
Also, after ADC Enable, a delay may be needed, for example [STM32L4 devices]:
On this STM32 serie, after ADC enable, a delay for
* ADC internal analog stabilization is required before performing a ADC conversion start.
* Refer to device datasheet, parameter tSTAB.
* @note On this STM32 serie, flag LL_ADC_FLAG_ADRDY is raised when the ADC is enabled and when conversion clock is active.
* (not only core clock: this ADC has a dual clock domain)
2023-01-16 12:09 PM
I am not familiar with stm32wb55, but other STM32 ADCs require configuration of things like resolution (e.g., 8-bit, 10-bit, etc.), data alignment, scan conversion mode, EOC Selection, sampling time, number of conversions, etc.
2023-01-16 12:18 PM
Also, after ADC Enable, a delay may be needed, for example [STM32L4 devices]:
On this STM32 serie, after ADC enable, a delay for
* ADC internal analog stabilization is required before performing a ADC conversion start.
* Refer to device datasheet, parameter tSTAB.
* @note On this STM32 serie, flag LL_ADC_FLAG_ADRDY is raised when the ADC is enabled and when conversion clock is active.
* (not only core clock: this ADC has a dual clock domain)
2023-01-18 09:21 PM
Thank you so much . The problem is about tSTAB parameter. Your comment helped me a lot :smiling_face_with_heart_eyes: