2014-10-06 04:11 AM
Hello,
I have a problem trying to communicate with SPI using the STM32 Nucleo. I am using the STM_HAL_Drivers to read data from an Invensense MPU9 When I read values, I sometimes get spoilage of the last bit, and this seems to coincide with the value of the MISO line when the register address is being sent (i.e if the MISO line is high when transmiting the register address, the recieved data will spoil high, and vice versa). I have checked all lines using an Oscilloscope and the data seems to be fine.
/* Includes ------------------------------------------------------------------*/
#include ''stm32f4xx_hal.h''
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;
UART_HandleTypeDef huart2;
/* USER CODE BEGIN 0 */
#include ''MPU_SPI.h''
#define HAL_SPI_MODULE_ENABLED
#define MPU_Add 0x68<<1
#define MPU_WHO_AM_I 0x75
/* USER CODE END 0 */
/* Private function prototypes -----------------------------------------------*/
void
SystemClock_Config(
void
);
static
void
MX_GPIO_Init(
void
);
static
void
MX_SPI1_Init(
void
);
static
void
MX_USART2_UART_Init(
void
);
int
main(
void
)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* System interrupt init*/
/* Sets the priority grouping field */
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI1_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
uint8_t *Buffer =
''Hello World -> 1\n''
;
uint8_t *Space =
''\n''
;
uint8_t *address[4];
//245 or f5
char
data[100];
int
*pdata =data;
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
HAL_Delay(100);
func_SPI_Write_Byte(0x6B, 0x80, data);
//__works
HAL_Delay(100);
func_SPI_Write_Byte(User_Control, 0x10, data);
//__works
HAL_Delay(100);
func_SPI_Write_Byte(0x6B, 0x00, data);
//__works
HAL_Delay(100);
func_SPI_Write_Byte(I2C_MST_Ctrl, 0x00, data);
func_SPI_Write_Byte(I2C_MST_Ctrl, 0x4D, data);
func_SPI_Write_Byte(User_Control, 0x60, data);
HAL_UART_Transmit(&huart2, Buffer, strlen(Buffer), 5000);
HAL_Delay(2000);
/* USER CODE END 2 */
/* USER CODE BEGIN 3 */
/* Infinite loop */
while
(1){
//this will read the contents of the MPU_Who_AM_I register
//passing results to the ''data''
func_SPI_Write_Byte((MPU_WHO_AM_I|0x80),0x00, data);
//__works
//this will read the contents of the MPU_Who_AM_I register
//This transmits 2 characters of ''data'' to be viewed on cutecom
HAL_UART_Transmit(&huart2, data, 2, 0x1000);
//this will pass the contents of the MAG_Who_AM_I register into ext_sensor_4 register
//it will then read this register passing results to the ''data''
//since it is an external sensor it requires more configuration
func_SPI_Read_Ext_Sens_Byte(MAG_who_am_i,data);
HAL_UART_Transmit(&huart2, data, 2, 0x1000);
func_SPI_Read_Ext_Sens_Byte(MAG_who_am_i,data);
HAL_UART_Transmit(&huart2, data, 2, 0x1000);
func_SPI_Write_Byte((MPU_WHO_AM_I|0x80),0x00, data);
HAL_UART_Transmit(&huart2, data, 2, 0x1000);
func_SPI_Write_Byte((MPU_WHO_AM_I|0x80),0x00, data);
HAL_UART_Transmit(&huart2, data, 2, 0x1000);
HAL_Delay(2000);
}
/* USER CODE END 3 */
}
/** System Clock Configuration
*/
void
SystemClock_Config(
void
)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 6;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 7;
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);
}
/* SPI1 init function */
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_2EDGE;
hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLED;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
HAL_SPI_Init(&hspi1);
}
/* USART2 init function */
5
void
MX_USART2_UART_Init(
void
)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2);
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void
MX_GPIO_Init(
void
)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__GPIOC_CLK_ENABLE();
__GPIOH_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
__GPIOB_CLK_ENABLE();
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : 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);
}
/* USER CODE BEGIN 4 */
/* int temp[6];
int i;
float value[2];
for (i=0;i<2;i++){
func_SPI_Write_Byte((MPU_Acc_X_H |0x80 + i),0x00, j);
HAL_UART_Transmit(&huart2, &data, strlen(&data), 0x1000);
HAL_UART_Transmit(&huart2, Space, strlen(Space), 0x1000);
temp[i]= data[2];
}
//for (i =0; i<3;i++){
int temp2[2];
temp2[0] = (int)(temp[i*2]<<8);
temp2[1] = (int)temp[i*2+1];
int16_t temp3 = (int16_t)(temp2[0] | temp2[1]);
value[i] = (float)((temp3)/16384);
//}
HAL_UART_Transmit(&huart2, &value, strlen(&value), 0x1000); //__works
*/
/* USER CODE END 4 */
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void
assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */
/* USER CODE END 6 */
}
#endif
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
The MPU_SPI header file includes the following functions and the MPU register addresses.
void
func_SPI_Write_Byte(uint8_t address, uint8_t data,
char
*j){
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
uint8_t Write_data[2];
Write_data[0] = address;
Write_data[1] = data;
HAL_SPI_TransmitReceive(&hspi1, &Write_data, j, 2, 0x1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
return
;
}
void
func_SPI_Read_Ext_Sens_Byte(uint8_t address,
char
*j){
func_SPI_Write_Byte(I2C_SLV4_ADD,(MAG_Add|0x80),j);
func_SPI_Write_Byte(I2C_SLV4_REG, address,j);
func_SPI_Write_Byte(I2C_SLV4_CTRL, 0x80,j);
func_SPI_Write_Byte((I2C_SLV4_DI|0x80), 0x00,j);
}
The MPU_Who_AM_I and the MAG_Who_Am_I are both set registers with values of 71 and 48 respectively.
All this should produce
.ExternalClassE97C7A5D5F78478BA9AA6DD4C930DF18 p, .ExternalClassE97C7A5D5F78478BA9AA6DD4C930DF18 li {white-space:pre-wrap;}
ff 71 ff 48 00 48 00 71 ff 71
however it producesff 71 ff 49 00 48 00 70 ff 71
Any help would be greatly recieved and apologies for the wall of code, I have little experience of both using this forum and of microprocessors... #spi-stm32-problem-mpu92502015-05-06 09:36 AM
Can you post a minimal but complete compilable code reproducing the problem, preferably runnable on the STM32L-DISCOVERY?
Note, that the OP appears to have used a 'F4... JW2015-09-01 12:18 AM
does became clear anything?
2015-09-02 10:23 AM