[DSP tutorial of STM32H7] Chapter 50 the spline interpolation of STM32H7 is realized, and the waveform fitting is smooth

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

Chapter 50        The spline interpolation of STM32H7 is realized, and the waveform fitting is smooth

This chapter explains spline interpolation, which is mainly used for waveform fitting and smooth transition.

catalogue

50.1 important tips for beginners

50.2 introduction to spline interpolation

50.3 implementation of spline interpolation

50.3.1 function arm_spline_init_f32

50.3.2 function arm_spline_f32

50.3.3 key points of using spline interpolation function

50.3.4 natural spline interpolation test

50.3.5 parabolic spline interpolation test

50.4 experimental routine description (MDK)

50.5 experimental routine description (IAR)

50.6 summary

50.1 important tips for beginners

DSP library supports spline interpolation, bilinear interpolation and linear interpolation. Here we mainly introduce the implementation of spline interpolation.

50.2 introduction to spline interpolation

In the numerical analysis of mathematics, spline is a special function, which is defined by polynomial segments. The English word spline comes from the deformable spline tool, which is used to draw smooth shapes in shipbuilding and engineering drawing. The Chinese mainland was once referred to as the "tooth function" in the early days. Later, it got its name because of the word "setting out" in engineering terminology. In interpolation problems, spline interpolation is usually better than polynomial interpolation. Using low-order spline interpolation can produce the same effect as high-order polynomial interpolation, and can avoid the numerical instability called Runge phenomenon. Moreover, low order spline interpolation also has the important property of "convexity preserving". In computer aided design and computer graphics of computer science, splines usually refer to piecewise defined polynomial parametric curves. Because of its simple structure, convenient use and accurate fitting, and can approximate the complex shapes in curve fitting and interactive curve design, spline is a common representation method of curves in these fields

50.3 implementation of spline interpolation

Spline interpolation is mainly realized by the following two functions.

50.3.1 function arm_spline_init_f32

Function prototype:

void arm_spline_init_f32(
        arm_spline_instance_f32 * S,
        arm_spline_type type,
  const float32_t * x,
  const float32_t * y,
        uint32_t n, 
        float32_t * coeffs,
        float32_t * tempBuffer)

Function Description:

This function is used for spline function initialization.

Function parameters:

  •   The first parameter is arm_ spline_ instance_ Type F32 struct variable.
  •   The second parameter is spline type selection:
    •   ARM_SPLINE_NATURAL table natural spline.
    •   ARM_SPLINE_PARABOLIC_RUNOUT represents a parabolic spline.
  •   The third parameter is the x-axis coordinate value of the original data.
  •   The fourth parameter is the y-axis coordinate value of the original data.
  •   The fifth parameter is the number of original data.
  •   The sixth parameter is the interpolation factor cache.
  •   The seventh parameter is temporary buffering.

matters needing attention:

  •   The x-axis coordinate data must be incremental.
  •   The sixth parameter is the interpolation factor cache size. If the number of original data is n, the number of interpolation factors must be greater than or equal to 3 * (n-1).
  •   The seventh parameter is the temporary buffer size. If the number of original data is n, the temporary buffer size must be greater than or equal to 2*n - 1

50.3.2 function arm_spline_f32

Function prototype:

void arm_spline_f32(
        arm_spline_instance_f32 * S, 
  const float32_t * xq,
        float32_t * pDst,
        uint32_t blockSize)

Function Description:

This function is used for spline interpolation implementation.

Function parameters:

  •   The first parameter is arm_ spline_ instance_ Type F32 struct variable.
  •   The second parameter is the interpolated x-axis coordinate value, which needs to be specified by the user. Note that the coordinate value must be increasing.
  •   The third parameter is the y-axis value output after interpolation calculation
  •   The fourth parameter is the number of data outputs

50.3.3 key points of using spline interpolation function

The main function of spline interpolation is to make the waveform smoother. For example, a frame has 128 points and the step size is 8 pixels. We can realize the waveform with a step size of 11024 points through interpolation. In essence, your total step size cannot be changed. We all have 1024 here. This cannot be changed. If you do interpolation on this basis, the effect will come out.

This understanding is very important, otherwise the interpolation algorithm cannot be used normally.

