STM32F429+STM32CubeMX SPI通信(采用DMA方式接收不定长数据)

硬件环境:两个CPU通过SPI通信,CPU型号为STM32F429,CPU1使用SPI1发送数据给CPU2的SPI2。
 在使用中发现,当SPI速率较快时,使用中断接收会丢数据,因而想到使用DMA方式。但我的接收长度是不定长的,接收长度在18~34个字节,下面是我使用DMA方式接收不定长数据的方法。

1 使用STM32CubeMX配置SPI
1.1CPU1的配置
CPU1用于发送,因而这里设置为:

参数设置:

1.2CPU2的配置
CPU2用于接收,设置为:

参数设置:

DMA设置,使用Circular方式,在程序中只需调用一次HAL_SPI_Receive_DMA()函数:

中断设置:

2 SPI接收不定长数据的方法
2.1CPU2的接收处理
DMA中断有半传输中断(HTIF)和传输完成中断(TCIF),对应的SPI DMA接收的中断回调函数为:
void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi);
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi);
因为我的接收长度为18~34个字节,因而我设置DMA接收缓存长度为36,如果接收为18字节时,则会发生半传输中断(HTIF),超过18字节时,只需略等一会儿就能接收到完整帧。算一下,5.625Mbps的速率,等待剩下的字节的时间是微秒级的。
我的程序使用了uCos嵌入式系统,在两个中断回调函数中发送信号量,就绪SPI接收任务。
        (void)OSTaskSemPost((OS_TCB  *)&SPI2_RxTaskTCB,
                            (OS_OPT   )OS_OPT_POST_NONE,
                            (OS_ERR  *)&os_err);                    
在SPI接收任务中:
#define  SPI2_DMABUF_SIZE                  (36)    
static  volatile uint8_t s_Spi2RxDMABuf[SPI1_DMABUF_SIZE];            
void  SPI2_RxPktTask(void *pdata)
{

    while(HAL_OK != HAL_SPI_Receive_DMA(phspi,(uint8_t*)&s_Spi2RxDMABuf, SPI2_DMABUF_SIZE))
    {
        OSTimeDlyHMSM(0u, 0u, 0u, 5u,
                OS_OPT_TIME_HMSM_STRICT,
                &os_err);
    }

    while(1)    {
    
        OSTaskSemPend (    timeout, OS_OPT_PEND_BLOCKING,     (void*)0, &os_err);    
        
        if(    OS_ERR_NONE != os_err) 
        {  

                continue;
        }
        
        OSTimeDlyHMSM(0u, 0u, 0u,  5u,                /*等5ms*/
                OS_OPT_TIME_HMSM_STRICT,
                &os_err);

        /* 根据DMA计数寄存器得到接收到的数据长度 */
        rec_len = SPI2_DMABUF_SIZE - (uint8_t) __HAL_DMA_GET_COUNTER(phspi->hdmarx);
        /* 缓存s_Spi2RxDMABuf是循环缓存,根据rec_len可以从中读出接收数据 */
    } /* end of while(1)  */    
    
}
 

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值