问答

汇集网友智慧,解决技术难题

21ic问答首页 - 外部与我50微秒通讯一次,串口时间来不急怎么办

串口 通讯 ar RT US SAR

外部与我50微秒通讯一次,串口时间来不急怎么办

pyqGO20222025-03-24
要求外部与我50微秒通讯一次,串口2.5M,
使用485,需要切换方向角
我接收用串口空闲中断+DMA接收不定长数据包,
发送直接在中断中轮询发送数据,能够正常通讯,但是进行其他操作时间就不充足了,必须要用DMA去发送,
但是我用DMA启动时需要时间,然后我发送完数据后就来不及接收数据了,有没有大佬帮忙看看我设置有什么问题吗
发送是轮询代码
void USARTy_IRQHandler(void)
{
   uint16_t clear;
   if(USART_GetIntStatus(USARTy, USART_INT_IDLEF)!= RESET )
   {
       /* 切换到发送模式 */
        GPIO_SetBits(CHALF_PORT, CHALF_PIN);

        uint16_t length = RxBufferSize - USARTy_Rx_DMA_Channel->TXNUM;
        TxCounter1 =0;
               
                /*
                *        数据处理
                */
               
        while (TxCounter1 < length)
        {
            /* Send one byte from USARTy to USARTz */
            USART_SendData(USARTy, TxBuffer[TxCounter1++]);
            /* Loop until USARTy DAT register is empty */
            while (USART_GetFlagStatus(USARTy, USART_FLAG_TXDE) == RESET)
            {
            }
        }

        DMA_EnableChannel(USARTy_Rx_DMA_Channel, DISABLE);
        clear = USARTy->STS;
        clear = USARTy->DAT;
        USART_ConfigInt(USARTy, USART_INT_IDLEF, DISABLE);
        GPIO_ResetBits(CHALF_PORT, CHALF_PIN);

        DMA_SetCurrDataCounter(USARTy_Rx_DMA_Channel, 6);
        DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);
        USART_ConfigInt(USARTy, USART_INT_IDLEF, ENABLE);
   }     
}

发送是DMA代码
void USARTy_IRQHandler(void)
{
   uint16_t clear;
   if(USART_GetIntStatus(USARTy, USART_INT_IDLEF)!= RESET )
   {
       /* 切换到发送模式 */
        GPIO_SetBits(CHALF_PORT, CHALF_PIN);
        USARTy_Rx_Done = 1;

        uint16_t length = RxBufferSize - USARTy_Rx_DMA_Channel->TXNUM;
        /*
                *        数据处理
                */

        clear = USARTy->STS;
        clear = USARTy->DAT;
        DMA_EnableChannel(USARTy_Tx_DMA_Channel, DISABLE);
        DMA_SetCurrDataCounter(USARTy_Tx_DMA_Channel, length);
        DMA_EnableChannel(USARTy_Tx_DMA_Channel, ENABLE);
   }     
}

void DMA_Channel3_4_IRQHandler(void)
{
    if(DMA_GetIntStatus(USARTy_Tx_DMA_INT, DMA) != RESET)
    {
        USARTy_Tx_Done = 1;
        GPIO_ResetBits(CHALF_PORT, CHALF_PIN);
        DMA_ClrIntPendingBit(USARTy_Tx_DMA_INT, DMA);

        DMA_EnableChannel(USARTy_Rx_DMA_Channel, DISABLE);
        DMA_SetCurrDataCounter(USARTy_Rx_DMA_Channel, 6);
        DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);
    }   
}

其他配置
void RS485_Init(void)
{
    RCC_Configuration();
    NVIC_Configuration();
    GPIO_Configuration();
    DMA_Configuration();

    USART_InitStructure.BaudRate            = 2500000;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;

    /* Configure USARTy and USARTz */
    USART_Init(USARTy, &USART_InitStructure);


    USART_ConfigInt(USARTy, USART_INT_IDLEF, ENABLE);
    /* Enable USARTy DMA Rx and TX request */
    USART_EnableDMA(USARTy, USART_DMAREQ_RX | USART_DMAREQ_TX, ENABLE);
    /* Enable USARTy RX DMA1 Channel */
    DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);


    /* Enable the USARTy and USARTz */
    USART_Enable(USARTy, ENABLE);
}

