ST意法半导体
直播中

efwedfd

8年用户 1078经验值
擅长:EMC/EMI设计
私信 关注
[问答]

两个STM32F103C8如何通过SPI连接?

我正在尝试连接 2 个 STM32F103C8(蓝色药丸板)。
我只使用一个 STM32 运行测试,使用 SPI1 作为主设备,SPI2 作为从设备,所有配置都工作正常(全双工,主传输。仅接收从设备....每个测试都很好(始终使用 TX 和 RX 中断),这执行测试以检查配置是否正常....
因为所有测试都正常,所以您决定互连 2 个 STM,而我在从 STM 中遇到问题:
主 SPI 仅发送一个数据 (3),在从 STM HAL_SPI_RxCpltCallback 中触发,因此我可以看到接收到的数据 (3),它被保存到一个数组中,但是如果主发送超过一个字 (16 bist),HAL_SPI_ErrorCallback 也会触发).
Master的数据没问题,请看下图:

这是从配置:
#include "main.h"
易失性 uint16_t SPI_Datos_RX[5000];
易失性 uint8_t SPI_NumElementos=1;
易失性 uint8_t SPI_RX_Data_Available=0;
易失性 uint16_t SPI_INDEX_RXED=0;
易失性 uint16_t SPI_DATA_RXed;
易失性 uint16_t INT_TMP=0;
SPI_HandleTypeDef hspi2;
void SystemClock_Config(void);
静态无效 MX_GPIO_Init(无效);
静态无效 MX_SPI2_Init(无效);
void Pasivar_SPI_SS()
{
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, 1);
}
void Activar_SPI_SS()
{
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, 0);
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
        SPI_Datos_RX[SPI_INDEX_RXED]=SPI_DATA_RXed;
        SPI_INDEX_RXED++;
        HAL_SPI_Receive_IT(&hspi2, &SPI_DATA_RXed, SPI_NumElementos);
}
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
        诠释;
        a=HAL_SPI_GetError(&hspi2);
}
int 主要(无效)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI2_Init();
HAL_SPI_MspInit(&hspi2);
__HAL_SPI_ENABLE(&hspi2);
HAL_SPI_Receive_IT(&hspi2, &SPI_DATA_RXed, SPI_NumElementos);
而 (1)
{
         对于 (int a=0; a<1000;a++);
         如果 ((SPI_Datos_RX[INT_TMP]!=0) & (SPI_INDEX_RXED!=0) & (INT_TMP!=0) & (SPI_INDEX_RXED>=4999) )
         {
                 SPI_INDEX_RXED=0;
                  INT_TMP=0;
         }
         INT_TMP++;
}
}
void SystemClock_Config(无效)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
如果 (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
  错误处理程序();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
如果 (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
  错误处理程序();
}
}
静态无效 MX_SPI2_Init(无效)
{
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_SLAVE;
hspi2.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
hspi2.Init.DataSize = SPI_DATASIZE_16BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_HARD_INPUT;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
如果 (HAL_SPI_Init(&hspi2) != HAL_OK)
{
  错误处理程序();
}
}
静态无效 MX_GPIO_Init(无效)
{
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
}
void Error_Handler(无效)
{
/* 用户代码开始 Error_Handler_Debug */
/* 用户可以添加自己的实现来报告HAL错误返回状态 */
__disable_irq();
而 (1)
{
}
/* 用户代码结束 Error_Handler_Debug */
}
#ifdef  USE_FULL_ASSERT
void assert_failed(uint8_t *文件,uint32_t行)
{
}
#endif /* USE_FULL_ASSERT */
这是 SPI2 寄存器:
此时,HAL_SPI_Receive_IT(&hspi2, &SPI_DATA_RXed, SPI_NumElementos);
被执行后,Slave SPI Board 正在等待来自 master 端的数据。
这是主数据到达时的寄存器。

在触发 HAL_SPI_RxCpltCallback 并保存数据后,因为我正在使用调试工具,所以我可以看到 HardFault_Handler 被调用......在 stm32f1xx_it.c 文件中。
/**
* @brief 此函数处理硬故障中断。
*/
void HardFault_Handler(无效)
{
/* 用户代码开始 HardFault_IRQn 0 */
        诠释;
        a=HAL_SPI_GetError(&hspi2);
/* 用户代码结束 HardFault_IRQn 0 */
而 (1)
{
  /* 用户代码开始 W1_HardFault_IRQn 0 */
  /* 用户代码结束 W1_HardFault_IRQn 0 */
}
}
当使用 HAL_SPI_GetError 时,ti 得到 0 值,因为没有任何错误……但由于某种原因,HardFault_Handler 被调用了……
这是 CubeIDE 的 SPI2 配置:


简而言之:Slave recibe SPI数据,16位,将数据移动到数组后,调用HardFault_Handler,之后如果Master再次发送数据,Slave可以处理(HAL_SPI_RxCpltCallback不再触发)










回帖(1)

刘龙飞

2022-12-15 10:35:36
溢出表明代码读取数据的速度不够快。尝试将时钟速率降低一个数量级以查看问题是否消失,或者使用 DMA。
硬故障是另一个问题。通过读取 SCB 寄存器来调试硬故障,了解问题的根源并进行更正。预计出现硬故障后未接收到数据。
> 如果 ((SPI_Datos_RX[INT_TMP]!=0) & (SPI_INDEX_RXED!=0) & (INT_TMP!=0) & (SPI_INDEX_RXED>=4999) )
您正在按位和此处进行操作。您可能需要逻辑与 (&&),而不是 &。虽然因为它们都是布尔值,所以这种语法实际上是有效的。
代码中还有一些其他问题,但我看不出是什么导致了硬故障。
举报

更多回帖

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