[DSP tutorial of STM32H7] Chapter 30 STM32H7 complex floating point FFT (support single precision and double precision)

Download address of the full version of the tutorial: http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547

Chapter 30: STM32H7 complex floating point FFT (support single precision and double precision)

This chapter mainly explains the complex floating-point FTT, which supports single precision and double precision.

catalogue

30.1 important tips for beginners

30.2 description of complex floating point FFT

30.2.1 function description

30.2.2 floating point FFT

30.3 single precision function arm_ cfft_ Use of F32 (including amplitude frequency and phase frequency)

30.3.1 function description

30.3.2 use examples and compare with Matlab

30.4 double precision function arm_ cfft_ Use of (including amplitude frequency and phase frequency)

30.4.1 function description

30.4.2 use examples and compare with Matlab

30.5 experimental routine description (MDK)

30.6 experimental routine description (IAR)

30.7 summary

 

 

30.1 important tips for beginners

  1. The new DSP library floating-point FFT recommends using the mixed basis function arm_cfft_f32, and the basis 2 function arm_cfft_radix2_f32 and basis 4 function arm_cfft_radix4_f32 will be discarded. The description of ARM is as follows:
Earlier releases of the library provided separate radix-2 and radix-4 algorithms that operated on floating-point data.  These functions are still provided but are deprecated.  The older functions are slower and less general than the new functions.
DSP Earlier releases of the library provided separate radix-2 and radix-4 An algorithm for computing floating-point data. These features are still available but deprecated. Compared with the new version, the function of the old version is slower and less universal

30.2 description of complex floating point FFT

30.2.1 function description

Currently, complex FFT functions support three data types: floating point, fixed-point Q31 and Q15. These FFT functions have a common feature, that is, they are used to buffer the input signal and store the output result after the conversion. The advantage of this is that it saves RAM space and does not need to set up separate caches for input and output results. Since it is a complex FFT, the input and output buffers need to store real and imaginary parts. The storage order is as follows: {real[0], imag[0], real[1], imag[1],.....................................}. Remember not to make mistakes in use.

30.2.2 floating point FFT

Floating point complex FFT uses a mixed radix algorithm, which is realized by multiple base 8 and single base 2 or base 4 algorithm. As needed, the algorithm supports lengths [16, 32, 64,..., 4096] and uses different rotation factor tables for each length.

The floating-point complex FFT uses the standard definition of FFT. The output result of FFT forward transformation will be amplified by fftLen, and will be reduced to 1/fftLen when calculating the inverse FFT transformation. This is consistent with the definition in the textbook.

The defined rotation factor and bit inversion table are already in the header file arm_ const_ structs. After it is defined in H, call the floating-point FFT function arm_cfft_f32, just include the corresponding header file. For example:

arm_cfft_f32(arm_cfft_sR_f32_len64, pSrc, 1, 1)

The above formula is to calculate a 64 point inverse FFT transform, including bit inversion. Data structure arm_cfft_sR_f32_len64 can be regarded as a constant and cannot be modified in the process of calculation. The same data structure can also be used for FFT forward transform and inverse transform of mixed basis.

The version of floating-point complex FFT function released earlier includes base 2 and base 4, but it is not recommended to use it again. Now all use arm_cfft_f32 replaced.

30.3 single precision function arm_ cfft_ Use of F32 (including amplitude frequency and phase frequency)

30.3.1 function description

Function prototype:

void arm_cfft_f32(
  const arm_cfft_instance_f32 * S,
        float32_t * p1,
        uint8_t ifftFlag,
        uint8_t bitReverseFlag)

Function Description:

This function is used for single precision floating-point complex FFT.

Function parameters:

1. The first parameter is the encapsulated floating-point FFT instantiation. The supported parameters are as follows:

  •   arm_cfft_sR_f32_len16, 16 point FFT
  •   arm_cfft_sR_f32_len32, 32 point FFT
  •   arm_cfft_sR_f32_len64, 64 point FFT
  •   arm_cfft_sR_f32_len128128 point FFT
  •   arm_cfft_sR_f32_len256256 point FFT
  •   arm_cfft_sR_f32_len512512 point FFT
  •   arm_cfft_sR_f32_len10241024 point FFT
  •   arm_cfft_sR_f32_len20482048 point FFT
  •   arm_cfft_sR_f32_len40964096 point FFT

