STM32F407: Transplantation of CMSIS-DSP library (based on library files)

Table of Contents

1. Source code download

2. Introduction to DSP library source code

3. Library-based transplantation (use of DSP library)

3.1 Experiment 1

3.2 Experiment 2

4. Compile using the V6 version of the compiler


Previous article: STM32F407-Discovery’s hardware FPU-CSDN blog

1. Source code download

Github address: GitHub – ARM-software/CMSIS_5: CMSIS Version 5 Development Repository

The latest version is 5.9.0, you can also use the one that comes with the HAL library. This article is based on the DSP version that comes with STM32Cube_FW_F4_V1.27.0

2. Introduction to DSP library source code

The directory structure is as follows: \Drivers\CMSIS\DSP

Example: Some official examples

Include: public header folder directory, the more important one is arm_math.h

Projects: Official project examples

Source: DSP source code implementation, which is the key directory

The function description of each folder in the Source directory is as follows:

folder

Implemented functions (API)

BasicMathFunctions

Implement basic mathematical functions, including basic operations such as floating point/fixed point/vector

CommonTables

Some common parameter tables

ComplexMathFunctions

Calculation of complex numbers: addition, subtraction, multiplication, division, modulus, etc.

ControllerFunctions

Some control function functions: such as PID control algorithm

FastMathFunctions

Some fast calculation algorithms implemented by pure mathematical theory: finding sine and cosine/fast square root

FilteringFunctions

Implementation of filtering function: IIR/FIR/LMS/convolution, etc.

MatrixFunctions

APIs related to matrix operations: addition, subtraction, transposition, inversion, etc.

StatisticsFunctions

Commonly used statistical methods: finding mean/variance/standard deviation/root mean square, etc.

SupportFunctions

Functional functions: data copy (a continuous block)/conversion between fixed-point and floating-point

TransformFunctions

Transformation function implementation: FFT/IFFT of complex numbers/real numbers and discrete cosine transform DCT

Corresponding DSP LIB library: \Drivers\CMSIS\Lib\ARM:

STM32F4 is an M4 core, and the FPU supports single-precision floating-point data operations and little-endian mode, so: arm_cortexM4lf_math.lib is the key file.

3. Library-based transplantation (use of DSP library)

Model the directory structure of the source code library file and create a new folder: Drivers\CMSIS\Lib\ARM

Then copy arm_cortexM4lf_math.lib directly to the ARM directory.

Model the directory structure of the source code library and create a new folder: Drivers\CMSIS\DSP\Include

Also copy the three header files in the source directory:

Add the library file to the Keil project and add the header file path:

At this point, the porting of the library has been completed, and the next step is to preprocess and define some macros.

(1) First, the hardware FPU needs to be turned on: it depends on __FPU_PRESENT and __FPU_USED

See the previous article for details: STM32F407-Discovery’s hardware FPU-CSDN blog

(2) Use basic mathematical operations in the DSP library, such as sin()/cos(): ARM_MATH_DSP

(3) If matrix operations are used, the matrix size is a very noteworthy issue. The size of the input matrix must be checked before the operation: ARM_MATH_MATRIX_CHECK

(4) When converting floating point numbers to Q32/Q15/Q7, rounding is processed to ensure that data accuracy is not lost to the maximum extent: ARM_MATH_ROUNDING

(5) Speed up execution when processing data in batches, such as finding absolute values in batches: ARM_MATH_LOOPUNROLL

(6) Finally, there is a macro of the CM4 kernel: ARM_MATH_CM4

Add these to the global macro definition:

USE_HAL_DRIVER,STM32F407xx,USE_STM32F4_DISCO,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING,ARM_MATH_LOOPUNROLL,ARM_MATH_CM4

3.1 Experiment 1

Compare the calculation speed of MDK standard library functions and DSP library functions.

Main.c

/* Includes ----------------------------------------------- -----------------------*/
#include "main.h"

#define DELTA 0.0001f /* Error value */
extern TIM_HandleTypeDef g_timx_handle;
uint8_t g_timeout;

/**
 * @brief sin cos test
 * @param angle: starting angle
 * @param times: number of operations
 * @param mode: whether to use DSP library
 * @arg 0, do not use DSP library;
 * @arg 1, use DSP library;
 *
 * @retval None
 */
