2016-02-09 01:26 PM
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 connectionuint16_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-spi2016-02-09 03:12 PM
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?