ST意法半导体
直播中

刘高

10年用户 964经验值
擅长:嵌入式技术
私信 关注
[问答]

LIS3DSH加速度计仅通过SPI发送0xFF或0x00的原因?

我连续数周都在努力解决 SPI 总线问题,但无济于事。我已经成功地为 UART、ADC、定时器等创建了自己的库,所以我相当确定这不是任何常见的陷阱,例如未启用时钟或错误配置 GPIO。我决定放弃并使用 ST 自己提供的 HAL 库,但我仍然看到同样的问题。
这是我的初始化代码:
  •   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 = 10;
  •   if (HAL_SPI_Init(&hspi1) != HAL_OK)
  •     {
  •       Error_Handler();
  •     }
  •   GPIO_InitTypeDef GPIO_InitStruct;
  •   __HAL_RCC_SPI1_CLK_ENABLE();
  •   GPIO_InitStruct.Pin = (1<<5)|(1<<6)|(1<<7);
  •   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  •   GPIO_InitStruct.Pull = GPIO_PULLUP;
  •   GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
  •   GPIO_InitStruct.Alternate = 5;
  •   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  •   GPIO_InitStruct.Pin = (1<<3);
  •   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  •   GPIO_InitStruct.Pull = GPIO_PULLUP;
  •   GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  •   GPIO_InitStruct.Alternate = 0;
  •   HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
然后是我的应用程序代码的相关部分。它等待我按下按钮(带有粗略的去抖动计数器),然后将 UART 消息输出到我的计算机,其中包含从加速度计返回的值(8 位值由我的 int82string 函数转换为字符串)。我正在读取地址 0x0F(确保发送 0x8F 所以它是一个读取函数),这是它的 WHO_AM_I 寄存器。我应该取回 63 0x3F 的值。相反,它只是 255 或 0。
  • while(1){
  •       if (HAL_GPIO_ReadPin(GPIOA, B1_Pin) == GPIO_PIN_SET) {
  •           if (dbounceCtr > 100000) {
  •               HAL_GPIO_WritePin(GPIOE, 3, GPIO_PIN_RESET);
  •               //HAL_SPI_TransmitReceive(&hspi1, &dummy, &response, 1, timeout);
  •               //HAL_SPI_Receive(&hspi1, &response, 1, timeout);
  •               HAL_SPI_TransmitReceive(&hspi1, &address, &response, 1, timeout);
  •               HAL_SPI_TransmitReceive(&hspi1, &dummy, &response, 1, timeout);
  •               HAL_GPIO_WritePin(GPIOE, 3, GPIO_PIN_SET);
  •               int82string(response, accel); //convert accelerometer's output to string
  •               HAL_UART_Transmit(&huart1, message1, strlen(message1), timeout);
  •               HAL_UART_Transmit(&huart1, accel, strlen(accel), timeout);
  •               dbounceCtr = 0;
  •           }
  •           dbounceCtr++;
  •       }
  •   }
我的理解是我需要传输我想读取的地址,然后发送一个虚拟地址,以便时钟信号在我收到实际值时继续。您可以从我的注释行中看到,我也尝试过事先进行另一个虚拟读取周期,但似乎没有任何效果。
任何帮助,将不胜感激。奇怪的是,网上的每一个答案都毫无结果。我的原始库完全按照它们的方式进行操作,因此我尝试使用 HAL 代码,但我又一次完全按照其他人的方式进行操作并得到了垃圾。还有其他人遇到过类似的问题吗?熟悉 ST HAL 库的人看到了吗?







回帖(1)

宫昊

2022-12-29 14:23:48
看起来您在启用时钟之前调用了 HAL_SPI_Init,至少在您提供的代码中是这样。可能不是问题。
> HAL_GPIO_WritePin(GPIOE, 3, GPIO_PIN_RESET);
这不会将 PE3 设置为 0。您需要以下任一选项:


  • HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);
  • HAL_GPIO_WritePin(GPIOE, 1 << 3, GPIO_PIN_RESET);
举报

更多回帖

发帖
×
20
完善资料,
赚取积分