问答

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

21ic问答首页 - 凌欧LSK45芯片的DMA相关问题,求助大佬

凌欧 芯片 DMA ar UART RT

凌欧LSK45芯片的DMA相关问题,求助大佬

suebillt2024-11-15
用串口助手发送8个字节的数据,在接收中断里面通过DMA搬运数据。但接收的数据有问题,第一个字节的数据搬运2次,最后一个字节的数据丢失。void uart_init(void)
{
    UART_InitTypeDef uart0_config;
    GPIO_InitTypeDef GPIO_InitStruct;
//    DMA_InitTypeDef uart0_dma_config;

    UART_StructInit(&uart0_config);

    // 这些是默认配置,简单的应用只配置波特率即可
    //    uart1_config.DUPLEX       = DISABLE;   // 半双工模式使能,tx_data
    //    uart1_config.MD_EN        = DISABLE;   // Multi-drop 使能
    //    uart1_config.CK_EN        = DISABLE;   // 数据校验使能
    //    uart1_config.CK_TYPE      = 0;         // 奇偶校验配置       0:偶校验(EVEN);1: 奇校验(ODD)
    //    uart1_config.BIT_ORDER    = 0;         // 数据发送顺序配置   0:LSB;1:MSB
    //    uart1_config.STOP_LEN     = 0;         // 停止位长度配置     0:1-Bit;1:2-Bit
    //    uart1_config.BYTE_LEN     = 0;         // 数据长度配置       0:8-Bit;1:9-Bit
    //    uart1_config.ADR          = 0;         // 多机通讯时的从机地址
    //    uart1_config.RX_DONE      = DISABLE;   // 接收完成 DMA 请求使能
    //    uart1_config.TX_BUF_EMPTY = DISABLE;   // 发送缓冲区空 DMA 请求使能
    //    uart1_config.TXD_INV      = DISABLE;   // TXD 输出极性取反
    //    uart1_config.RXD_INV      = DISABLE;   // RXD 输入极性取反
//                uart0_config.TX_DONE  = ENABLE;                                     // 发送完成 DMA 请求使能
                uart0_config.RX_DONE  = ENABLE;   
                uart0_config.TX_BUF_EMPTY = ENABLE;                                   // 发送缓冲区空 DMA 请求使能
    uart0_config.IE       = UART_IF_SendOver | UART_IF_RcvOver|UART_IF_SendBufEmpty;         // 中断配置
    uart0_config.BAUDRATE = 115200;                                      // 波特率
    UART_Init(UART0, &uart0_config);

               
/*UART0_485的GPIO配置*/
    //uart0_485
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;
    GPIO_Init(GPIO0, &GPIO_InitStruct);   
          GPIO0_PDO |= BIT15;                                                                                                        //写1

    /* P0.14-RX0,  UART0 */
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_14 ;
    GPIO_Init(GPIO0, &GPIO_InitStruct);

    /*P1.0-TX0 UART0 */
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_0;
    GPIO_Init(GPIO1, &GPIO_InitStruct);

    GPIO_PinAFConfig(GPIO1, GPIO_PinSource_0, GPIO_AF_UART);
    GPIO_PinAFConfig(GPIO0, GPIO_PinSource_14, GPIO_AF_UART);
               
       
               
/*开启UART的中断*/
    NVIC_EnableIRQ(UART0_IRQn);
    NVIC_SetPriority(UART0_IRQn, 1);
}

/*DMA接收来自外设的数据*/
void uart0_dma_485_recvdata(u8 *t, u16 len)
{
    DMA_InitTypeDef uart0_dma_config;
//                GPIO0_PDO &= ~BIT15;
    uart0_dma_config.DMA_Channel_EN = ENABLE;           /* DMA 通道使能*/
    uart0_dma_config.DMA_IRQ_EN     = ENABLE;           /* DMA 中断使能 */
    uart0_dma_config.DMA_RMODE      = ENABLE;           /* 多轮传输使能 */
    uart0_dma_config.DMA_CIRC       = DISABLE;          /* 循环模式使能 */
    uart0_dma_config.DMA_SINC       = DISABLE;          /* 源地址递增使能 */
    uart0_dma_config.DMA_DINC       = ENABLE;           /* 目的地址递增使能 */
    uart0_dma_config.DMA_SBTW       = 0;                /* 源地址访问位宽, 0:byte, 1:half-word, 2:word */
    uart0_dma_config.DMA_DBTW       = 0;                /* 目的地址访问位宽, 0:byte, 1:half-word, 2:word */
    uart0_dma_config.DMA_REQ_EN     = DMA_REQ_UART0_RX; /* 通道 x 硬件 DMA 请求使能,高有效 */
    uart0_dma_config.DMA_TIMES      = 8;                /* DMA 通道 x 数据搬运次数 */
    uart0_dma_config.DMA_SADR       = (u32)&UART0_BUFF; /* DMA 通道 x 源地址 */
    uart0_dma_config.DMA_DADR       = (u32)t;                                         /* DMA 通道 x 目的地址 */
    DMA_Init(DMA_CH0, &uart0_dma_config);                                                               
   DMA_Trigger(DMA_CH0);                                                                //开始一次DMA传输
}

void UART0_IRQHandler(void)
{
if (UART_GetIRQFlag(UART0, UART_IF_SendOver)) /*发送完成中断*/
  {
    UART_ClearIRQFlag(UART0, UART_IF_SendOver);
//                GPIO_ResetBits(GPIO0, GPIO_Pin_15);
  }
  if (UART_GetIRQFlag(UART0, UART_IF_RcvOver)) /*接收完成中断*/
  {       
                UART_ClearIRQFlag(UART0, UART_IF_RcvOver);       
                uart0_dma_485_recvdata(ModbusSlave_RX_TempBuff, 8);
    }
                               
               
}





回答 +关注 1
531人浏览 1人回答问题 分享 举报
1 个回答

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