50.3.4 natural spline interpolation test

The implementation of spline test code is as follows:

#define INPUT_TEST_LENGTH_SAMPLES  	 128 / * number of input data*/
#define OUT_TEST_LENGTH_SAMPLES    	 1024 / * number of output data*/

#define SpineTab OUT_TEST_LENGTH_SAMPLES/INPUT_TEST_LENGTH_SAMPLES / * the 8 coordinate values at the end of interpolation are not used*/


float32_t xn[INPUT_TEST_LENGTH_SAMPLES];   /* Input data x-axis coordinates */
float32_t yn[INPUT_TEST_LENGTH_SAMPLES];   /* Input data y-axis coordinates */

float32_t coeffs[3*(INPUT_TEST_LENGTH_SAMPLES - 1)];     /* Interpolation coefficient buffer */  
float32_t tempBuffer[2 * INPUT_TEST_LENGTH_SAMPLES - 1]; /* Interpolated temporary buffer */  

float32_t xnpos[OUT_TEST_LENGTH_SAMPLES];  /* X-axis coordinate value after interpolation calculation */
float32_t ynpos[OUT_TEST_LENGTH_SAMPLES];  /* Y-axis value after interpolation calculation */

/*
*********************************************************************************************************
*	Function name: main
*	Function Description: c program entry
*	Formal parameters: None
*	Return value: error code (no processing required)
*********************************************************************************************************
*/
int main(void)
{
	uint32_t i;
	uint32_t idx2;
	uint8_t ucKeyCode;	
	arm_spline_instance_f32 S;
	

	bsp_Init();		/* Hardware initialization */
	PrintfLogo();	/* Print information such as routine name and version */
	PrintfHelp();	/* Print operation tips */
	
	bsp_StartAutoTimer(0, 100);	/* Start a 100ms automatic reassembly timer */
	
	
	/* Original x-axis value and y-axis value */
	for(i=0; i<INPUT_TEST_LENGTH_SAMPLES; i++)
	{
		xn[i] = i*SpineTab;
		yn[i] = 1 + cos(2*3.1415926*50*i/256 + 3.1415926/3);
	}
	
	/* The X-axis coordinate value after interpolation needs to be set by the user */
	for(i=0; i<OUT_TEST_LENGTH_SAMPLES; i++)
	{
		xnpos[i] = i;
	}
	
	while (1)
	{
		bsp_Idle();		/* This function is in the bsp.c file. Users can modify this function to realize CPU sleep and dog feeding */

		/* Judge timer timeout */
		if (bsp_CheckTimer(0))	
		{
			/* Come in every 100ms */  
			bsp_LedToggle(2);
		}

		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 Press the key to natural spline interpolation */
					/* Spline initialization */
					arm_spline_init_f32(&S,
										ARM_SPLINE_NATURAL ,
										xn,
										yn,
										INPUT_TEST_LENGTH_SAMPLES,
										coeffs,
										tempBuffer);
					/* Spline calculation */
					arm_spline_f32	(&S,
									 xnpos,
									 ynpos,
									 OUT_TEST_LENGTH_SAMPLES);

				
					/* Printout */
					idx2 = 0;
					for (i = 0; i < OUT_TEST_LENGTH_SAMPLES-SpineTab; i++)
					{	
							if ((i % SpineTab) == 0)
							{
									printf("%f,%f\r\n", ynpos[i], yn[idx2++]);
							}
							else
							{
									printf("%f,\r\n", ynpos[i]);
							}
					}
					break;
				
				default:
					/* Other key values are not processed */
					break;
			}
		}
	}
}

Several key points in the code:

  •   The original coordinate arrays xn and yn are 128 groups, while we generate 1024 groups of xnpos and ynpos through interpolation. The initial value of 1024 groups of xnpos needs to be set by the user, which cannot be ignored.
  •   Function arm_spline_init_f32 is used for spline function initialization. Note that this function is mainly used to operate the original data. Arm for natural spline interpolation_ SPLINE_ NATURAL.
  •   Function arm_spline_f32 is used for spline function calculation.

The actual output effect is as follows:

 

50.3.5 parabolic spline interpolation test

The implementation of spline test code is as follows:

