我想使用 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 中断,然后我制作字节数据并存储到全局缓冲区。它工作正常,直到我收到最后一个字节的数据包。也许字节之间的大延迟使得难以获得下一个字节?