Я хочу прочитать сообщение UART на выводе GPIO, используя DMA2. Плата является STM32F72ZE. Мне удалось получить один пакет (26 байт), но следующий пакет я получаю с ошибкой. Этот код взят из библиотеки ST для STM32F4.
Эта небольшая программа (раньше я включал CLOCKs для GPIO, DMA2, TIM1):
//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 сконфигурировано как Failing.
Объяснение: После сбоя сигнала EXT1 я вызываю функцию UART_Emul_SetConfig_DMARx()
для создания прерывания DMA, после чего я делаю байты данных и сохраняю их в глобальный буфер. Это работает нормально, пока я не получу последний байт пакета. Может быть, большая задержка между байтами затрудняет получение следующего байта?