#define INPUT_TEST_LENGTH_SAMPLES  	 128 / * number of input data*/
#define OUT_TEST_LENGTH_SAMPLES    	 1024 / * number of output data*/

#define SpineTab OUT_TEST_LENGTH_SAMPLES/INPUT_TEST_LENGTH_SAMPLES / * the 8 coordinate values at the end of interpolation are not used*/


float32_t xn[INPUT_TEST_LENGTH_SAMPLES];   /* Input data x-axis coordinates */
float32_t yn[INPUT_TEST_LENGTH_SAMPLES];   /* Input data y-axis coordinates */

float32_t coeffs[3*(INPUT_TEST_LENGTH_SAMPLES - 1)];     /* Interpolation coefficient buffer */  
float32_t tempBuffer[2 * INPUT_TEST_LENGTH_SAMPLES - 1]; /* Interpolated temporary buffer */  

float32_t xnpos[OUT_TEST_LENGTH_SAMPLES];  /* X-axis coordinate value after interpolation calculation */
float32_t ynpos[OUT_TEST_LENGTH_SAMPLES];  /* Y-axis value after interpolation calculation */

/*
*********************************************************************************************************
*	Function name: main
*	Function Description: c program entry
*	Formal parameters: None
*	Return value: error code (no processing required)
*********************************************************************************************************
*/
int main(void)
{
	uint32_t i;
	uint32_t idx2;
	uint8_t ucKeyCode;	
	arm_spline_instance_f32 S;
	

	bsp_Init();		/* Hardware initialization */
	PrintfLogo();	/* Print information such as routine name and version */
	PrintfHelp();	/* Print operation tips */
	
	bsp_StartAutoTimer(0, 100);	/* Start a 100ms automatic reassembly timer */
	
	
	/* Original x-axis value and y-axis value */
	for(i=0; i<INPUT_TEST_LENGTH_SAMPLES; i++)
	{
		xn[i] = i*SpineTab;
		yn[i] = 1 + cos(2*3.1415926*50*i/256 + 3.1415926/3);
	}
	
	/* The X-axis coordinate value after interpolation needs to be set by the user */
	for(i=0; i<OUT_TEST_LENGTH_SAMPLES; i++)
	{
		xnpos[i] = i;
	}
	
	while (1)
	{
		bsp_Idle();		/* This function is in the bsp.c file. Users can modify this function to realize CPU sleep and dog feeding */

		/* Judge timer timeout */
		if (bsp_CheckTimer(0))	
		{
			/* Come in every 100ms */  
			bsp_LedToggle(2);
		}

		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_K2:			/* K2 Key pressed, parabola spline interpolation */
					/* Spline initialization */
					arm_spline_init_f32(&S,
										ARM_SPLINE_PARABOLIC_RUNOUT , 
										xn,
										yn,
										INPUT_TEST_LENGTH_SAMPLES,
										coeffs,
										tempBuffer);
					/* Spline calculation */
					arm_spline_f32	(&S,
									 xnpos,
									 ynpos,
									 OUT_TEST_LENGTH_SAMPLES);

				
					/* Printout */
					idx2 = 0;
					for (i = 0; i < OUT_TEST_LENGTH_SAMPLES-SpineTab; i++)
					{	
							if ((i % SpineTab) == 0)
							{
									printf("%f,%f\r\n", ynpos[i], yn[idx2++]);
							}
							else
							{
									printf("%f,\r\n", ynpos[i]);
							}
					}
					break;
				
				default:
					/* Other key values are not processed */
					break;
			}
		}
	}
}

Several key points in the code:

  •   The original coordinate arrays xn and yn are 128 groups, while we generate 1024 groups of xnpos and ynpos through interpolation. The initial value of 1024 groups of xnpos needs to be set by the user, which cannot be ignored.
  •   Function arm_spline_init_f32 is used for spline function initialization. Note that this function is mainly used to operate the original data. Arm for parabolic spline interpolation_ SPLINE_ PARABOLIC_ RUNOUT.
  •   Function arm_spline_f32 is used for spline function calculation.

The actual output effect is as follows:

 

50.4 experimental routine description (MDK)

Supporting examples:

V7-235_ Spline interpolation, waveform fitting, smooth wire

