usart1实现DMA的发送和接收功能,出现的接收问题

2020-01-01 17:36发布

小弟刚上手stm32不久,我现在搞了一个用usart1实现了DMA的发送和接收功能。已经成功了,但是我设置的是一次接收32

个字符,如果接收的超过或者少于32个字符,就会出现问题,就无法接收了(我们实现的是用ZigBee无线传输,一次定义32

个字符为一个数据包,但是就怕zigbee的接收的问题,使得DMA无法收到定义好的32个字符,这样就会无法完成后续的任务



我的思路是这样的:
1.先配置USART1的时钟以及相应的GPIO,初始化USART1,使能USART1;
2.0使能DMA时钟
2.1配置DMA发送:
----配置DMA发送中断(DMA1_Channel4)
----DMA发送设置,DMA_BufferSize设为32,都是8bit(DMA_PeripheralDataSize_Byte,DMA_MemoryDataSize_Byte),DMA_Mode为循环模式,然后:
        DMA_Cmd (DMA1_Channel4,ENABLE);       
        DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);
2.2配置DMA接收:
----配置DMA接收中断(DMA1_Channel5)
----DMA接收设置,DMA_BufferSize设为32,都是8bit(DMA_PeripheralDataSize_Byte,DMA_MemoryDataSize_Byte),DMA_Mode为循环模式,然后:
        DMA_Cmd (DMA1_Channel5,ENABLE);       
        DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,ENABLE);
2.3串口向 DMA发出请求(先让DMA接收,接收到了在发送)
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
3.1在DMA接收中断函数中(void DMA1_Channel5_IRQHandler(void))
----如果接收完成 //if(DMA_GetFlagStatus(DMA1_FLAG_TC5)==SET)
----就先给一个全局变量flag=1(为了在main函数中的循环里识别)
----再关闭串口的DMA接收请求  //USART_DMACmd(USART1, USART_DMAReq_Rx, DISABLE);
----清除标志        //DMA_ClearFlag(DMA1_FLAG_TC5);
3.2在main函数的while循环中 如果发现flag==1,说明接收完成,可以传想要传输的数据了;
----于是,打开串口的DMA发送请求  //USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);       
----同时flag=0
3.3在DMA发送中断函数中(void DMA1_Channel4_IRQHandler(void))
----如果发送完成  //if(DMA_GetFlagStatus(DMA1_FLAG_TC4)==SET)
----就关闭串口的DMA发送请求,再打开串口的DMA接收请求:
        USART_DMACmd(USART1, USART_DMAReq_Tx, DISABLE);
        USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
----清除标志        //DMA_ClearFlag(DMA1_FLAG_TC4);
//////////////////////////////////////////////////////////////////////////////////////////////
这就是整个函数,函数实现的很好,接了32个字符(PC给stm32 发送32个字符),马上就发回32个字符,看似已经ok,但是遇到两种蛋疼的情况:

1.pc给stm32 发送的字符少于32个;
2.发送的多于32个;
这样都会导致,stm32无法在继续接收和发送字符了,即使我在向stm32发送正确的32个字符,必须复位才行,这样的话,我们的stm32就无法接收后续的数据了,这怎么办,我想了让它在先关闭串口的DMA请求,在打开,可惜还是不行,请求高人解答。
希望高人谈一下引起这种情况的原因,以及详细的解答方案,最好能有关键性的代码和解释。
谢谢。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
27条回答
20061002838
2020-01-03 04:35
humanking7 发表于 2013-3-12 23:11
您说的是检测usart是否空闲,然后做出判断?您有没有合适的代码,一些东西还是不太清楚,有源码更好一点 ...

这需要什么源码
STM32硬件支持总线空闲中断了

直接使能这个中断(已经设置好接收DMA,且DMA接收长度大于等于实际数据长度);
STM32检测到总线空闲就会进入中断,中断里面读取数据、重新初始化DMA(你要是用大的环形缓冲的话连重新初始化DMA都不用)就行了

好好看看STM32的参考手册吧

一周热门 更多>