0

我想使用 DMA2 读取 GPIO 引脚上的 UART 消息。该板是STM32F72ZE。我能够得到一个数据包(26 字节),但我得到的下一个数据包出错。此代码取自 STM32F4 的 ST 库。

这是一个小程序(之前,我为 GPIO、DMA2、TIM1 启用了 CLOCK):

//Rx DMA configuration
static void UART_Emul_SetConfig_DMARx(void)
{
  hdma_rx.Init.Channel   = DMA_CHANNEL_6;
  hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY
  hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_rx.Init.MemInc    = DMA_MINC_ENABLE;          
  hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
  hdma_rx.Init.Mode                = DMA_NORMAL;
  hdma_rx.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
  hdma_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
  hdma_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
  hdma_rx.Init.MemBurst            = DMA_MBURST_SINGLE;
  hdma_rx.Init.PeriphBurst         = DMA_PBURST_SINGLE;

  hdma_rx.Instance = DMA2_Stream2;

  __HAL_LINKDMA(&TimHandle, hdma[2], hdma_rx);

  HAL_DMA_Init(TimHandle.hdma[2]);

  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 3, 3);
  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
}

//Start of DMA before each bytes

static void UART_Emul_ReceiveFrame(UART_Emul_HandleTypeDef *huart, uint32_t *pData)
{
  uint32_t tmp_sr =0;
  uint32_t tmp_ds =0;
  uint32_t tmp_size =0;
  uint32_t tmp_arr =0;

  tmp_arr = TIM1->ARR;
  tmp_ds = (uint32_t)pData;
  tmp_sr = (uint32_t) &(huart->RxPortName->IDR);
  tmp_size =  __HAL_UART_EMUL_FRAME_LENGTH(huart);

  /* Enable the transfer complete interrupt */
  __HAL_DMA_ENABLE_IT(&hdma_rx, DMA_IT_TC);

  /* Enable the transfer Error interrupt */
  __HAL_DMA_ENABLE_IT(&hdma_rx, DMA_IT_TE);

  /* Configure DMA Stream data length */
  hdma_rx.Instance->NDTR = tmp_size;

  /* Configure DMA Stream source address */
  hdma_rx.Instance->PAR = tmp_sr;

  /* Configure DMA Stream destination address */
  hdma_rx.Instance->M0AR = tmp_ds;

  /* Enable the Peripheral */
  __HAL_DMA_ENABLE(&hdma_rx);

   TIM1->CCR2 = ((TIM1->CNT + (tmp_arr / 2)) % tmp_arr);

  /* Enable the TIM Update DMA request */
  __HAL_TIM_ENABLE_DMA(&TimHandle, TIM_DMA_CC2);

  /* Enable Timer */
  __HAL_TIM_ENABLE(&TimHandle);

}
//Configure timer
static void UART_Emul_SetConfig (UART_Emul_HandleTypeDef *huart)
{
  uint32_t bit_time = 0;

  /* Init Bit Time */
  if((HAL_RCC_GetSysClockFreq()/HAL_RCC_GetPCLK2Freq()== 1) | (HAL_RCC_GetSysClockFreq()/HAL_RCC_GetPCLK2Freq()== 2))
  {
      bit_time = ((uint32_t) ((HAL_RCC_GetSysClockFreq()/huart->Init.BaudRate) - 1));
  }
  else
  {
      bit_time = ((uint32_t) (((HAL_RCC_GetPCLK2Freq()*2)/huart->Init.BaudRate) - 1));
  }

  /*##-1- Configure  the Timer peripheral (TIM1) in Bit Delay ##############*/
  /* Initialize TIM1 peripheral as follow:
  + Period = TimerPeriod
  + Prescaler = 0
  + ClockDivision = 0
  + Counter direction = Up
  */
  TimHandle.Instance            = TIM1;
  TimHandle.Init.Period         = bit_time;
  TimHandle.Init.Prescaler      = 0;
  TimHandle.Init.ClockDivision  = 0;
  TimHandle.Init.CounterMode    = TIM_COUNTERMODE_UP;
  HAL_TIM_Base_Init(&TimHandle);

  UART_Emul_SetConfig_DMARx();
}

我没有在这里放置 EXT1 的中断处理程序(连接输入线的地方)。EXT1 中断配置为失败。

说明: EXT1 信号失败后,我调用UART_Emul_SetConfig_DMARx()函数创建 DMA 中断,然后我制作字节数据并存储到全局缓冲区。它工作正常,直到我收到最后一个字节的数据包。也许字节之间的大延迟使得难以获得下一个字节?

4

1 回答 1

0
I found the source of the problem. After analyzing the incorrect data, I determined that all 24 bytes of the second packet have a 1 bit left shift, and all bytes of the third packet have a 2 bit left shift and so on.
The UART_Emul_SetConfig () function, which should calculate the period of one bit, makes it with a large error. So after a long break between packets, the DMA reads correctly, and the TIMER processes it incorrectly.
于 2019-11-06T17:51:17.793 回答