Purpose of the experiment:

  1. Learn the implementation of spline interpolation.

Experiment content:

  1. Start an automatic software reinstallation timer and flip LED2 every 100ms.
  2. Press the K1 key to perform natural spline interpolation test.
  3. Press the K2 key to perform parabolic interpolation test.

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 implemented in bsp.c file:

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

	/* 
       STM32H7xx HAL During library initialization, 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. It is only supported by MDK5.25 and above, but 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. It 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 parameters: 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 to turn off read Cache and write Cache */
	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_NOT _BUFFERABLE;
	MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT _CACHEABLE;
	MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
	MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
	MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
	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 parameters: 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 flip LED2 every 100ms.
  •   Press the K1 key to perform natural spline interpolation test.
  •   Press the K2 key to perform parabolic interpolation test.
/*
*********************************************************************************************************
*	Function name: main
*	Function Description: c program entry
*	Formal parameters: None
*	Return value: error code (no processing required)
*********************************************************************************************************
*/
int main(void)
{
	uint32_t i;
	uint32_t idx2;
	uint8_t ucKeyCode;	
	arm_spline_instance_f32 S;
	

	bsp_Init();		/* Hardware initialization */
	PrintfLogo();	/* Print information such as routine name and version */
	PrintfHelp();	/* Print operation tips */
	
	bsp_StartAutoTimer(0, 100);	/* Start a 100ms automatic reassembly timer */
	
	
	/* Original x-axis value and y-axis value */
	for(i=0; i<INPUT_TEST_LENGTH_SAMPLES; i++)
	{
		xn[i] = i*SpineTab;
		yn[i] = 1 + cos(2*3.1415926*50*i/256 + 3.1415926/3);
	}
	
	/* The X-axis coordinate value after interpolation needs to be set by the user */
	for(i=0; i<OUT_TEST_LENGTH_SAMPLES; i++)
	{
		xnpos[i] = i;
	}
	
	while (1)
	{
		bsp_Idle();		/* This function is in the bsp.c file. Users can modify this function to realize CPU sleep and dog feeding */

		/* Judge timer timeout */
		if (bsp_CheckTimer(0))	
		{
			/* Come in every 100ms */  
			bsp_LedToggle(2);
		}

		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 Press the key to natural spline interpolation */
					/* Spline initialization */
					arm_spline_init_f32(&S,
										ARM_SPLINE_NATURAL ,
										xn,
										yn,
										INPUT_TEST_LENGTH_SAMPLES,
										coeffs,
										tempBuffer);
					/* Spline calculation */
					arm_spline_f32	(&S,
									 xnpos,
									 ynpos,
									 OUT_TEST_LENGTH_SAMPLES);

				
					/* Printout */
					idx2 = 0;
					for (i = 0; i < OUT_TEST_LENGTH_SAMPLES-SpineTab; i++)
					{	
							if ((i % SpineTab) == 0)
							{
									printf("%f,%f\r\n", ynpos[i], yn[idx2++]);
							}
							else
							{
									printf("%f,\r\n", ynpos[i]);
							}
					}
					break;

				case KEY_DOWN_K2:			/* K2 Key pressed, parabola spline interpolation */
					/* Spline initialization */
					arm_spline_init_f32(&S,
										ARM_SPLINE_PARABOLIC_RUNOUT , 
										xn,
										yn,
										INPUT_TEST_LENGTH_SAMPLES,
										coeffs,
										tempBuffer);
					/* Spline calculation */
					arm_spline_f32	(&S,
									 xnpos,
									 ynpos,
									 OUT_TEST_LENGTH_SAMPLES);

				
					/* Printout */
					idx2 = 0;
					for (i = 0; i < OUT_TEST_LENGTH_SAMPLES-SpineTab; i++)
					{	
							if ((i % SpineTab) == 0)
							{
									printf("%f,%f\r\n", ynpos[i], yn[idx2++]);
							}
							else
							{
									printf("%f,\r\n", ynpos[i]);
							}
					}
					break;
				
				default:
					/* Other key values are not processed */
					break;
			}
		}
	}
}

50.5 experimental routine description (IAR)

Supporting examples:

V7-235_ Spline interpolation, waveform fitting, smooth wire