2. The second parameter is the complex address. The storage order is real part, imaginary part, real part, imaginary part, and so on.

3. The third parameter is used to set forward transformation and inverse transformation. ifftFlag=0 means forward transformation and ifftFlag=1 means inverse transformation.

4. The fourth parameter is used to set the output bit inversion. bitReverseFlag=1 means enable and bitReverseFlag=0 means disable.

30.3.2 use examples and compare with Matlab

Next, run this function on the development board and calculate the corresponding amplitude and frequency, and then compare it with the results calculated by Matlab.

/*
*********************************************************************************************************
*    Function name: arm_cfft_f32_app
*    Function Description: call the function arm_cfft_f32 calculate amplitude frequency and phase frequency
*    Formal parameter: None
*    Return value: None
*********************************************************************************************************
*/
static void arm_cfft_f32_app(void)
{
    uint16_t i;
    
    ifftFlag = 0; 
    doBitReverse = 1; 
    
    /* According to real part, imaginary part, real part, imaginary part Store data in order */
    for(i=0; i<TEST_LENGTH_SAMPLES; i++)
    {
        /* The waveform is composed of DC component, 50Hz sine wave, waveform sampling rate of 1024 and initial phase of 60 ° */
        testInput_f32[i*2] = 1 + cos(2*3.1415926f*50*i/1024 + 3.1415926f/3);
        testInput_f32[i*2+1] = 0;
    }
    
    /* CFFT Transform */ 
    arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32, ifftFlag, doBitReverse);

    /* Solving modulus  */ 
    arm_cmplx_mag_f32(testInput_f32, testOutput_f32, TEST_LENGTH_SAMPLES);
    

    printf("=========================================\r\n");    
    
    /* Phase frequency */
    PowerPhaseRadians_f32(testInput_f32, Phase_f32, TEST_LENGTH_SAMPLES, 0.5f);
    
    /* Modulus of serial port printing solution */
    for(i=0; i<TEST_LENGTH_SAMPLES; i++)
    {
        printf("%f, %f\r\n", testOutput_f32[i], Phase_f32[i]);
    }    
}

Run function arm_cfft_f32_app can print out the calculated modulus and phase angle through the serial port. Next, we will compare the modulus and phase angle calculated by Matlab with arm_cfft_f32 calculated for comparison.

Before comparison, you need to load the data printed by the serial port into Matlab and name the array sampledata. The loading method has been explained in the summary of 13.6 in Chapter 13 of the previous tutorial, which will not be repeated here. The code running in MATLAB is as follows:

Fs = 1024;               % sampling rate
N  = 1024;               % Sampling points
n  = 0:N-1;              % Sampling sequence
t  = 0:1/Fs:1-1/Fs;      % time series
f = n * Fs / N;          %Real frequency

%The waveform is composed of DC component, 50 Hz Sine wave sine wave composition
x = 1 + cos(2*pi*50*t + pi/3)   ;  
y = fft(x, N);               %Make changes to the original signal FFT Transform
Mag = abs(y);

subplot(2,2,1);
plot(f, Mag); 
title('Matlab Calculate amplitude frequency response');
xlabel('frequency');
ylabel('assignment');

subplot(2,2,2);
realvalue = real(y);
imagvalue = imag(y);
plot(f, atan2(imagvalue, realvalue)*180/pi.*(Mag>=200)); 
title('Matlab Calculate phase frequency response');
xlabel('frequency');
ylabel('phase angle');

subplot(2,2,3);
plot(f, sampledata1);  %draw STM32 Calculated amplitude frequency response
title('STM32 Calculate amplitude frequency response');
xlabel('frequency');
ylabel('assignment');

subplot(2,2,4);
plot(f, sampledata2);   %draw STM32 Calculated phase frequency response
title('STM32 Calculate phase frequency response');
xlabel('frequency');
ylabel('phase angle');

The output results after running Matlab are as follows:

From the above comparison results, it can be seen that Matlab and function arm_ cfft_ The result of F32 calculation is basically constant. The amplitude obtained from the amplitude frequency response and the initial phase angle obtained from the phase frequency response are all OK.

30.4 double precision function arm_ cfft_ Use of (including amplitude frequency and phase frequency)

30.4.1 function description

Function prototype:

void arm_cfft_f64(
  const arm_cfft_instance_f64 * S,
        float64_t * p1,
        uint8_t ifftFlag,
        uint8_t bitReverseFlag)

Function Description:

This function is used for double precision floating-point complex FFT.

Function parameters:

1. The first parameter is the encapsulated floating-point FFT instantiation. The supported parameters are as follows:

  •   arm_cfft_sR_f64_len16, 16 point FFT
  •   arm_cfft_sR_f64_len32, 32 point FFT
  •   arm_cfft_sR_f64_len64, 64 point FFT
  •   arm_cfft_sR_f64_len128128 point FFT
  •   arm_cfft_sR_f64_len256256 point FFT
  •   arm_cfft_sR_f64_len512512 point FFT
  •   arm_cfft_sR_f64_len10241024 point FFT
  •   arm_cfft_sR_f64_len20482048 point FFT
  •   arm_cfft_sR_f64_len40964096 point FFT

2. The second parameter is the complex address. The storage order is real part, imaginary part, real part, imaginary part, and so on.

3. The third parameter is used to set forward transformation and inverse transformation. ifftFlag=0 means forward transformation and ifftFlag=1 means inverse transformation.

4. The fourth parameter is used to set the output bit inversion. bitReverseFlag=1 means enable and bitReverseFlag=0 means disable.

30.4.2 use examples and compare with Matlab

Next, run this function on the development board and calculate the corresponding amplitude and frequency, and then compare it with the results calculated by Matlab.

/*
*********************************************************************************************************
*    Function name: arm_cfft_f64_app
*    Function Description: call the function arm_ cfft_ Calculate amplitude frequency and phase frequency
*    Formal parameter: None
*    Return value: None
*********************************************************************************************************
*/
static void arm_cfft_f64_app(void)
{
    uint16_t i;
    float64_t lX,lY;
    
    ifftFlag = 0; 
    doBitReverse = 1; 
    
    /* According to real part, imaginary part, real part, imaginary part Store data in order */
    for(i=0; i<TEST_LENGTH_SAMPLES; i++)
    {
        /* The waveform is composed of DC component, 50Hz sine wave, waveform sampling rate of 1024 and initial phase of 60 ° */
        testInput_f64[i*2] = 1 + cos(2*3.1415926*50*i/1024 + 3.1415926/3);
        testInput_f64[i*2+1] = 0;
    }
    
    /* CFFT Transform */ 
    arm_cfft_f64(&arm_cfft_sR_f64_len1024, testInput_f64, ifftFlag, doBitReverse);

    /* Solving modulus  */ 
    for (i =0; i < TEST_LENGTH_SAMPLES; i++)
    {
         lX = testInput_f64[2*i];            /* real part*/
        lY = testInput_f64[2*i+1];          /* imaginary part */  
        testOutput_f64[i] = sqrt(lX*lX+ lY*lY);   /* Seeking module */
    }
    
    printf("=========================================\r\n");    
    
    /* Phase frequency */
    PowerPhaseRadians_f64(testInput_f64, Phase_f64, TEST_LENGTH_SAMPLES, 0.5);
    
    
    /* Modulus of serial port printing solution */
    for(i=0; i<TEST_LENGTH_SAMPLES; i++)
    {
        printf("%.11f, %.11f\r\n", testOutput_f64[i], Phase_f64[i]);
    }    
    
}

Run function arm_cfft_f64_app can print out the calculated modulus and phase angle through the serial port. Next, we will compare the modulus and phase angle calculated by Matlab with arm_ cfft_ Compare the calculated results.

Before comparison, you need to load the data printed by the serial port into Matlab and name the array sampledata. The loading method has been explained in the summary of 13.6 in Chapter 13 of the previous tutorial, which will not be repeated here. The code running in MATLAB is as follows:

Fs = 1024;               % sampling rate
N  = 1024;               % Sampling points
n  = 0:N-1;              % Sampling sequence
t  = 0:1/Fs:1-1/Fs;      % time series
f = n * Fs / N;          %Real frequency

%The waveform is composed of DC component, 50 Hz Sine wave sine wave composition
x = 1 + cos(2*pi*50*t + pi/3)   ;  
y = fft(x, N);               %Make changes to the original signal FFT Transform
Mag = abs(y);