void RCC_Configuration(void)
{
    /* DMA clock enable */
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA, ENABLE);
    /* Enable GPIO clock */
    RCC_EnableAPB2PeriphClk(USARTy_GPIO_CLK, ENABLE);
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
    /* Enable USARTy Clock */
    USARTy_APBxClkCmd(USARTy_CLK, ENABLE);
}

void GPIO_Configuration(void)
{
    GPIO_InitType GPIO_InitStructure;

    /* Initialize GPIO_InitStructure */
    GPIO_InitStruct(&GPIO_InitStructure);


    //dir
    GPIO_InitStructure.Pin            = CHALF_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_HIGH;
    GPIO_InitPeripheral(CHALF_PORT, &GPIO_InitStructure);
    GPIO_ResetBits(CHALF_PORT, CHALF_PIN);

    /* Configure USARTy Tx as alternate function push-pull */
    GPIO_InitStructure.Pin            = USARTy_TxPin;   
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = USARTy_Tx_GPIO_AF;
    GPIO_InitPeripheral(USARTy_GPIO, &GPIO_InitStructure);

    /* Configure USARTx Rx as alternate function push-pull */
    GPIO_InitStructure.Pin            = USARTy_RxPin;
    GPIO_InitStructure.GPIO_Alternate = USARTy_Rx_GPIO_AF;
    GPIO_InitPeripheral(USARTy_GPIO, &GPIO_InitStructure);


}

void NVIC_Configuration(void)
{
    NVIC_InitType NVIC_InitStructure;

    /* Enable the USARTy_Rx Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel            = USARTy_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority    = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd         = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* Enable the USARTy_Tx DMA Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel            = USARTy_Tx_DMA_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority    = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd         = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

}

void DMA_Configuration(void)
{
    DMA_InitType DMA_InitStructure;

    /* USARTy_Tx_DMA_Channel (triggered by USARTy Tx event) Config */
    DMA_DeInit(USARTy_Tx_DMA_Channel);
    DMA_InitStructure.PeriphAddr     = USARTy_DAT_Base;
    DMA_InitStructure.MemAddr        = (uint32_t)TxBuffer;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_DST;
    DMA_InitStructure.BufSize        = TxBufferSize;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.CircularMode   = DMA_MODE_NORMAL;
    DMA_InitStructure.Priority       = DMA_PRIORITY_VERY_HIGH;
    DMA_InitStructure.Mem2Mem        = DMA_M2M_DISABLE;
    DMA_Init(USARTy_Tx_DMA_Channel, &DMA_InitStructure);
    DMA_RequestRemap(USARTy_Tx_DMA_REMAP, DMA, USARTy_Tx_DMA_Channel, ENABLE);


    /* USARTy RX DMA Channel (triggered by USARTy Rx event) Config */
    DMA_DeInit(USARTy_Rx_DMA_Channel);
    DMA_InitStructure.PeriphAddr = USARTy_DAT_Base;
    DMA_InitStructure.MemAddr    = (uint32_t)RxBuffer;
    DMA_InitStructure.Direction  = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize    = RxBufferSize;
    DMA_Init(USARTy_Rx_DMA_Channel, &DMA_InitStructure);
    DMA_RequestRemap(USARTy_Rx_DMA_REMAP, DMA, USARTy_Rx_DMA_Channel, ENABLE);

}
回答 +关注 0
320人浏览 1人回答问题 分享 举报
1 个回答
  • 1、触发DMA发送完成中断后,数据并没有发送完成,需要等待串口完成标志后切换方向脚
    2、切换方向脚会产生毛刺
    3、可以将所有的库函数操作变成直接操作寄存器

您需要登录后才可以回复 登录 | 注册