STM32F429 usart DMA 收发


目标:

实现串口通过DMA收发,不使用串口中断及DMA中断,使用1ms中断来判断是否发送结束或启动发送。



初始化,使用usart1:

1、UART_HandleTypeDef huart1;
typedef struct
{  
    UINT16        wRxdRdPtr;
    UINT16        wRxdWrPtr;
    UINT16        wTxdRdPtr;
    UINT16        wTxdWrPtr;
    BYTE        byRxdBuff[2048];
    BYTE        byTxdBuff[2048];    
    UART_HandleTypeDef    *phandle;
    UINT32         dwRamScan2;
}tagCOMM;

tagCOMM                g_tUart[1];
int uart0wRxdWrPtr;
int uart0delay=0;
int uart0rxdflag=0;
int uart0txdflag=0;
TIM_HandleTypeDef htim10;
 

int HY_USART1_UART_Init(int bps,int    cs,int    databits,int    stopbits)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = bps;
  huart1.Init.WordLength = databits;
  huart1.Init.StopBits = stopbits;
  huart1.Init.Parity = cs;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;

 if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
    return -1;
  }
  /* USER CODE BEGIN USART1_Init 2 */
  g_tUart[0].phandle    =    &huart1;

    return 0;

}

void MYDMA_Config(void)

    //Tx DMA配置
       //数据流选择
        __HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能    
    
       UARTDMATX_HD.Instance = DMA2_Stream7;
       //通道选择
       UARTDMATX_HD.Init.Channel = DMA_CHANNEL_4;
       //存储器到外设
       UARTDMATX_HD.Init.Direction = DMA_MEMORY_TO_PERIPH;
       //外设非增量模式,UART只有一个DR寄存器,地址不能变化
       UARTDMATX_HD.Init.PeriphInc = DMA_PINC_DISABLE;
       //存储器增量模式
       UARTDMATX_HD.Init.MemInc = DMA_MINC_ENABLE;
       //外设数据长度:8位一个字节
       UARTDMATX_HD.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
       //存储器数据长度:8位
       UARTDMATX_HD.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
       //外设普通模式
       UARTDMATX_HD.Init.Mode = DMA_NORMAL;
       //中等优先级
       UARTDMATX_HD.Init.Priority = DMA_PRIORITY_LOW;
       //关闭FIFO
       UARTDMATX_HD.Init.FIFOMode = DMA_FIFOMODE_DISABLE;               
       //FIFO阀值选择
       UARTDMATX_HD.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
       //存储器突发单次传输
       UARTDMATX_HD.Init.MemBurst = DMA_MBURST_SINGLE;
       //外设突发单次传输
       UARTDMATX_HD.Init.PeriphBurst = DMA_PBURST_SINGLE;
       //恢复默认配置
       HAL_DMA_DeInit(&UARTDMATX_HD); 
       //初始化DMA
       HAL_DMA_Init(&UARTDMATX_HD); 
       //将DMA与USART1联系起来(发送DMA)
       __HAL_LINKDMA(&huart1, hdmatx, UARTDMATX_HD);
       
       //Rx DMA配置
       UARTDMARX_HD.Instance = DMA2_Stream2;
       UARTDMARX_HD.Init.Channel = DMA_CHANNEL_4;
       UARTDMARX_HD.Init.Direction = DMA_PERIPH_TO_MEMORY;
       UARTDMARX_HD.Init.PeriphInc = DMA_PINC_DISABLE;
       UARTDMARX_HD.Init.MemInc = DMA_MINC_ENABLE;
       UARTDMARX_HD.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
       UARTDMARX_HD.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
       UARTDMARX_HD.Init.Mode = DMA_CIRCULAR;
       UARTDMARX_HD.Init.Priority = DMA_PRIORITY_LOW;
       UARTDMARX_HD.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
       HAL_DMA_DeInit(&UARTDMARX_HD);
       HAL_DMA_Init(&UARTDMARX_HD);
       __HAL_LINKDMA(&huart1, hdmarx, UARTDMARX_HD);
       
      // HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);  //抢占优先级0,子优先级0
      // HAL_NVIC_EnableIRQ(USART1_IRQn);          //使能USART1中断通道
       
       HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 3, 2);
       HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
       
       memset(&g_tUart[0],0,sizeof(g_tUart[0]));
      // HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 3, 1);
      // HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);

