SPI主从双机通讯使用如下方案,实现的部分功能:
1)STM32H723将EtherCAT主站的电机指令通过SPI发送至STM32G473;
2)STM32G473将接收到的电机指令通过CAN发送至电机,同时接收电机反馈数据;
3)STM32G473同时通过SPI接收IMU的数据,与电机CAN反馈数据打包一起发送至STM32H723。
为提高效率,SPI 都使用DMA方式传输,调试过程中遇到了一些问题,花了两三天时间,这里记录一下几个主要问题,以方便后续避坑。
1、SPI配置
1.1 STM32H723的SPI配置
作为主机,片选信号单独使用1个GPIO。
DMA配置,由于Data Size设为16 Bits,此处Data Width选择Half Word。
1.2 STM32G473的SPI配置
作为从机,选择硬件NSS输入信号,注意Data size和Clock参数与主机保持一致。
DMA配置,发送和接收都一样,此处就放一张图了,注意Data Width和主机保持一致。
IMU的SPI作为主站配置,参数基本一样,就不在上图了。
2、问题总结
问题1:SPI通讯一段时间就停止了
1)SPI通讯部分代码如下
主机:
主程序以2ms的周期调用MCU_SPI_DMA_CMD()函数进行 SPI通讯。
/**
\brief This function will called from the synchronisation ISR
or from the mainloop if no synchronisation is supported
*
void APPL_Application(void)
{
uint8_t TxCntStart[canNm] = {0}; //发送CAN数据后开始计数,用于CAN节点数据反馈超时判断
static uint16_t TxCnt[canNm] = {0}; //计数值
uint8_t canSts = 0; //CAN发送状态
static uint8_t firstRun = 1;
/**PDO to CAN**/
if(escRxUpdate == 1)
{
/**从站接收的数据通过SPI转发到MCU2的CAN*/
uint16_t *spiTxData = (uint16_t *)&CAN_OUT0x7000.OutCanMsg9_Typ_St;
if(canChNm == 4){
spiTxData = (uint16_t *)&CAN_OUT0x7000.OutCanMsg12_Typ_St;
}
// if(mcu2_spiRdy){
if(firstRun || spiTrCpt){
MCU_SPI_DMA_CMD(spiTxData,SPI_TR_LENGHT);
firstRun = 0;
// mcu2_spiRdy = 0;
}
……
}
}
主机SPI DMA传输函数
/**
* MCU SPI send and receive
*/
//uint8_t mcu2_spiR