I am trying to read accelerometer data over i2c. The i2c address of the accelerometer is 0x19 for reading and 0x18 for writing. To check for correct communication with the accelerometer, I should read register 0x00 and it must return 0x12 as the result. But I am not able to get acknowledgement from the accelerometer. I am using the HAL libraries and code generated using CubeMX. Here is the code:
#include "main.h"
#include "stm32l0xx_hal.h"
I2C_HandleTypeDef hi2c1;
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
uint8_t data[2];
uint8_t result;
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
while (1)
{
// HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
HAL_I2C_Mem_Read_DMA(&hi2c1, 0x19, 0x00, 1, &result, 1);
HAL_Delay(100);
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
/**Configure the main internal regulator output voltage */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/**Initializes the CPU, AHB and APB busses clocks */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/**Initializes the CPU, AHB and APB busses clocks */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/**Configure the Systick interrupt time */
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick */
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* I2C1 init function */
static void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x00000708;
hi2c1.Init.OwnAddress1 = 0x18;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/**Configure Analogue filter */
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
}
2 external pull up resistors of 4,7kOhms are used.
mc pins:
https://developer.mbed.org/platforms/ST-Nucleo-L011K4/
pins D4 and D5 to SDA and SCL respectively. GND and 3.3V are connected to accelerometers respective power connections.
The SDA pin of board is PB7 and SCL pin is PB6. However, you don't initialize these pins clock. You should enable port B clock in MX_GPIO_Init function.
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
}
You should set OwnAddress1 to 0 in MX_I2C1_Init function.
hi2c1.Init.OwnAddress1 = 0;
Also read address should be 0x18 in HAL_I2C_Mem_Read_DMA or HAL_I2C_Mem_Read function. I am not sure Timing is correct. Most of I2C devices clock speed is between 100-400Khz. What is your I2C device clock speed? You can try at 100 or 400Khz.
hi2c1.Init.Timing = 400000;
Related
I have stm32L053R8 nucleo64 board. I'm trying to get adc measure in low power run mode. It's not working correctly in Lprun mode but when I try in run mode it's working. In Lprun mode I only get 2 values. Half of the resolution and full of the resolution(12bit -> 2047 & 4095). Can you guys help me to figure out where am I doing wrong?
I tried to figure out why this happens and configured LFMEN, VREFEN, ULP bits but didn't worked.
ADC_HandleTypeDef hadc;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC_Init(void);
uint16_t adcVal = 0;
int main(void) {
HAL_Init();
MX_GPIO_Init();
MX_ADC_Init();
/*
// Bit 25 LFMEN: Low Frequency Mode enabled
ADC->CCR |= (1UL << 25);
// Bit 22 VREFEN: VREFINT enable
ADC->CCR |= (1UL << 22);
// Bit 9 ULP: Vrefint is ON in low power mode
PWR->CR &= ~(1UL << 9U);
*/
HAL_PWREx_EnableLowPowerRunMode();
while (1) {
HAL_Delay(500);
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, 100);
adcVal = HAL_ADC_GetValue(&hadc);
HAL_ADC_Stop(&hadc);
}
}
/* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/* Configure the main internal regulator output voltage */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Initializes the RCC Oscillators according to the specified
*parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_2;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
/* Initializes the CPU, AHB and APB buses clocks */
RCC_ClkInitStruct.ClockType =RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {
Error_Handler();
}
}
/*
* #brief ADC Initialization Function
* #param None
* #retval None
*/
static void MX_ADC_Init(void) {
/* USER CODE BEGIN ADC_Init 0 */
/* USER CODE END ADC_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC_Init 1 */
/* USER CODE END ADC_Init 1 */
/* Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */
hadc.Instance = ADC1;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerFrequencyMode = ENABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
if (HAL_ADC_Init(&hadc) != HAL_OK) {
Error_Handler();
}
/* Configure for the selected ADC regular channel to be converted. */
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
Error_Handler();
}
}
I'm using DMA to Access the Data from my ADC. The value at the ADC changes permantenly.
I read I can use DMA so I can use the value of the ADC everytime and everywhere I want to.
Problem is that my Main while() Loop is not or just once execute. The DMA Interupt calls.
HAL_ADC_Start_DMA(&hadc, (uint32_t*) &buffer, 1);
Here is the Code for Start the DMA for the ADC. Mode is Circular.
Here is the Init:
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSI14
|RCC_OSCILLATORTYPE_HSI48;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.HSI14State = RCC_HSI14_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.HSI14CalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2
|RCC_PERIPHCLK_I2C1;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_HSI;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/**
* #brief ADC Initialization Function
* #param None
* #retval None
*/
static void MX_ADC_Init(void)
{
/* USER CODE BEGIN ADC_Init 0 */
/* USER CODE END ADC_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC_Init 1 */
/* USER CODE END ADC_Init 1 */
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = ENABLE;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC_Init 2 */
/* USER CODE END ADC_Init 2 */
}
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
The ADC reads a analog volage from I/O.
My while(1) Loop currently just contains blinking led code.
Check the following:
Inside Hal_MSP file use DMA_CIRCULAR
create the buffer like this -> __IO uint16_t buffer[1]
then use it like this -> HAL_ADC_Start_DMA(&hadc, (uint32_t*) &buffer, 1);
Its better to start DMA at the end of ADC init. You can place above line inside the USER CODE BEGIN ADC_Init 2 comment braces.
The ADC size is 12 bit of this controller so circular DMA will automatically overwrite after every conversion.
I am working on a project where a STM32H743 nucleo board and use of 16 ADC inputs are involved.
Obviously, these analog inputs are used once a time; read the value via polling mechanism and configure the next input... configure the ADC channel, start the ADC, read the value via polling and configure the next input... 16 times each 1 ms, as a Real-Time behaviour.
The problem I found is that I can´t start any of the 3 ADCs, it stuck at this line at
stm32h7xx_hal_adc.h (I think that I configure the clocks or another sort of things incorrectly) :
while(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL)
This line is in the function:
HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef *hadc)
That is being called by:
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc)
Thanks in advance for the help, the source code is provided below.
The source code files are:
MAIN.C
#include "main.h"
#include "hwdrvlib.h"
#include "test.h"
volatile unsigned int systick_count = 0;
static volatile int systick_active = 1;
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
#ifdef CPU_CACHE
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
#endif
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config(); //Located on hwdrvlid.h y hwdrvlib.c
/* SysTick is 0 at start */
tick = (uint8_t)0;
/* Initialize */
ADC_Init(); /* Initialize ADC peripherals and GPIO ADC inputs as analog */
//Located on hwdrvlid.h y hwdrvlib.c
/* Sample Time: 0.001 */
while (...) { /* Some comparison deleted for readability */
RT_Task(); //Located on Function file
} //End of while
}
hwdrvlib.c (The file that contains configuration functions)
ADC_HandleTypeDef hadc1 __attribute__((section(".ramd2")));
ADC_HandleTypeDef hadc2 __attribute__((section(".ramd2")));
ADC_HandleTypeDef hadc3 __attribute__((section(".ramd2")));
void ADC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* ADC Clock Enable */
__HAL_RCC_ADC12_CLK_ENABLE();
__HAL_RCC_ADC3_CLK_ENABLE();
/* ADC Periph interface clock configuration */
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP);//or PLL2
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/* ADCs GPIO as analog input */
/* System ADC Input number 1 PF9 */
/*##-2- Configure peripheral GPIO ##########################################*/
/* ADC Channel GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* Initialization of 16 analog inputs, hidden for readability */
/* System ADC Input number 16 PA3 */
/*##-2- Configure peripheral GPIO ##########################################*/
/* ADC Channel GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* ADC1 Config */
hadc1.Instance = ADC1;
if (HAL_ADC_DeInit(&hadc1) != HAL_OK) {
/* ADC1 de-initialization Error */
Error_Handler();
}
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_16B;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1; /* Vector Support */
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.NbrOfDiscConversion = 1;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK) {
Error_Handler();
}
/* The same for ADC2 and ADC3 using hadc2 and hadc3 */
}
void ADC_Input_Select(ADC_HandleTypeDef *hadc,uint32_t Channel)
{
static ADC_ChannelConfTypeDef sConfig = { 0 };
/* Configure Regular Channel */
sConfig.Channel = Channel;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_387CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(hadc, &sConfig) != HAL_OK) {
Error_Handler();
}
}
/**
* #brief System Clock Configuration
* #retval None
*
*
*
* Configure 480 MHz CPU Clock, 240 MHz APB1 and APB2 Clock
* flash latency 4
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 };
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {
}
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {
}
__HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSI);//HSE
/* a 480 MHz config */
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {
}
/** Initializes the CPU, AHB and APB busses clocks
*/
#ifdef USB_VCP_SETUP
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 |
RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 60;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
#else
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 60;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
#endif
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
/* End of old 480 MHz config */
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) {
Error_Handler();
}
/* USB CLK Initialization if needed */
#ifdef USB_VCP_SETUP
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;//PLL
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
Error_Handler();
}
/** Enable USB Voltage detector
*/
HAL_PWREx_EnableUSBVoltageDetector();
#endif
}
FUNCTION FILE
(The function that contains the function to be executed, in order to read analog input data)
void RT_Task(void)
{
/* ADC3-IN2 PF9 */
ADC_Input_Select(&hadc3,ADC_CHANNEL_2);
HAL_ADC_Start(&hadc3); /* Execution stucks here :( */
if (HAL_ADC_PollForConversion(&hadc3,1000) != HAL_OK ) {
/* ADC conversion fails */
//Escribir aqui la salida de error
} else {
test2_B.VectorConcatenate[1] = HAL_ADC_GetValue(&hadc3) + 0;
}
/* More ADC reading hidden for readability */
}
Solution for this problem, remember that you can face this with any microcontroller:
I found the failure, it is something that I never imagine before.
The initialization function takes more time that the SysTick IRQ needs to trigger the first IRQ (the Real-Time task is called from the SysTick IRQ), and due to ADC peripherals are not initialized... its functions could not be executed properly.
I added an uint8 variable to detect if the initialization function ends at RT Task call start code. Also I need to enable ADC_ConfigureBoostMode(&hadc1); for each used ADC.
int main(void)
{
Init_finished = (uint8_t)0;
#ifdef CPU_CACHE
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
#endif
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* SysTick is 0 at start */
tick = (uint8_t)0;
/* Initialize model */
test_initialize(1);
Init_finished = (uint8_t)255;
and use these
ADC_ConfigureBoostMode(&hadc1); /* and for hadc2 and hadc3 */
I am using HC-05 bluetooth module and STM32F407. I am trying to change the name of the bluetooth module. I can enter AT Command Mode, but i can't send any AT Commands to module. I tried something in main. But it didn't work
I see
huart->Instance->DR = (*pData++ & (uint8_t)0xFF);
in my Transmit function. Also, i see ascii values of elements in DR
Here is my try.
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "string.h"
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart3;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART3_UART_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART3_UART_Init();
/* USER CODE BEGIN 2 */
char* data = "AT+NAME=charles \n\r";
HAL_UART_Transmit(&huart3, (uint8_t *)data, strlen(data), 2000);
/* USER CODE END 2 */
while (1)
{
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
static void MX_USART3_UART_Init(void)
{
huart3.Instance = USART3;
huart3.Init.BaudRate = 38400;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart3) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
}
[1]: https://i.stack.imgur.com/pbxqx.png
If you want to send a character buffer:
static void MX_USART3_UART_Init(void)
{
char* data = "AT+NAME=charles \n\r";
HAL_UART_Transmit(&huart3, (uint8_t *)data, strlen(data), 2000);
}
That's all you need. You called sprintf as if it was strcpy and the first argument is an uninitialized character buffer.
as tadman said, you don't need this:
uint8_t data[50];
But this is not a uninitialized character buffer as tadman said.
I want to configure ADC with DMA on STM32(Nucleo-F401RE) and transmit the values through SPI to Basys 3 FPGA. Before transmission through SPI, when i read the values in memory realtime using STMSTudio, it is erratic.
In the past,I have tried increasing the sampling cycles, the issue persists.
Configured ADC without DMA with HAL_ADC_Start function and transferred the values to PC through UART, unable to retrieve the original signal. I'm unable to isolate where the problem lies.
uint32_t ADC1ConvertedValues[100];
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_SPI1_Init();
while (1) {
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,GPIO_PIN_SET);
if (HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC1ConvertedValues, 100) == HAL_OK) {
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1,(uint8_t*)(ADC1ConvertedValues),4,1);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,GPIO_PIN_SET);
}
}
}
void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
Error_Handler();
}
}
static void MX_ADC1_Init(void) {
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_8B;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if (HAL_ADC_Init(&hadc1) != HAL_OK) {
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
Error_Handler();
}
}
static void MX_SPI1_Init(void) {
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK) {
Error_Handler();
}
}
static void MX_DMA_Init(void) {
__HAL_RCC_DMA2_CLK_ENABLE();
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
static void MX_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void Error_Handler(void) {
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line) {
#endif /* USE_FULL_ASSERT */
EDIT 1: I used the arduino IDE to program NUCLEO-f401 RE and below is the code used :
#include <f401reMap.h>
float analogPin = pinMap(31); //PA0
float val = 0; // variable to store the value read
void setup() {
Serial.begin(115200); // setup serial
analogReadResolution(12);
}
void loop() {
val = analogRead(analogPin); // read the input pin
Serial.println(val); // debug value
}
It works for input signal frequency below 100Hz. How do I increase the throughput rate? My project requires conversion of analog signal between 500KHz to 900Khz.
Tried changing the DMA buffer size/speed uint32_t ADC1ConvertedValues[100]; reading about the DMA for this chip for my project I found that this sets the size of memory direct memory access allocated samples per clock? If it was I2C or if you would like to read about the timing concepts keep reading You need to find the ADC registers that set the spi baud rate and account for the setup requirements or re-initialization.
hadc1.Instance = ADC1;// this selects analog to digital circuit one
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; //"skip" 3 out of 4 clock steps in sync with time scale read on...
hadc1.Init.Resolution = ADC_RESOLUTION_8B; //use 8 bits to pack the numbers to send to the intergrated CPU of the f401
Background on the math
ADC and DMA are often classifyed in read rate at the spi level not at the analog level. So if the chip can do 8khz spi using 8 bits then we can calculate in bigO (8n+n) time that we should get just under 1khz read speed. HOWEVER you need to write 8 bits to receive 8bits so bigO time is now bigO(n16+n) . But because of continuous register I believe it could be as low as bigO (8n+n+8) or (8n+n+8setupbits). So using that we know the time consumed by the intermediate operations in terms of clock cycles note that the term n alone is to account for assumptions of unknown internal clock trigger conditions and should have a scalar that relative to theta if scale resolution is a absolute requirement. Also keep in mind that these frequencies you may be experiencing noise from impedance resistance and capacitance.