2024-05-10 12:18 PM
Hello,
I use STM32F767ZI (on a board NUCLEO-F767ZI) , CubeIDE, HAL driver and I try to communicate with an accelerometer (LIS2DW12 on the board SEN0405) with SPI interface. I'll try to give the more details possible so that you can help me a maximum.
To test the communication between my microcontroller and my accelerometer, I try to read the WHO_AM_I register of the LIS2DW12. This register is a read-only register. Its value is fixed at 44h. Unfortunately I can't read this value but I read FFh. First of all, so that you can confirm that I haven't made an error of connection, here's how I connected my accelerometer to my nucleo-board :
I just connected the accelerometer to the supply (+3.3V & GND) and the 4 SPI wires.
Then, I configured the SPI communication in CUBEMX according to the LIS2DW12 datasheet :
I wrote a simple code to read value of the register WHO_AM_I using the function HAL_SPI_TransmitReceive. According to the datasheet, to read this register (address 0Fh), it must be sent a byte with the value of the address register and a 1 as MSB -> 8Fh.
Here is a part of my code, where I try to read and the SPI configuration below :
uint8_t TxData[2] = {0x8F, 0x00};
uint8_t RxData[2] = {0x00, 0x00};
HAL_SPI_TransmitReceive(&hspi1, TxData, RxData, 2, 200);
/**
* @brief SPI1 Initialization Function
* @PAram None
* @retval None
*/
static void MX_SPI1_Init(void)
{
/* USER CODE BEGIN SPI1_Init 0 */
/* USER CODE END SPI1_Init 0 */
/* USER CODE BEGIN SPI1_Init 1 */
/* USER CODE END SPI1_Init 1 */
/* SPI1 parameter configuration*/
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_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_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hspi->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
}
After executing my code, my RxData contains two FFh bytes. I don't know where I did something wrong, if someone have any idea, help me please thank you !
Solved! Go to Solution.
2024-05-10 05:18 PM
Do you have a scope to see the signals are coming out?
BTW: do you use a nCS signal?
Is this the second ground wire to set nCS on external SPI slave low (all the time)?
Are you sure the external chip works with hold nCS all the time low? (many chips want to see a new nCS cycle,
and even they would allow to let nCS all the time low: after this chip comes out of reset and nCS is already low - the chip has no clue about "where we are in the protocol").
OK, you configure "MSB first". But are you sure that SPI mode is correct?
(looks like SPI mode 3 needed and you have it this way, I think)
For a simple test: do this:
2024-05-10 05:18 PM
Do you have a scope to see the signals are coming out?
BTW: do you use a nCS signal?
Is this the second ground wire to set nCS on external SPI slave low (all the time)?
Are you sure the external chip works with hold nCS all the time low? (many chips want to see a new nCS cycle,
and even they would allow to let nCS all the time low: after this chip comes out of reset and nCS is already low - the chip has no clue about "where we are in the protocol").
OK, you configure "MSB first". But are you sure that SPI mode is correct?
(looks like SPI mode 3 needed and you have it this way, I think)
For a simple test: do this:
2024-05-11 10:52 AM
Yes, I connected a ground wire to set nCS on external SPI slave low all the time. On the datasheet, it is indicated that the CS pin must be 0 to use the SPI interface, and 1 for i2c. It's the reason why I connected it to a ground wire to have 0 on CS.
But in reality, the accelerometer want to see a new nCS cycle as you told me. I had already tried to connect CS to a GPIO before my post but it didn’t work. I try again and now it's working ! So the first time, I think I tried with another SPI configuration (which was wrong). Thank you for your advice !