cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 SPI Issues

ifarah
Associate
Posted on February 09, 2016 at 22:26

I'm working with the Nucleo-F303RE development board, and am having a hard time communicating accurately with the board. I have it attached to an ADC that can communicate over SPI. The ADC outputs a 16-bit word corresponding to a voltage between 0 and VREF (3.3V in this case). The issue I'm running in to is that the SPI output doesn't seem to make sense for middle values (~1.65V). I think it is an issue with how I've set up the SPI communication with my code, and was hoping for any help or clarification. Shown below is the code I'm using:

SPI_HandleTypeDef hspi1;

int main(void)

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  MX_SPI1_Init();

  while(1)

  {

 //Test SPI

 output_byte = SPI_ReadData();

//Toggle off board LED to ensure communication

   HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);

 HAL_Delay(200);

  }

}

void SystemClock_Config(void)

{

  RCC_OscInitTypeDef RCC_OscInitStruct;

  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  RCC_PeriphCLKInitTypeDef PeriphClkInit;

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

  RCC_OscInitStruct.HSIState = RCC_HSI_ON;

  RCC_OscInitStruct.HSICalibrationValue = 16;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;

  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;

  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType =      RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1;

  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;

  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12;

  PeriphClkInit.Adc12ClockSelection = RCC_ADC12PLLCLK_DIV1;

  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);

  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */

  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}

void MX_SPI1_Init(void)

{

  hspi1.Instance                     = SPI1;

  hspi1.Init.Mode                  = SPI_MODE_MASTER;

  hspi1.Init.Direction             = SPI_DIRECTION_2LINES;

  hspi1.Init.DataSize             = SPI_DATASIZE_8BIT;

  hspi1.Init.CLKPolarity       = SPI_POLARITY_HIGH;

  hspi1.Init.CLKPhase          = SPI_PHASE_1EDGE;

  hspi1.Init.NSS                    = SPI_NSS_SOFT;

  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;

  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_8BIT;

  hspi1.Init.NSSPMode          = SPI_NSS_PULSE_DISABLE;

  HAL_SPI_Init(&hspi1);

}

void MX_GPIO_Init(void)

{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */

  __GPIOC_CLK_ENABLE();

  __GPIOF_CLK_ENABLE();

  __GPIOA_CLK_ENABLE();

  __GPIOB_CLK_ENABLE();

  /*Configure GPIO pins : PB6 */

  GPIO_InitStruct.Pin = GPIO_PIN_6;

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;

  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  //Set CS Pin to default high

  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);

}

//Function to read data from ADC via SPI connection

uint16_t SPI_ReadData()

{

uint8_t byte1 = 0;

uint8_t byte2 = 0;

uint8_t transfer_byte1 = 0xA0;

uint8_t transfer_byte2 = 0x00;

uint16_t raw_byte = 0;

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);

HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(&hspi1, &transfer_byte1, &byte1, 1, 10);

if (status != HAL_OK) {

return status;

}

HAL_StatusTypeDef status2 = HAL_SPI_TransmitReceive(&hspi1, &transfer_byte2, &byte2, 1, 10);

if (status2 != HAL_OK) {

return status2;

}

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);

raw_byte = (byte1 << 8) | byte2;

return raw_byte;

}

The last function is where I think the issue is occurring. Any help is greatly appreciated.

#psychic-debugging #stm32-spi
1 REPLY 1
Posted on February 10, 2016 at 00:12

Perhaps you can debug this and explain the values you are seeing in the routine you think are failing, and illustrate how the values read there differ from the data you see on a scope or analyzer?

What values do you see in byte1 and byte2? Do you need to cast them when combining?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..