之前用标准库,开SPI接收中断,接收后到数据后判断是否位帧首,是的话,置个标志位,将再接收的数据存放到一个数组里。接收的同时,发送下一个将要发送的数据,等待下一次接收时自动发送出去。接收到一定数量后,判断校验位,清标志位。 现在改用HAL库了,HAL_SPI_Receive_IT( )函数使调用一次开启一次中断,执行完后关闭中断及SPI,然后执行回调函数。 我尝试在回调函数里,再次调用HAL_SPI_Receive_IT( ),以使设备一直处于接收状态。结果,没调成功。 后改成在void SPI2_IRQHandler(void)里,再次调用HAL_SPI_Receive_IT( )函数,暂时可以正常接收。 帧首尾的判断也放在了void SPI2_IRQHandler(void)里,现在接收完一组数据后,通过串口发送过来,是正确的。 按原来的思路,接收一个数据后,就应准备发送下一个准备发送的数据,于是就调用HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)函数,可最后一个参数,是超时判断用的,超时后,貌似会自动关闭SPI中断及SPI。而我接收完一组数据后,下次数据也许会等比较长的时间...... 还有没有别的好的办法供参考? |
1、配置基础工程,我这里开启了SPI DMA传输;
2、上电后,开启一个字节命令码DMA接收中断 HAL_SPI_Receive_DMA(&hspi1,spi_cmd,1);
3、SPI接收完成回调函数中判断接收到的命令码是否为0xA1,并准备发送1K数据
if(spi_cmd[0] == 0xA1){
HAL_SPI_Transmit_DMA(&hspi1,test_buf,1024);
}
4、从机准备好发送的数据,当主机读取1K数据完成时进入发送完成回调函数,此时再次开启一个字节命令码DMA接收中断
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi){
if(hspi->Instance == SPI1){
HAL_SPI_Receive_DMA(&hspi1,spi_cmd,1);
}
}
5、以上述简单的例子,举一反三实现更多相关的应用;
HAL_SPI_Receive_IT( ) 调用的回调函数里改变状态的.
评分
查看全部评分
HAL_SPI_Receive_IT( ) 调用的回调函数里改变状态的.
没明白,能否细说下?
评分
查看全部评分
评分
查看全部评分
现在想想,是一开始定的通讯协议不太合理造成的。
主设备发送数据的同时,从设备接收数据同时发送相应反馈数据。这个可能不太合理,如果是主设备发送命令后,等待一段时间,重设备处理完数据后,主设备再发送SCL信号,从设备发送反馈数据,这样就好了。
现在这种情况的话,只能降低发送速率,从设备中断接收尽量简短。主设备也是STM32,用的是硬件SPI,要是能控制每帧里面各数据的间隔长度就好了。