AnsweredAssumed Answered

STM32 SPI Issues

Question asked by farah.ibrahim on Feb 9, 2016
Latest reply on Feb 10, 2016 by Clive One
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.

Outcomes