subplot(2,2,1);
plot(f, Mag); 
title('Matlab Calculate amplitude frequency response');
xlabel('frequency');
ylabel('assignment');

subplot(2,2,2);
realvalue = real(y);
imagvalue = imag(y);
plot(f, atan2(imagvalue, realvalue)*180/pi.*(Mag>=200)); 
title('Matlab Calculate phase frequency response');
xlabel('frequency');
ylabel('phase angle');

subplot(2,2,3);
plot(f, sampledata1);  %draw STM32 Calculated amplitude frequency response
title('STM32 Calculate amplitude frequency response');
xlabel('frequency');
ylabel('assignment');

subplot(2,2,4);
plot(f, sampledata2);   %draw STM32 Calculated phase frequency response
title('STM32 Calculate phase frequency response');
xlabel('frequency');
ylabel('phase angle');

The output results after running Matlab are as follows:

From the above comparison results, it can be seen that Matlab and function arm_ cfft_ The result of the calculation is basically constant. The amplitude obtained from the amplitude frequency response and the initial phase angle obtained from the phase frequency response are all OK.

30.5 experimental routine description (MDK)

Supporting examples:

V7-220_ Complex floating point FTT (support single precision and double precision)

Purpose of the experiment:

  1. Learn complex floating-point FFT and support single precision floating-point and double precision floating-point

Experiment content:

  1. Start an automatic software reinstallation timer and turn LED2 every 100ms.
  2. Press the key K1, and the serial port will print the amplitude frequency response and phase frequency response of 1024 point complex single precision FFT.
  3. Press the key K2, and the serial port will print the amplitude frequency response and phase frequency response of 1024 point complex double precision FFT.

Precautions for using AC6

Pay special attention to the issues in Annex section C

Information printed by serial port after power on:

Baud rate 115200, data bit 8, parity bit none, stop bit 1.

RTT printing information:

Programming:

System stack size allocation:

DTCM for RAM space:

Hardware peripheral initialization

The initialization of hardware peripherals is in BSP C file realization:

/*
*********************************************************************************************************
*    Function name: bsp_Init
*    Function Description: initialize all hardware devices. This function configures CPU registers and peripheral registers and initializes some global variables. It only needs to be called once
*    Formal parameter: None
*    Return value: None
*********************************************************************************************************
*/
void bsp_Init(void)
{
    /* Configure MPU */
    MPU_Config();
    
    /* Enable L1 Cache */
    CPU_CACHE_Enable();

    /* 
       STM32H7xx HAL When the library is initialized, the system still uses the 64MHz provided by H7. HSI clock:
       - Call function HAL_InitTick, initialize tick clock interrupt for 1ms.
       - Set the NVIC priority group to 4.
     */
    HAL_Init();

    /* 
       Configure the system clock to 400MHz
       - Switch to HSE.
       - This function updates the global variable systemcorelock and reconfigures HAL_InitTick. 
    */
    SystemClock_Config();

    /* 
       Event Recorder: 
       - It can be used for code execution time measurement, mdk5 25 and above, not IAR.
       - It is not enabled by default. If you want to enable this option, please refer to Chapter 8 of the V7 development board user manual
    */    
#if Enable_EventRecorder == 1  
    /* Initialize the EventRecorder and turn it on */
    EventRecorderInitialize(EventRecordAll, 1U);
    EventRecorderStart();
#endif
    
    bsp_InitKey();        /* The key initialization should be placed before the tick timer, because the button detection is scanned by the tick timer */
    bsp_InitTimer();      /* Initialize tick timer */
    bsp_InitUart();    /* Initialize serial port */
    bsp_InitExtIO();    /* Initialize FMC bus 74HC574 extension IO Must be in BSP_ Execute before initled() */    
    bsp_InitLed();        /* Initialize LED */    
}

MPU configuration and Cache configuration:

Both data Cache and instruction Cache are enabled. The AXI SRAM area is configured (AXI SRAM is not used in this example) and the extended IO area of FMC.