//    __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);   //开启IDLE中断,以帧方式接收不定长数据
    __HAL_DMA_ENABLE_IT(&UARTDMATX_HD, DMA_IT_TC);       //开启DMA传输完成中断
//    __HAL_DMA_ENABLE_IT(&UARTDMARX_HD, DMA_IT_TC);
    HAL_UART_Receive_DMA(&huart1, g_tUart[0].byRxdBuff, 1024);
}

void _BSP_UARRxinit(void)
{
    if(uart0delay++>5000)
    {
        uart0delay=0;
         HAL_UART_DMAStop(&huart1);
        g_tUart[0].wRxdRdPtr=g_tUart[0].wRxdWrPtr=0;
        g_tUart[0].wTxdRdPtr=g_tUart[0].wTxdWrPtr=0;
         HAL_UART_Receive_DMA(&huart1, g_tUart[0].byRxdBuff, 1024);
         
    }
    if((uart0delay%500)==0)
    {
        if(g_tUart[0].wTxdRdPtr<g_tUart[0].wTxdWrPtr)
        {
            _BSP_UARTxTransmit( g_tUart[0].byTxdBuff+g_tUart[0].wTxdRdPtr, g_tUart[0].wTxdWrPtr-g_tUart[0].wTxdRdPtr);
            g_tUart[0].wTxdRdPtr += (g_tUart[0].wTxdWrPtr-g_tUart[0].wTxdRdPtr);
        }
        }
}

void _BSP_UARTxTransmit(uint8_t *pData,         //传输的数据指针
                        uint16_t Size)        //传输的数据量
{
  //开启DMA传输
  HAL_UART_DMAStop(&huart1);
  //HAL_DMA_Start(huart1.hdmatx, (uint32_t)pData, (uint32_t)&huart1.Instance->DR, Size);
  //使能串口DMA发送,没有对应的函数只能直接使用寄存器
 // huart1.Instance->CR3 |= USART_CR3_DMAT;
 g_tUart[0].wRxdRdPtr=g_tUart[0].wRxdWrPtr=0;
HAL_UART_Receive_DMA(&huart1, g_tUart[0].byRxdBuff, 1024);
  HAL_UART_Transmit_DMA(&huart1, pData,  Size);
  uart0delay=0;
  uart0txdflag=0x55;
}    
void DMA2_Stream7_IRQHandler(void)
{
  //DMA2_Steam7传输完成
  if(__HAL_DMA_GET_FLAG(&UARTDMATX_HD, DMA_FLAG_TCIF3_7)) 
  {
    //清除DMA2_Steam7传输完成标志
    __HAL_DMA_CLEAR_FLAG(&UARTDMATX_HD, DMA_FLAG_TCIF3_7);
    //传输完成以后关闭串口DMA
 //   HAL_UART_DMAStop(&huart1);   
    //    __HAL_DMA_ENABLE_IT(&UARTDMATX_HD, DMA_IT_TC);
    if(g_tUart[0].wTxdRdPtr>=g_tUart[0].wTxdWrPtr)
        
    g_tUart[0].wTxdWrPtr=g_tUart[0].wTxdRdPtr=0;
    
        uart0txdflag=0;
  }
  //调用中断处理公共函数
  HAL_DMA_IRQHandler(&UARTDMATX_HD);
 
}

static void MX_TIM10_Init(void)
{

  /* USER CODE BEGIN TIM10_Init 0 */

  /* USER CODE END TIM10_Init 0 */

  /* USER CODE BEGIN TIM10_Init 1 */

  /* USER CODE END TIM10_Init 1 */
  htim10.Instance = TIM10;
  htim10.Init.Prescaler =17999 ;
  htim10.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim10.Init.Period = 10-1;
  htim10.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim10.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim10) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM10_Init 2 */
  HAL_TIM_Base_Start_IT(&htim10);
  g_systemdata.count_250us=0;

  /* USER CODE END TIM10_Init 2 */

}


