cancel
Showing results for 
Search instead for 
Did you mean: 

Incorrect SPI clock frequency

Sirac
Associate III

Hello,

I'm trying to get data from an external ADC (18bits) with an STM32l476RG nucleo board. There is a lot of overhead and I will improve it later but even the frequency clock is not fast enough.

I don't understand why but the maximum clock frequency I get is 16Mhz (normally 40Mhz) and th signal is very durty. The systeme core clock is 80Mhz (trough the PLL and HSE) and the SPI prescaler is 2. I use cubeMx to configure the MCU:

The system clock is configured like that:

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
 
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit;
 
    /**Initializes the CPU, AHB and APB busses clocks 
    */
  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 = 2;
  RCC_OscInitStruct.PLL.PLLN = 16;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
    /**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_PLLCLK;
  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_4) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
    /**Configure the main internal regulator output voltage 
    */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
    /**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);
}

The SPI is configure as Master and receive only :

static void MX_SPI1_Init(void)
{
 
  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
  hspi1.Init.DataSize = SPI_DATASIZE_9BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
}

Any idea about this lack of speed ?

1 ACCEPTED SOLUTION

Accepted Solutions
Sirac
Associate III

I find the mistake:

firstly RCC_ClkInitStruct.APB2CLKDivider was configured with RCC_HCLK_DIV2,

and the hardware was configured with the 8Mhz of the stlink MCO and not with the crystal....

So only my fault about this issue...

Thank you for answers.

View solution in original post

7 REPLIES 7

> the signal is very dirty

What do you exactly mean by this? How do you observe the clock? If you use a LA or oscilloscope, do you have adequate bandwidth/sampling rate?

JW

Sirac
Associate III

There is a large overshoot on the falling and rising edge. I use an 350Mhz probe correctly calibrated and an 400Mhz oscilloscope. Please, see the picture.

Try decreasing the GPIO drive (as set in GPIO_OSPEEDR).

Ringing and overshoots are high-frequency artefacts on mismatched tracks/load. Note, that a few ns edge means significant frequency content well into the GHz region.

JW

Bob S
Principal

What @Community member​ said regarding drive strength. Though often that ringing you see on the scope is caused as much by a "long" ground lead on your scope probe as it is actual ringing (even with a 350MHz bandwidth probe, or SPECIALLY with a 350MHz probe).

Also - your SystemClock_Config() sets the PLL parameters for a 32MHz clock from an 8MHz crystal. That is why you are getting a 16MHz SPI clock. Change to M=1, N=20 to get 80 MHz SYSCLK and 40MHz SPI clock

T J
Lead

16MHz 40HMhz ? are huge clocking rates...

The ringing is the ground probe length and lack of a solid ground pin. as suggested by @Bob S​ 

at those frequencies the SPI will be running warm.

did you add a resistor in series with the clock pin ? at least 27R maybe 100R would be good.

that will lower the power and clip the high energy transistion current spikes. as suggested by @Community member​ 

try to thicken the ground track significantly on the next PCB,

[ from the Scope probe, cut the ground wire down to 1cm, connect it to the SPIchip bypass capacitor ground pin for the best image]

Sirac
Associate III

Thank you for your answer.

"32MHz clock from an 8MHz"

The clock come from a 20Mhz crystal so I get 80Mhz.

I'm agree with you and I'm not really surprised with the poo quality of the signal. What I don't understand is more about the frequency. I should get something very ugly but at 40Mhz. I know it's a lot but it's juste to set up correctly the SPI.

I tried with the discovery board with the exact same config and I get a correct 40Mhz SPI clock but on this one no. I will try on an other pin to see what happen.

Sirac
Associate III

I find the mistake:

firstly RCC_ClkInitStruct.APB2CLKDivider was configured with RCC_HCLK_DIV2,

and the hardware was configured with the 8Mhz of the stlink MCO and not with the crystal....

So only my fault about this issue...

Thank you for answers.