/*
*********************************************************************************************************
*    Function name: MPU_Config
*    Function Description: configure MPU
*    Formal parameter: None
*    Return value: None
*********************************************************************************************************
*/
static void MPU_Config( void )
{
    MPU_Region_InitTypeDef MPU_InitStruct;

    /* Disable MPU */
    HAL_MPU_Disable();

    /* Configure the MPU attribute of AXI SRAM as Write back, Read allocate, Write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x24000000;
    MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    
    /* Configure the MPU attribute of FMC extension IO as Device or Strongly Ordered */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x60000000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_64KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;    
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER1;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
    
    HAL_MPU_ConfigRegion(&MPU_InitStruct);

    /*Enable MPU */
    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

/*
*********************************************************************************************************
*    Function name: CPU_CACHE_Enable
*    Function Description: enable L1 Cache
*    Formal parameter: None
*    Return value: None
*********************************************************************************************************
*/
static void CPU_CACHE_Enable(void)
{
    /* Enable I-Cache */
    SCB_EnableICache();

    /* Enable D-Cache */
    SCB_EnableDCache();
}

Main functions:

The main program realizes the following operations:

  • Start an automatic software reinstallation timer and turn LED2 every 100ms.
  • Press the key K1, and the serial port will print the amplitude frequency response and phase frequency response of 1024 point complex single precision FFT.
  • Press the key K2, and the serial port will print the amplitude frequency response and phase frequency response of 1024 point complex double precision FFT.
/*
*********************************************************************************************************
*    Function name: main
*    Function Description: c program entry
*    Formal parameter: None
*    Return value: error code (no processing required)
*********************************************************************************************************
*/
int main(void)
{
    uint8_t ucKeyCode;        /* Key code */
    

    bsp_Init();        /* Hardware initialization */
    PrintfLogo();    /* Print routine information to serial port 1 */

    PrintfHelp();    /* Print operation tips */
    

    bsp_StartAutoTimer(0, 100);    /* Start a 100ms timer for automatic reassembly */

    /* Enter the main program loop body */
    while (1)
    {
        bsp_Idle();        /* This function is in BSP C documents. Users can modify this function to realize CPU sleep and dog feeding */
        

        if (bsp_CheckTimer(0))    /* Judge timer timeout */
        {
            /* Come in every 100ms */
            bsp_LedToggle(4);    /* Flip the status of LED2 */   
        }
        
        ucKeyCode = bsp_GetKey();    /* Read the key value and return to key when no key is pressed_ NONE = 0 */
        if (ucKeyCode != KEY_NONE)
        {
            switch (ucKeyCode)
            {
                case KEY_DOWN_K1:            /* K1 Key press */
                    arm_cfft_f32_app();
                    break;
                
                case KEY_DOWN_K2:            /* K2 Key press */
                    arm_cfft_f64_app();
                    break;
                
                    
                default:
                    /* Other key values are not processed */
                    break;
            }
        }

    }
}

30.6 experimental routine description (IAR)

Supporting examples:

V7-220_ Complex floating point FTT (support single precision and double precision)

Purpose of the experiment:

  1. Learn complex floating-point FFT and support single precision floating-point and double precision floating-point

Experiment content:

  1. Start an automatic software reinstallation timer and turn LED2 every 100ms.
  2. Press the key K1, and the serial port will print the amplitude frequency response and phase frequency response of 1024 point complex single precision FFT.
  3. Press the key K2, and the serial port will print the amplitude frequency response and phase frequency response of 1024 point complex double precision FFT.

Precautions for using AC6

Pay special attention to the issues in Annex section C

Information printed by serial port after power on:

Baud rate 115200, data bit 8, parity bit none, stop bit 1.

RTT printing information:

Programming:

System stack size allocation:

DTCM for RAM space:

Hardware peripheral initialization

The initialization of hardware peripherals is in BSP C file realization:

/*
*********************************************************************************************************
*    Function name: bsp_Init
*    Function Description: initialize all hardware devices. This function configures CPU registers and peripheral registers and initializes some global variables. It only needs to be called once
*    Formal parameter: None
*    Return value: None
*********************************************************************************************************
*/
void bsp_Init(void)
{
    /* Configure MPU */
    MPU_Config();
    
    /* Enable L1 Cache */
    CPU_CACHE_Enable();

    /* 
       STM32H7xx HAL When the library is initialized, the system still uses the 64MHz provided by H7. HSI clock:
       - Call function HAL_InitTick, initialize tick clock interrupt for 1ms.
       - Set the NVIC priority group to 4.
     */
    HAL_Init();

    /* 
       Configure the system clock to 400MHz
       - Switch to HSE.
       - This function updates the global variable systemcorelock and reconfigures HAL_InitTick. 
    */
    SystemClock_Config();

    /* 
       Event Recorder: 
       - It can be used for code execution time measurement, mdk5 25 and above, not IAR.
       - It is not enabled by default. If you want to enable this option, please refer to Chapter 8 of the V7 development board user manual
    */    
#if Enable_EventRecorder == 1  
    /* Initialize the EventRecorder and turn it on */
    EventRecorderInitialize(EventRecordAll, 1U);
    EventRecorderStart();
#endif
    
    bsp_InitKey();        /* The key initialization should be placed before the tick timer, because the button detection is scanned by the tick timer */
    bsp_InitTimer();      /* Initialize tick timer */
    bsp_InitUart();    /* Initialize serial port */
    bsp_InitExtIO();    /* Initialize FMC bus 74HC574 extension IO Must be in BSP_ Execute before initled() */    
    bsp_InitLed();        /* Initialize LED */    
}

MPU configuration and Cache configuration:

Both data Cache and instruction Cache are enabled. The AXI SRAM area is configured (AXI SRAM is not used in this example) and the extended IO area of FMC.

/*
*********************************************************************************************************
*    Function name: MPU_Config
*    Function Description: configure MPU
*    Formal parameter: None
*    Return value: None
*********************************************************************************************************
*/
static void MPU_Config( void )
{
    MPU_Region_InitTypeDef MPU_InitStruct;

    /* Disable MPU */
    HAL_MPU_Disable();

    /* Configure the MPU attribute of AXI SRAM as Write back, Read allocate, Write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x24000000;
    MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    
    /* Configure the MPU attribute of FMC extension IO as Device or Strongly Ordered */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x60000000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_64KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;    
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER1;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
    
    HAL_MPU_ConfigRegion(&MPU_InitStruct);

    /*Enable MPU */
    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

/*
*********************************************************************************************************
*    Function name: CPU_CACHE_Enable
*    Function Description: enable L1 Cache
*    Formal parameter: None
*    Return value: None
*********************************************************************************************************
*/
static void CPU_CACHE_Enable(void)
{
    /* Enable I-Cache */
    SCB_EnableICache();

    /* Enable D-Cache */
    SCB_EnableDCache();
}

Main functions:

The main program realizes the following operations:

  • Start an automatic software reinstallation timer and turn LED2 every 100ms.
  • Press the key K1, and the serial port will print the amplitude frequency response and phase frequency response of 1024 point complex single precision FFT.
  • Press the key K2, and the serial port will print the amplitude frequency response and phase frequency response of 1024 point complex double precision FFT.
/*
*********************************************************************************************************
*    Function name: main
*    Function Description: c program entry
*    Formal parameter: None
*    Return value: error code (no processing required)
*********************************************************************************************************
*/
int main(void)
{
    uint8_t ucKeyCode;        /* Key code */
    

    bsp_Init();        /* Hardware initialization */
    PrintfLogo();    /* Print routine information to serial port 1 */

    PrintfHelp();    /* Print operation tips */
    

    bsp_StartAutoTimer(0, 100);    /* Start a 100ms timer for automatic reassembly */

    /* Enter the main program loop body */
    while (1)
    {
        bsp_Idle();        /* This function is in BSP C documents. Users can modify this function to realize CPU sleep and dog feeding */
        

        if (bsp_CheckTimer(0))    /* Judge timer timeout */
        {
            /* Come in every 100ms */
            bsp_LedToggle(4);    /* Flip the status of LED2 */   
        }
        
        ucKeyCode = bsp_GetKey();    /* Read the key value and return to key when no key is pressed_ NONE = 0 */
        if (ucKeyCode != KEY_NONE)
        {
            switch (ucKeyCode)
            {
                case KEY_DOWN_K1:            /* K1 Key press */
                    arm_cfft_f32_app();
                    break;
                
                case KEY_DOWN_K2:            /* K2 Key press */
                    arm_cfft_f64_app();
                    break;
                
                    
                default:
                    /* Other key values are not processed */
                    break;
            }
        }

    }
}

30.7 summary

This chapter is designed to realize FFT. Those who are interested can have an in-depth understanding of the implementation of the source code.

 

Keywords: stm32 dsp Flash EMWIN

Added by slyte33 on Mon, 31 Jan 2022 00:14:26 +0200