调用:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   

    /* USER CODE BEGIN Callback 1 */
    if (htim->Instance == TIM10)  //250ms
    {
        
        GetUart1Rxdprt();
        
    }


    /* USER CODE END Callback 1 */
}

void GetUart1Rxdprt(void)
{
    g_tUart[0].wRxdWrPtr= 1024-UARTDMARX_HD.Instance->NDTR;
    COM0rxd();
    _BSP_UARRxinit();
}

void COM0rxd(void)
{
    if(uart0wRxdWrPtr!=g_tUart[0].wRxdWrPtr)
    {
        uart0wRxdWrPtr=g_tUart[0].wRxdWrPtr;
        if((uart0wRxdWrPtr!=0)&&(uart0wRxdWrPtr<1024))
        {
            g_byRxdbuf[0]=g_tUart[0].byRxdBuff[uart0wRxdWrPtr-1];
            if(g_tUart[0].wRxdWrPtr<4)
            {
                if((g_byRxdbuf[0]==0xfe))
                    g_tCOMMCMD[0].cmdflag=0;
            }
            if(g_tCOMMCMD[0].cmdflag==0)
            {
                g_tCOMMCMD[0].rxddata=g_byRxdbuf[0];
                g_tCOMMCMD[0].rxddelay=10;
            }
            else
                uart0rxdflag=0x55;
            if(uart0wRxdWrPtr>10)
                g_tCOMMCMD[0].cmdflag=0;
        }
    }
        
            
}

void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 if(huart->Instance==USART1)

  {
  /* USER CODE BEGIN USART1_MspInit 0 */

  /* USER CODE END USART1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
  
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**USART1 GPIO Configuration    
    PB6     ------> USART1_TX
    PB7     ------> USART1_RX 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* USART1 interrupt Init */
   // HAL_NVIC_SetPriority(USART1_IRQn, 9, 5);
   // HAL_NVIC_EnableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspInit 1 */

  /* USER CODE END USART1_MspInit 1 */
  }
  

  

}



发送函数:

void HY_Uart1_SendData(uint8_t    *pbyBuf, uint32_t dwLen)
{
    int num=0;
    if(g_tUart[num].wTxdWrPtr>2000)
        g_tUart[num].wTxdWrPtr=0;
    if(g_tUart[num].wTxdRdPtr>2000)
        g_tUart[num].wTxdRdPtr=0;
    if(g_tCOMMCMD[num].cmdflag!=0x55)
        g_tUart[num].wTxdWrPtr=g_tUart[num].wTxdRdPtr=0;
    if(g_tUart[0].wTxdWrPtr+dwLen<2000)
    {
        memcpy(g_tUart[0].byTxdBuff+g_tUart[0].wTxdWrPtr, pbyBuf, dwLen);
        g_tUart[0].wTxdWrPtr += dwLen;
    }
    if(g_tUart[0].wTxdRdPtr == 0)
    {
        _BSP_UARTxTransmit( g_tUart[0].byTxdBuff+g_tUart[0].wTxdRdPtr, g_tUart[0].wTxdWrPtr-g_tUart[0].wTxdRdPtr);
        g_tUart[0].wTxdRdPtr += (g_tUart[0].wTxdWrPtr-g_tUart[0].wTxdRdPtr);
    }
}

接收函数:

 int    ComRead(BYTE*    rxdbuf,int maxlen)
 {
     int dwLen=0;
    int i;
    int port;
   
        dwLen=0;
        if(g_tUart[0].wRxdRdPtr==g_tUart[0].wRxdWrPtr)
            return dwLen;
        for(i=0;i<maxlen;i++)
        {
            rxdbuf[i]=g_tUart[0].byRxdBuff[g_tUart[0].wRxdRdPtr++];
            if(g_tUart[0].wRxdRdPtr>=1023)
                g_tUart[0].wRxdRdPtr=0;
            if(g_tUart[0].wRxdRdPtr==g_tUart[0].wRxdWrPtr)
            {
                dwLen=i+1;
               
                return dwLen;
            }
        }
        return maxlen;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值