uint8_t sin_cos_test(float angle, uint32_t times, uint8_t mode)
{
    float sinx, cosx;
    float result;
    uint32_t i = 0;

    if (mode == 0)
    {
        for (i = 0; i < times; i + + )
        {
            cosx = cosf(angle); /* Sin, cos function without DSP optimization */
            sinx = sinf(angle);
            result = sinx * sinx + cosx * cosx; /* The calculation result should be equal to 1 */
            result = fabsf(result - 1.0f); /* Compare the difference with 1 */

            if (result > DELTA)return 0XFF; /* Judgment failed */

            angle + = 0.001f; /* Angle increases */
        }
    }
    else
    {
        for (i = 0; i < times; i + + )
        {
            cosx = arm_cos_f32(angle); /* Use DSP optimized sin, cos function */
            sinx = arm_sin_f32(angle);
            result = sinx * sinx + cosx * cosx; /* The calculation result should be equal to 1 */
            result = fabsf(result - 1.0f); /* Compare the difference with 1 */

            if (result > DELTA)return 0XFF; /* Judgment failed */

            angle + = 0.001f; /* Angle increases */
        }
    }

    return 0; /* Task completed */
}

int main(void)
{
float time;
uint8_t res;

/* STM32F4xx HAL library initialization:
- Configure the Flash prefetch, instruction and Data caches
- Configure the Systick to generate an interrupt each 1 msec
-Set NVIC Group Priority to 4
- Global MSP (MCU Support Package) initialization
*/
HAL_Init();
/* Configure the system clock to 168 MHz */
SystemClock_Config();

/* Serial port 2 initialization: only use tx function */
if(uart2_init(9600))
{
Error_Handler();
}

#if 1
// BSP_LED_Off(LED6);
// HAL_Delay(200);
//
// BSP_LED_On(LED6);
// //HAL_Delay(1000);
// //test_fpu_tmp1();
// fft_test();
// BSP_LED_Off(LED6);
// for (int i=0; i <N; i + + ) { //Printing is time-consuming
// printf("ifft: OUTPUT_SEQ[%d].real=%f, OUTPUT_SEQ[%d].img=%f\\
", i, OUTPUT_SEQ[i].real, i, OUTPUT_SEQ[i] .img);
// }
// printf("\\
\\
");

   //Don’t use GPIO to measure the duration, use a timer instead
btim_timx_int_init(65535, 8400 - 1);
__HAL_TIM_SET_COUNTER( & amp;g_timx_handle, 0); /* Reset the counter value of TIM6 timer */
g_timeout = 0;
res = sin_cos_test(PI / 6, 200000, 0);
//HAL_Delay(1000);

time = __HAL_TIM_GET_COUNTER( & amp;g_timx_handle) + (uint32_t)g_timeout * 65536;
    printf("%0.1fms\r\\
", time / 10);

/* Use DSP optimization */
__HAL_TIM_SET_COUNTER( & amp;g_timx_handle, 0); /* Reset the counter value of TIM6 timer */
g_timeout = 0;
res = sin_cos_test(PI / 6, 200000, 1);
time = __HAL_TIM_GET_COUNTER( & amp;g_timx_handle) + (uint32_t)g_timeout * 65536;
printf("%0.1fms\r\\
", time / 10);
#endif

printf("__CC_ARM:%d\\
", __CC_ARM);
printf("__FPU_PRESENT:%d\\
", __FPU_PRESENT);
printf("__FPU_USED:%d\\
", __FPU_USED);
printf("SCB->CPACR:0x%x\\
", SCB->CPACR);

while(1){
;
}

return 0;
}

/**
  * @brief System Clock Configuration
  * The system Clock is configured as follow:
  * System Clock source = PLL (HSE)
  *SYSCLK(Hz) = 168000000
  *HCLK(Hz) = 168000000
  * AHB Prescaler = 1
  *APB1 Prescaler = 4
  *APB2 Prescaler = 2
  *HSE Frequency(Hz) = 8000000
  *PLL_M = 8
  *PLL_N = 336
  *PLL_P = 2
  *PLL_Q = 7
  * VDD(V) = 3.3
  * Main regulator output voltage = Scale1 mode
  * Flash Latency(WS) = 5
  * @param None
  * @retval None
  */
static void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;

  /* Enable Power Control clock */
  __HAL_RCC_PWR_CLK_ENABLE();

  /* 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);


  /* Enable HSE Oscillator and activate PLL with HSE as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;

  if(HAL_RCC_OscConfig( & amp;RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
     clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  if(HAL_RCC_ClockConfig( & amp;RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }

  /* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */
  if (HAL_GetREVID() == 0x1001)
  {
    /* Enable the Flash prefetch */
    __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
  }
}

The running results are as follows:

[22:54:44.691] 315.0ms //Use library function

[22:54:44.851] 153.9ms //Use DSP

[22:54:44.851] __CC_ARM:1

[22:54:44.867] __FPU_PRESENT:1

[22:54:44.883] __FPU_USED:1

[22:54:44.898] SCB->CPACR:0xf00000

3.2 Experiment 2

Measure the running time of complex FFT calculation of 1024 points

main.c

/* FFT length, if not specified, the default is 1024 points
 * Optional length range: 16, 64, 256, 1024.
 */
#define FFT_LENGTH 1024

float fft_inputbuf[FFT_LENGTH * 2]; /* FFT input array */
float fft_outputbuf[FFT_LENGTH]; /* FFT output array */
uint8_t g_timeout;
extern TIM_HandleTypeDef g_timx_handle;

int main(void)
{
float time;
uint8_t res;
int i;
arm_cfft_radix4_instance_f32 scfft;

/* STM32F4xx HAL library initialization:
- Configure the Flash prefetch, instruction and Data caches
- Configure the Systick to generate an interrupt each 1 msec
-Set NVIC Group Priority to 4
- Global MSP (MCU Support Package) initialization
*/
HAL_Init();

/* Configure the system clock to 168 MHz */
SystemClock_Config();

/* Serial port 2 initialization: only use tx function */
if(uart2_init(9600))
{
Error_Handler();
}

/* Initialize the scfft structure and set relevant parameters */
arm_cfft_radix4_init_f32( & amp;scfft, FFT_LENGTH, 0, 1);

#if 1
/* Initialize input sequence */
for (i = 0; i < FFT_LENGTH; i + + )
{
fft_inputbuf[2 * i] = 100 +
10 * arm_sin_f32(2 * PI * i / FFT_LENGTH) +
30 * arm_sin_f32(2 * PI * i * 4 / FFT_LENGTH) +
50 * arm_cos_f32(2 * PI * i * 8 / FFT_LENGTH); /* real part */
fft_inputbuf[2 * i + 1] = 0; /* Imaginary part: both are 0 */
}
\t
btim_timx_int_init(65535, 8400 - 1);
__HAL_TIM_SET_COUNTER( & amp;g_timx_handle, 0); /* Reset the counter value of TIM6 timer */
g_timeout = 0;

arm_cfft_radix4_f32( & amp;scfft, fft_inputbuf); /* FFT (base 4) */

/* Calculate running time */
time =__HAL_TIM_GET_COUNTER( & amp;g_timx_handle) + (uint32_t)g_timeout * 65536;
printf("%0.1fms\r\\
", time / 10);

arm_cmplx_mag_f32(fft_inputbuf, fft_outputbuf, FFT_LENGTH); /* Find the modulus */

printf("\r\\
%d point FFT runtime:%0.1fms\r\\
", FFT_LENGTH, time / 10);
// printf("FFT Result:\r\\
");

// for (i = 0; i < FFT_LENGTH; i + + )
// {
// printf("fft_outputbuf[%d]:%f\r\\
", i, fft_outputbuf[i]);
// }
#endif

printf("__CC_ARM:%d\\
", __CC_ARM);
printf("__FPU_PRESENT:%d\\
", __FPU_PRESENT);
printf("__FPU_USED:%d\\
", __FPU_USED);
printf("SCB->CPACR:0x%x\\
", SCB->CPACR);

while(1){
;
}

return 0;
}

Printing: It takes about 0.6ms to complete a 1024-point complex number operation.

[23:39:30.141] 0.6ms

[23:39:30.141]

[23:39:30.141] 1024 point FFT runtime:0.0ms

[23:39:30.172] __CC_ARM:1

[23:39:30.188] __FPU_PRESENT:1

[23:39:30.204] __FPU_USED:1

[23:39:30.220] SCB->CPACR:0xf00000

4. Use Compile with the V6 version of the compiler

A bunch of errors occurred during compilation: ArmClang: error: unsupported option ‘–C99’

Just change –C99 to -xc -std=c99:

Change as follows:

Note:

(1) If you want to use the V5 compiler, this option must be changed back to –C99

(2) The V6 version of the compiler has optimized floating point number operations. After configuring the optimization level to fast mode, there is a significant speed improvement compared to the V5 version, as follows:

AC6 version compiler configuration

Based on the above experiment 2: the running result took 0.5ms

[10:47:32.200] test_fft()->times: 0.500000ms

[10:47:32.232] __FPU_PRESENT:1

[10:47:32.248] __FPU_USED:1

[10:47:32.264] SCB->CPACR:0xf00000

For comparison of AC5 and AC6 compilers of MDK5, you can refer to this forum:

https://www.armbbs.cn/forum.php?mod=viewthread & amp;tid=95455

Test code: main.c

/**
  *************************************************** ******************************
  * @file UART/UART_TwoBoards_ComPolling/Src/main.c
  * @author MCD Application Team
  * @brief This sample code shows how to use STM32F4xx UART HAL API to transmit
  * and receive a data buffer with a communication process based on
  * polling transfer.
  * The communication is done using 2 Boards.
  *************************************************** ******************************
  * @attention
  *
  * Copyright (c) 2017 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  *************************************************** ******************************
  */

/* Includes ----------------------------------------------- ------------------*/
#include "main.h"

/** @addtogroup STM32F4xx_HAL_Examples
  * @{
  */

/** @addtogroup UART_TwoBoards_ComPolling
  * @{
  */

/* Private typedef ----------------------------------------------- -------------*/
/* Private define -------------------------------------------------- ---------------*/
#define TRANSMITTER_BOARD

/* Private function prototypes ------------------------------------------------ --*/
static void SystemClock_Config(void);
static void Error_Handler(void);

/* Private functions -------------------------------------------------- -----------*/

extern TIM_HandleTypeDef g_timx_handle;
uint8_t g_timeout;

float re_dat;
float a=0.14f;
float b=0.26f;

void test_fpu_tmp1(void)
{
long i, j;
float re_nul;
float time;

/* Initialize timer 6 */
btim_timx_int_init(65535, 8400 - 1);
/* Reset the counter value of TIM6 timer */
__HAL_TIM_SET_COUNTER( & amp;g_timx_handle, 0);
g_timeout = 0;

for(i=0; i<10000; i + + ) {
for(j=0; j<2; j + + ) {
re_nul=a*b;
re_dat=re_dat + re_nul;
a=a + 0.1f;
b=b + 0.1f;
}
}

/* Calculate running time */
time =__HAL_TIM_GET_COUNTER( & amp;g_timx_handle) + (uint32_t)g_timeout * 65536;
printf("%s()->times: %fms\r\\
", __func__, time / 10);

btim_timx_int_deinit(65535, 8400 - 1);
printf("re_dat:%f\\
", re_dat);

}

complex INPUT_SEQ[FFT_LEN], RES_SEQ[FFT_LEN], OUTPUT_SEQ[FFT_LEN];
float SEQ_DAT[FFT_LEN], dataR[FFT_LEN], dataI[FFT_LEN];
int fft_priv_test(void)
{
int i, j;
float time;

//Construct a sequence of real numbers
for (i=0; i < FFT_LEN; i + + ) {
SEQ_DAT[i]=i + 0.0f;
}

//Construct a sequence of imaginary numbers
for (j=0; j<FFT_LEN; j + + ) {
INPUT_SEQ[j].real= SEQ_DAT[j];
INPUT_SEQ[j].img=0.0f;
}

// for (i=0; i <FFT_LEN; i + + ) {
// printf("before fft: INPUT_SEQ[%d].real=%f, INPUT_SEQ[%d].img=%f\\
", i, INPUT_SEQ[i].real, i, INPUT_SEQ[i ].img);
// }
// printf("\\
\\
");

/* Initialize timer 6 */
btim_timx_int_init(65535, 8400 - 1);
/* Reset the counter value of TIM6 timer */
__HAL_TIM_SET_COUNTER( & amp;g_timx_handle, 0);
g_timeout = 0;

#if 1
FFT(INPUT_SEQ, FFT_LEN, FFT_ORDER, RES_SEQ);
// for (i=0; i <FFT_LEN; i + + ) {
// printf("fft: RES_SEQ[%d].real=%f, RES_SEQ[%d].img=%f\\
", i, RES_SEQ[i].real, i, RES_SEQ[i] .img);
// }
// printf("\\
\\
");

iFFT(RES_SEQ, FFT_LEN, FFT_ORDER, OUTPUT_SEQ);
/* Calculate running time */
time =__HAL_TIM_GET_COUNTER( & amp;g_timx_handle) + (uint32_t)g_timeout * 65536;
printf("%s()->times: %fms\r\\
", __func__, time / 10);

btim_timx_int_deinit(65535, 8400 - 1);

#else
HAL_Delay(1000);
#endif

// for (i=0; i <FFT_LEN; i + + ) { //Printing is time-consuming
// printf("ifft: OUTPUT_SEQ[%d].real=%f, OUTPUT_SEQ[%d].img=%f\\
", i, OUTPUT_SEQ[i].real, i, OUTPUT_SEQ[i] .img);
// }
// printf("\\
\\
");

return 0;
}

#define DELTA 0.0001f /* Error value */

/**
 * @brief sin cos test
 * @param angle: starting angle
 * @param times: number of operations
 * @param mode: whether to use DSP library
 * @arg 0, do not use DSP library;
 * @arg 1, use DSP library;
 *
 * @retval None
 */
uint8_t sin_cos_test(float angle, uint32_t times, uint8_t mode)
{
    float sinx, cosx;
    float result;
float time;
    uint32_t i = 0;

/* Initialize timer 6 */
btim_timx_int_init(65535, 8400 - 1);
/* Reset the counter value of TIM6 timer */
__HAL_TIM_SET_COUNTER( & amp;g_timx_handle, 0);
g_timeout = 0;

    if (mode == 0)
    {
    printf("not use DSP\\
");
        for (i = 0; i < times; i + + )
        {
            cosx = cosf(angle); /* Sin, cos function without DSP optimization */
            sinx = sinf(angle);
            result = sinx * sinx + cosx * cosx; /* The calculation result should be equal to 1 */
            result = fabsf(result - 1.0f); /* Compare the difference with 1 */

            if (result > DELTA)return 0XFF; /* Judgment failed */

            angle + = 0.001f; /* Angle increases */
        }
    }
    else
    {
    printf("use DSP\\
");
        for (i = 0; i < times; i + + )
        {
            cosx = arm_cos_f32(angle); /* Use DSP optimized sin, cos function */
            sinx = arm_sin_f32(angle);
            result = sinx * sinx + cosx * cosx; /* The calculation result should be equal to 1 */
            result = fabsf(result - 1.0f); /* Compare the difference with 1 */

            if (result > DELTA)return 0XFF; /* Judgment failed */

            angle + = 0.001f; /* Angle increases */
        }
    }

/* Calculate running time */
time =__HAL_TIM_GET_COUNTER( & amp;g_timx_handle) + (uint32_t)g_timeout * 65536;
printf("%s()->times: %fms\r\\
", __func__, time / 10);

btim_timx_int_deinit(65535, 8400 - 1);
    return 0; /* Task completed */
}


/****************************************************** *******************/
/* FFT length, if not specified, the default is 1024 points
 * Optional length range: 16, 64, 256, 1024.
 */
#define FFT_LENGTH 1024
float fft_inputbuf[FFT_LENGTH * 2]; /* FFT input array */
float fft_outputbuf[FFT_LENGTH]; /* FFT output array */

void test_fft(void)
{
int i;
float time;
arm_cfft_radix4_instance_f32 scfft;

/* Initialize the scfft structure and set relevant parameters */
arm_cfft_radix4_init_f32( & amp;scfft, FFT_LENGTH, 0, 1);

/* Initialize input sequence */
for (i = 0; i < FFT_LENGTH; i + + )
{
\t\t\t/* Real */
fft_inputbuf[2 * i] = 100 +
10 * arm_sin_f32(2 * PI * i / FFT_LENGTH) +
30 * arm_sin_f32(2 * PI * i * 4 / FFT_LENGTH) +
50 * arm_cos_f32(2 * PI * i * 8 / FFT_LENGTH);
/* Imaginary part: all are 0 */
fft_inputbuf[2 * i + 1] = 0;
}

/* Initialize timer 6 */
btim_timx_int_init(65535, 8400 - 1);
/* Reset the counter value of TIM6 timer */
__HAL_TIM_SET_COUNTER( & amp;g_timx_handle, 0);
g_timeout = 0;

/* FFT(base 4) */
arm_cfft_radix4_f32( & amp;scfft, fft_inputbuf);

/* Calculate running time */
time =__HAL_TIM_GET_COUNTER( & amp;g_timx_handle) + (uint32_t)g_timeout * 65536;
printf("%s()->times: %fms\r\\
", __func__, time / 10);

/* Find the modulus */
// arm_cmplx_mag_f32(fft_inputbuf, fft_outputbuf, FFT_LENGTH);
//
// printf("\r\\
%d point FFT runtime:%0.1fms\r\\
", FFT_LENGTH, time / 10);
// printf("FFT Result:\r\\
");
//
// for (i = 0; i < FFT_LENGTH; i + + )
// {
// printf("fft_outputbuf[%d]:%f\r\\
", i, fft_outputbuf[i]);
// }
btim_timx_int_deinit(65535, 8400 - 1);
}
/****************************************************** *******************/

int main(void)
{
uint8_t res;

/* STM32F4xx HAL library initialization:
- Configure the Flash prefetch, instruction and Data caches
- Configure the Systick to generate an interrupt each 1 msec
-Set NVIC Group Priority to 4
- Global MSP (MCU Support Package) initialization
*/
HAL_Init();

/* Configure the system clock to 168 MHz */
SystemClock_Config();

/* Serial port 2 initialization: only use tx function */
if(uart2_init(9600))
{
Error_Handler();
}

#if 1
test_fft();
// res=sin_cos_test(PI / 6, 200000, 0);
// res=sin_cos_test(PI / 6, 200000, 1);
// res=fft_priv_test();
// test_fpu_tmp1();
#endif

//printf("__CC_ARM:%d\\
", __CC_ARM);
printf("__FPU_PRESENT:%d\\
", __FPU_PRESENT);
printf("__FPU_USED:%d\\
", __FPU_USED);
printf("SCB->CPACR:0x%x\\
", SCB->CPACR);

while(1){
;
}

return 0;
}

/**
  * @brief System Clock Configuration
  * The system Clock is configured as follow:
  * System Clock source = PLL (HSE)
  *SYSCLK(Hz) = 168000000
  *HCLK(Hz) = 168000000
  * AHB Prescaler = 1
  *APB1 Prescaler = 4
  *APB2 Prescaler = 2
  *HSE Frequency(Hz) = 8000000
  *PLL_M = 8
  *PLL_N = 336
  *PLL_P = 2
  *PLL_Q = 7
  * VDD(V) = 3.3
  * Main regulator output voltage = Scale1 mode
  * Flash Latency(WS) = 5
  * @param None
  * @retval None
  */
static void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;

  /* Enable Power Control clock */
  __HAL_RCC_PWR_CLK_ENABLE();

  /* 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);


  /* Enable HSE Oscillator and activate PLL with HSE as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;

  if(HAL_RCC_OscConfig( & amp;RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
     clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  if(HAL_RCC_ClockConfig( & amp;RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }

  /* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */
  if (HAL_GetREVID() == 0x1001)
  {
    /* Enable the Flash prefetch */
    __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
  }
}

/**
  * @brief UART error callbacks
  * @param UartHandle: UART handle
  * @note This example shows a simple way to report transfer error, and you can
  * add your own implementation.
  * @retval None
  */
void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle)
{
  /* Turn LED3 on: Transfer error in reception/transmission process */
  BSP_LED_On(LED3);
}


/**
  * @brief This function is executed in case of error occurrence.
  * @param None
  * @retval None
  */
static void Error_Handler(void)
{
  /* Turn LED5 on */
  BSP_LED_On(LED5);
  while(1)
  {
  }
}

#ifdef USE_FULL_ASSERT

/**
  * @brief Reports the name of the source file and the source line number
  * where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\\
", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/**
  * @}
  */

/**
  * @}
  */

Next:

syntaxbug.com © 2021 All Rights Reserved.