我连续数周都在努力解决 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 库的人看到了吗?