2023-04-23 01:45 AM - edited 2023-11-20 07:22 AM
I am currently working on a project using the STM32F407G-DISC1 development board and STM32CubeIDE. The goal is to analyze the data and print the respiratory rate after continuously collecting ADC data for 10 seconds. However, I encountered some problems and hope you can help.
First of all, when I press the button for the first time, the pointer points to the "HardFault_Handler"; and when I press it for the second time, although the ADC value can be read, there is no printing in the ITM window. The fault analyzer shows the following information:
1.Bus: Memory management or usage failure
2.Instruction access conflict
3.When the fault occurs, the value of the stack pointer, please make sure this value points to a valid heap memory area
MSP = Main Stack Pointer
PSP = Process Stack Pointer
I have increased the stack size to 0x2000.
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_host.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <math.h>
#include <stdio.h>
#include "arm_math.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_conf.h"
#include "stdbool.h"
#define ADC_BUFFER_SIZE 512
#define FFT_SIZE 512
#define SAMPLING_FREQ 100
volatile bool adc_conversion_complete = false;
volatile bool print_bpm_flag = false;
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
uint16_t adc_buffer[ADC_BUFFER_SIZE];
float32_t fft_input[FFT_SIZE];
float32_t fft_output[FFT_SIZE];
float32_t magnitude[FFT_SIZE/2];
uint16_t max_index;
float32_t max_magnitude;
float32_t freq_estimate;
uint16_t adc_val;
uint16_t adc_val_global= 0;
float32_t freq_estimate_global= 0;
float32_t freq_estimate_global_bpm= 0;
bool print_timer_flag = true;
uint32_t counter = 0;
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
int _write(int file, char *ptr, int len) {
int i;
for (i = 0; i < len; i++) {
ITM_SendChar(*ptr++);
}
return len;
}
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
I2C_HandleTypeDef hi2c1;
SPI_HandleTypeDef hspi1;
TIM_HandleTypeDef htim2;
/* USER CODE BEGIN PV */
/* 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_I2C1_Init(void);
static void MX_SPI1_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM2_Init(void);
void MX_USB_HOST_Process(void);
/* USER CODE BEGIN PFP */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
// Add a printf statement to check if the callback is being called
//printf("ADC conversion complete callback called\n");
float32_t sum = 0.0;
for (int i = 0; i < ADC_BUFFER_SIZE; i++) {
sum += adc_buffer[i];
}
for (int i = 0; i < ADC_BUFFER_SIZE; i++) {
adc_val = adc_buffer[i];
fft_input[i] = ((float32_t)adc_val)/4095.0f; //normalize to [0,1]
}
// Perform FFT
arm_cfft_radix4_instance_f32 fft_instance;
arm_cfft_radix4_init_f32(&fft_instance, FFT_SIZE, 0, 1);
arm_cfft_radix4_f32(&fft_instance, fft_input);
arm_cmplx_mag_f32(fft_input, magnitude, FFT_SIZE/2);
// Find maximum magnitude index
max_index = 0;
max_magnitude = 0;
for (int i = 0; i < FFT_SIZE/2; i++) {
if (magnitude[i] > max_magnitude) {
max_magnitude = magnitude[i];
max_index = i;
}
}
adc_conversion_complete = true;
// Estimate frequency
freq_estimate = ((float32_t)max_index)*((float32_t)SAMPLING_FREQ)/((float32_t)FFT_SIZE);
//Update the HAL_ADC_ConvCpltCallback function to store the values in global variables
adc_val_global = adc_buffer[0];
freq_estimate_global = freq_estimate;
freq_estimate_global_bpm= freq_estimate_global*60.0f;
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM2)
{
counter++;
// Add a printf statement to check if the callback is being called
// printf("TIM2 callback called, counter: %lu\n", counter);
if (counter >= 10)
{
if (adc_conversion_complete)
{
printf("frequency estimate: %f \n", freq_estimate_global);
printf("Respiratory frequency estimate: %f bpm\n", freq_estimate_global_bpm);
// Reset the counter
counter = 0;
// Reset the flag
adc_conversion_complete = false;
}
}
}
}
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
//STM32 Debugging With ST-Link v2 SWD | Serial Wire Viewer
/* 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_I2C1_Init();
MX_SPI1_Init();
MX_USB_HOST_Init();
MX_ADC1_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
HAL_Delay(100);
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_BUFFER_SIZE);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
MX_USB_HOST_Process();
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}