与龙共舞 发表于 2018-4-25 16:23:28

CubeMX 串口空闲中断 DMA 串口数据收发

用DMA的方式,原封不动的把PC通过串口发送过来的数据,在串口返回给PC。
附件有CubeMX 原始的代码0
已经修改以后可以完成效果的代码1
方便用比较工具看出我的修改吧。
实际效果是:PC快速给STM32发送数据时候,会丢失数据。
昨天开会,强哥说不用DMA,因为CubeMX 有bug。不明所以。

图片是整个实验的逻辑。

第一部分:串口通信--直接发送 输出
技术代码:
HAL_UART_Transmit(&huart1, (uint8_t *)&ch,       1, 0xFFFF);//3
HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer, 10,0xFFFF);//4
第二部分:串口通信--接收数据原封不动输出
技术代码:
HAL_UART_Transmit_IT(&huart1, (uint8_t *)aRxBuffer, sizeof(aRxBuffer));//5
HAL_UART_Receive_IT(&huart1,(uint8_t *)aRxBuffer, 10);//6
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
          HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer,       1,0xFFFF);
          HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer,   1);
}

第三部分:串口通信--DAM处理原封不动输出
http://blog.csdn.net/youmeichifan/article/details/51750435
思路PC---->发消息到串口it.c处理---》设置了标记位在main死循环处理--》直接发送回来-->发送完成
main.c>>>>>>>>>>
if(UsartType1.receive_flag)
{
        UsartType1.receive_flag=0;/*Ǩ³ö±ê¼Ç*/
        Usart1SendData_DMA(UsartType1.usartDMA_rxBuf,UsartType1.rx_len); /*send*/
}

main.c>>>>>>>>>>       
HAL_UART_Receive_DMA(&huart1, UsartType1.usartDMA_rxBuf, RECEIVELEN);/*ʹÄÜDMA½ÓÊÕ*/
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);/*ʹÄÜ´®¿Ú¿ÕÏÐÖжÏ*/
it.c>>>>>>>>>>>>>
void USART1_IRQHandler(void)
{   
UsartReceive_IDLE(&huart1);
HAL_UART_IRQHandler(&huart1);
}

usart.c>>>>>>>>
USART_RECEIVETYPE UsartType1;

//DMA发送函数
void Usart1SendData_DMA(uint8_t *pdata, uint16_t Length)
{
    while(UsartType1.dmaSend_flag == USART_DMA_SENDING);
    UsartType1.dmaSend_flag = USART_DMA_SENDING;
    HAL_UART_Transmit_DMA(&huart1, pdata, Length);
}

//DMA发送完成中断回调函数
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
   __HAL_DMA_DISABLE(huart->hdmatx);
    UsartType1.dmaSend_flag = USART_DMA_SENDOVER;
}

//串口接收空闲中断
void UsartReceive_IDLE(UART_HandleTypeDef *huart)
{
    uint32_t temp;

    if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))
    {   
      __HAL_UART_CLEAR_IDLEFLAG(&huart1);
      HAL_UART_DMAStop(&huart1);
      temp = huart1.hdmarx->Instance->NDTR;
      UsartType1.rx_len =RECEIVELEN - temp;   
      UsartType1.receive_flag=1;
      HAL_UART_Receive_DMA(&huart1,UsartType1.usartDMA_rxBuf,RECEIVELEN);
    }
}

usart.c>>>>>>>>
USART_RECEIVETYPE UsartType1;



usart.h>>>>>>>>
#define RECEIVELEN 1024
#define USART_DMA_SENDING1//发送未完成
#define USART_DMA_SENDOVER 0//发送完成
typedef struct
{
uint8_t receive_flag:1;//空闲接收标记
uint8_t dmaSend_flag:1;//发送完成标记
uint16_t rx_len;//接收长度
uint8_t usartDMA_rxBuf;//DMA接收缓存
}USART_RECEIVETYPE;


extern USART_RECEIVETYPE UsartType1;



waiman-156411 发表于 2018-4-26 11:15:40

其实是用CubeMx的DMA代码可以的,只是数据量大了,就会溢出

板子粉丝 发表于 2018-4-26 11:20:59

路过看看

Cortexxx 发表于 2018-4-26 14:21:58

CubeMX编译的时间太长了~~
页: [1]
查看完整版本: CubeMX 串口空闲中断 DMA 串口数据收发