Purpose of the experiment:

  1. Learn the implementation of spline interpolation.

Experiment content:

  1. Start an automatic software reinstallation timer and flip LED2 every 100ms.
  2. Press the K1 key to perform natural spline interpolation test.
  3. Press the K2 key to perform parabolic interpolation test.

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 implemented in bsp.c file:

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

	/* 
       STM32H7xx HAL During library initialization, 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. It is only supported by MDK5.25 and above, but 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. It 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 parameters: 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 parameters: 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 flip LED2 every 100ms.
  •   Press the K1 key to perform natural spline interpolation test.
  •   Press the K2 key to perform parabolic interpolation test.
/*
*********************************************************************************************************
*	Function name: main
*	Function Description: c program entry
*	Formal parameters: None
*	Return value: error code (no processing required)
*********************************************************************************************************
*/
int main(void)
{
	uint32_t i;
	uint32_t idx2;
	uint8_t ucKeyCode;	
	arm_spline_instance_f32 S;
	

	bsp_Init();		/* Hardware initialization */
	PrintfLogo();	/* Print information such as routine name and version */
	PrintfHelp();	/* Print operation tips */
	
	bsp_StartAutoTimer(0, 100);	/* Start a 100ms automatic reassembly timer */
	
	
	/* Original x-axis value and y-axis value */
	for(i=0; i<INPUT_TEST_LENGTH_SAMPLES; i++)
	{
		xn[i] = i*SpineTab;
		yn[i] = 1 + cos(2*3.1415926*50*i/256 + 3.1415926/3);
	}
	
	/* The X-axis coordinate value after interpolation needs to be set by the user */
	for(i=0; i<OUT_TEST_LENGTH_SAMPLES; i++)
	{
		xnpos[i] = i;
	}
	
	while (1)
	{
		bsp_Idle();		/* This function is in the bsp.c file. Users can modify this function to realize CPU sleep and dog feeding */

		/* Judge timer timeout */
		if (bsp_CheckTimer(0))	
		{
			/* Come in every 100ms */  
			bsp_LedToggle(2);
		}

		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 Press the key to natural spline interpolation */
					/* Spline initialization */
					arm_spline_init_f32(&S,
										ARM_SPLINE_NATURAL ,
										xn,
										yn,
										INPUT_TEST_LENGTH_SAMPLES,
										coeffs,
										tempBuffer);
					/* Spline calculation */
					arm_spline_f32	(&S,
									 xnpos,
									 ynpos,
									 OUT_TEST_LENGTH_SAMPLES);

				
					/* Printout */
					idx2 = 0;
					for (i = 0; i < OUT_TEST_LENGTH_SAMPLES-SpineTab; i++)
					{	
							if ((i % SpineTab) == 0)
							{
									printf("%f,%f\r\n", ynpos[i], yn[idx2++]);
							}
							else
							{
									printf("%f,\r\n", ynpos[i]);
							}
					}
					break;

				case KEY_DOWN_K2:			/* K2 Key pressed, parabola spline interpolation */
					/* Spline initialization */
					arm_spline_init_f32(&S,
										ARM_SPLINE_PARABOLIC_RUNOUT , 
										xn,
										yn,
										INPUT_TEST_LENGTH_SAMPLES,
										coeffs,
										tempBuffer);
					/* Spline calculation */
					arm_spline_f32	(&S,
									 xnpos,
									 ynpos,
									 OUT_TEST_LENGTH_SAMPLES);

				
					/* Printout */
					idx2 = 0;
					for (i = 0; i < OUT_TEST_LENGTH_SAMPLES-SpineTab; i++)
					{	
							if ((i % SpineTab) == 0)
							{
									printf("%f,%f\r\n", ynpos[i], yn[idx2++]);
							}
							else
							{
									printf("%f,\r\n", ynpos[i]);
							}
					}
					break;
				
				default:
					/* Other key values are not processed */
					break;
			}
		}
	}
}

50.6 summary

This chapter mainly explains the implementation of spline interpolation. The actual project is more practical. If you are interested, you can have an in-depth understanding of the source code.

Tags: stm32 ARM

Posted on Mon, 08 Nov 2021 10:22:50 -0500 by rainbowsntoffee